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; }
public void Save(Document input, Stream output, CompressionFormats format, Surface scratchSurface, ushort majorVersion, ProgressEventHandler callback) { if (majorVersion == PSPConstants.majorVersion5 && input.Layers.Count > 64) { throw new FormatException(string.Format(Properties.Resources.MaxLayersFormat, 64)); } else if ((majorVersion == PSPConstants.majorVersion6 || majorVersion == PSPConstants.majorVersion7) && input.Layers.Count > 100) { throw new FormatException(string.Format(Properties.Resources.MaxLayersFormat, 100)); } using (BinaryWriterEx writer = new BinaryWriterEx(output, false)) { this.fileHeader = new FileHeader(majorVersion); this.imageAttributes = new GeneralImageAttributes( input.Width, input.Height, CompressionFromTokenFormat(format), 0, input.Layers.Count, majorVersion); switch (input.DpuUnit) { case MeasurementUnit.Centimeter: this.imageAttributes.ResValue = input.DpuX; this.imageAttributes.ResUnit = ResolutionMetric.Centimeter; break; case MeasurementUnit.Inch: this.imageAttributes.ResValue = input.DpuX; this.imageAttributes.ResUnit = ResolutionMetric.Inch; break; } this.totalProgress = 0; this.doneProgress = 0; bool flatImage = true; foreach (Layer item in input.Layers) { BitmapLayer layer = (BitmapLayer)item; Rectangle rect = PSPUtil.GetImageSaveRectangle(layer.Surface); if (!rect.IsEmpty) { if (LayerHasTransparency(layer.Surface, rect)) { this.totalProgress += 4; flatImage = false; } else { this.totalProgress += 3; } } } if (flatImage) { this.imageAttributes.SetGraphicContentFlag(PSPGraphicContents.FlatImage); } if (majorVersion > PSPConstants.majorVersion5) { CreateCompositeImageBlock(input, scratchSurface, callback, majorVersion); } else { CreateThumbnailBlock(input, scratchSurface, callback, majorVersion); } int layerCount = input.Layers.Count; LayerInfoChunk[] layerInfoChunks = new LayerInfoChunk[layerCount]; LayerBitmapInfoChunk[] layerBitmapChunks = new LayerBitmapInfoChunk[layerCount]; for (int i = 0; i < layerCount; i++) { BitmapLayer layer = (BitmapLayer)input.Layers[i]; Rectangle savedBounds = PSPUtil.GetImageSaveRectangle(layer.Surface); LayerInfoChunk infoChunk = new LayerInfoChunk(layer, BlendOptoBlendMode(layer.BlendOp), savedBounds, majorVersion); int channelCount = 3; int bitmapCount = 1; if (LayerHasTransparency(layer.Surface, savedBounds)) { channelCount = 4; bitmapCount = 2; } LayerBitmapInfoChunk biChunk = new LayerBitmapInfoChunk(bitmapCount, channelCount) { channels = SplitImageChannels(layer.Surface, savedBounds, channelCount, majorVersion, false, callback) }; if (majorVersion <= PSPConstants.majorVersion5) { infoChunk.v5BitmapCount = biChunk.bitmapCount; infoChunk.v5ChannelCount = biChunk.channelCount; } layerInfoChunks[i] = infoChunk; layerBitmapChunks[i] = biChunk; } this.layerBlock = new LayerBlock(layerInfoChunks, layerBitmapChunks); string creatorData = input.Metadata.GetUserValue(PSPCreatorMetaData); if (!string.IsNullOrEmpty(creatorData)) { this.creator = DeserializeFromBase64 <CreatorBlock>(creatorData); } else { this.creator = new CreatorBlock(); } writer.Write(PSPFileSig); this.fileHeader.Save(writer); this.imageAttributes.Save(writer); this.creator.Save(writer); if (this.compImage != null) { this.compImage.Save(writer); } else if (this.v5Thumbnail != null) { this.v5Thumbnail.Save(writer); } this.layerBlock.Save(writer, majorVersion); } }