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; } } } }
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; }
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); }