Ejemplo n.º 1
0
        private void LoadPSPFile(Stream input)
        {
            byte[] sigBytes = new byte[32];

            input.ProperRead(sigBytes, 0, sigBytes.Length);

            if (!CheckSig(sigBytes))
            {
                throw new FormatException(Properties.Resources.InvalidPSPFile);
            }

            using (BufferedBinaryReader reader = new BufferedBinaryReader(input))
            {
                this.fileHeader = new FileHeader(reader);

                while (reader.Position < reader.Length)
                {
                    uint blockSig = reader.ReadUInt32();
                    if (blockSig != PSPConstants.blockIdentifier)
                    {
                        throw new FormatException(Properties.Resources.InvalidBlockSignature);
                    }
                    PSPBlockID blockID            = (PSPBlockID)reader.ReadUInt16();
                    uint       initialBlockLength = this.fileHeader.Major <= PSPConstants.majorVersion5 ? reader.ReadUInt32() : 0;
                    uint       blockLength        = reader.ReadUInt32();

                    switch (blockID)
                    {
                    case PSPBlockID.ImageAttributes:
                        this.imageAttributes = new GeneralImageAttributes(reader, this.fileHeader.Major);
                        break;

                    case PSPBlockID.Creator:
                        this.creator = new CreatorBlock(reader, blockLength);
                        break;

                    case PSPBlockID.ColorPalette:
                        this.globalPalette = new ColorPaletteBlock(reader, this.fileHeader.Major);
                        break;

                    case PSPBlockID.LayerStart:
                        this.layerBlock = new LayerBlock(reader, this.imageAttributes, this.fileHeader.Major);
                        break;

                    case PSPBlockID.ExtendedData:
                        this.extData = new ExtendedDataBlock(reader, blockLength);
                        break;

#if DEBUG
                    case PSPBlockID.CompositeImageBank:
                        this.compImage = new CompositeImageBlock(reader, this.fileHeader.Major);
                        break;
#endif
                    default:
                        reader.Position += blockLength;
                        break;
                    }
                }
            }
        }
Ejemplo n.º 2
0
 public PSPFile()
 {
     this.fileHeader      = null;
     this.imageAttributes = null;
     this.extData         = null;
     this.creator         = null;
     this.compImage       = null;
     this.globalPalette   = null;
     this.layerBlock      = null;
     this.v5Thumbnail     = null;
 }
Ejemplo n.º 3
0
        private void CreateCompositeImageBlock(Document input, Surface scratchSurface, ProgressEventHandler callback, ushort majorVersion)
        {
            Size jpegThumbSize = GetThumbnailDimensions(input.Width, input.Height, 200);

            CompositeImageAttributesChunk normAttr = new CompositeImageAttributesChunk(
                input.Width,
                input.Height,
                PSPCompositeImageType.Composite,
                this.imageAttributes.CompressionType);
            CompositeImageAttributesChunk jpgAttr = new CompositeImageAttributesChunk(
                jpegThumbSize.Width,
                jpegThumbSize.Height,
                PSPCompositeImageType.Thumbnail,
                PSPCompression.JPEG);
            JPEGCompositeInfoChunk  jpgChunk  = new JPEGCompositeInfoChunk();
            CompositeImageInfoChunk infoChunk = new CompositeImageInfoChunk();

            using (RenderArgs args = new RenderArgs(scratchSurface))
            {
                input.Render(args, true);

                int channelCount = 3;
                if (LayerHasTransparency(args.Surface, args.Surface.Bounds))
                {
                    channelCount           = 4;
                    infoChunk.channelCount = 4;
                    infoChunk.bitmapCount  = 2;
                }
#if DEBUG
                using (Bitmap bmp = args.Surface.CreateAliasedBitmap())
                {
                }
#endif

                this.totalProgress += channelCount;

                infoChunk.channelBlocks = SplitImageChannels(args.Surface, args.Surface.Bounds, channelCount, majorVersion, true, callback);

                using (Surface fit = new Surface(jpegThumbSize))
                {
                    fit.FitSurface(ResamplingAlgorithm.SuperSampling, args.Surface);

                    if (channelCount == 4)
                    {
                        unsafe
                        {
                            for (int y = 0; y < jpgAttr.height; y++)
                            {
                                ColorBgra *ptr    = fit.GetRowAddressUnchecked(y);
                                ColorBgra *endPtr = ptr + jpgAttr.width;

                                while (ptr < endPtr)
                                {
                                    if (ptr->A == 0)
                                    {
                                        ptr->Bgra |= 0x00ffffff; // set the color of the transparent pixels to white, same as Paint Shop Pro
                                    }

                                    ptr++;
                                }
                            }
                        }
                    }

                    using (Bitmap temp = fit.CreateAliasedBitmap(false))
                    {
                        using (MemoryStream stream = new MemoryStream())
                        {
                            temp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);

                            jpgChunk.imageData      = stream.ToArray();
                            jpgChunk.compressedSize = (uint)stream.Length;
                        }
                    }
                }
            }

            this.imageAttributes.SetGraphicContentFlag(PSPGraphicContents.Composite);
            this.imageAttributes.SetGraphicContentFlag(PSPGraphicContents.Thumbnail);

            if (infoChunk.bitmapCount == 2)
            {
                this.imageAttributes.SetGraphicContentFlag(PSPGraphicContents.CompositeTransparency);
            }

            this.compImage = new CompositeImageBlock(new CompositeImageAttributesChunk[2] {
                jpgAttr, normAttr
            }, jpgChunk, infoChunk);
        }