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; } } } }
/// <summary> /// Checks that the block type matches the expected <see cref="PSPBlockID"/>. /// </summary> /// <param name="blockID">The block identifier.</param> /// <param name="expected">The expected <see cref="PSPBlockID"/>.</param> internal static void CheckBlockType(ushort blockID, PSPBlockID expected) { if (blockID != (ushort)expected) { throw new FormatException(string.Format(Properties.Resources.UnexpectedBlockTypeFormat, blockID.ToString(CultureInfo.InvariantCulture), ((ushort)expected).ToString(CultureInfo.InvariantCulture), expected.ToString())); } }
public CompositeImageInfoChunk(BufferedBinaryReader br, CompositeImageAttributesChunk attr, ushort majorVersion) { this.chunkSize = br.ReadUInt32(); this.bitmapCount = br.ReadUInt16(); this.channelCount = br.ReadUInt16(); this.paletteSubBlock = null; this.channelBlocks = new ChannelSubBlock[this.channelCount]; long dif = (long)this.chunkSize - HeaderSize; if (dif > 0) { br.Position += dif; } int index = 0; do { uint blockSig = br.ReadUInt32(); if (blockSig != PSPConstants.blockIdentifier) { throw new FormatException(Properties.Resources.InvalidBlockSignature); } PSPBlockID blockType = (PSPBlockID)br.ReadUInt16(); #pragma warning disable IDE0059 // Value assigned to symbol is never used uint chunkLength = br.ReadUInt32(); #pragma warning restore IDE0059 // Value assigned to symbol is never used switch (blockType) { case PSPBlockID.ColorPalette: this.paletteSubBlock = new ColorPaletteBlock(br, majorVersion); break; case PSPBlockID.Channel: ChannelSubBlock block = new ChannelSubBlock(br, attr.compressionType, majorVersion); this.channelBlocks[index] = block; index++; break; } }while (index < this.channelCount); }
public ThumbnailBlock(BufferedBinaryReader br) { this.width = br.ReadInt32(); this.height = br.ReadInt32(); this.bitDepth = br.ReadUInt16(); this.compressionType = (PSPCompression)br.ReadUInt16(); this.planeCount = br.ReadUInt16(); this.colorCount = br.ReadUInt32(); this.paletteEntryCount = br.ReadUInt32(); this.channelCount = br.ReadUInt16(); this.channelBlocks = new ChannelSubBlock[this.channelCount]; int index = 0; do { uint blockSig = br.ReadUInt32(); if (blockSig != PSPConstants.blockIdentifier) { throw new System.FormatException(Properties.Resources.InvalidBlockSignature); } PSPBlockID blockType = (PSPBlockID)br.ReadUInt16(); #pragma warning disable IDE0059 // Value assigned to symbol is never used uint chunkLength = br.ReadUInt32(); #pragma warning restore IDE0059 // Value assigned to symbol is never used switch (blockType) { case PSPBlockID.ColorPalette: this.paletteSubBlock = new ColorPaletteBlock(br, PSPConstants.majorVersion5); break; case PSPBlockID.Channel: ChannelSubBlock block = new ChannelSubBlock(br, this.compressionType, PSPConstants.majorVersion5); this.channelBlocks[index] = block; index++; break; } }while (index < this.channelCount); }
private static IList <RasterLayerChunk> CountRasterChunks(BufferedBinaryReader reader, int layerCount, ushort majorVersion) { List <RasterLayerChunk> rasterChunks = new List <RasterLayerChunk>(layerCount); int index = 0; while (index < layerCount) { uint head = reader.ReadUInt32(); if (head != PSPConstants.blockIdentifier) { throw new FormatException(Properties.Resources.InvalidBlockSignature); } PSPBlockID blockID = (PSPBlockID)reader.ReadUInt16(); #pragma warning disable IDE0059 // Value assigned to symbol is never used uint initialBlockLength = majorVersion <= PSPConstants.majorVersion5 ? reader.ReadUInt32() : 0; #pragma warning restore IDE0059 // Value assigned to symbol is never used uint blockLength = reader.ReadUInt32(); if (blockID == PSPBlockID.Layer) { index++; long endOffset = reader.Position + blockLength; LayerInfoChunk chunk = new LayerInfoChunk(reader, majorVersion); long currentOffset = reader.Position; switch (chunk.type) { case PSPLayerType.Raster: case PSPLayerType.FloatingRasterSelection: if (majorVersion >= PSPConstants.majorVersion12) { // Paint Shop Pro X2 and later insert an unknown block (0x21) before the start of the LayerBitmapInfo chunk. bool ok = false; if (reader.ReadUInt32() == PSPConstants.blockIdentifier) { ushort block = reader.ReadUInt16(); uint length = reader.ReadUInt32(); if (block == 0x21) { reader.Position += length; if (reader.ReadUInt32() == LayerBitmapInfoChunk.HeaderSize) { reader.Position -= 4L; currentOffset = reader.Position; ok = true; } } } if (!ok) { throw new FormatException(Properties.Resources.UnsupportedFormatVersion); } } rasterChunks.Add(new RasterLayerChunk(chunk, currentOffset)); break; } reader.Position += (endOffset - currentOffset); } else { reader.Position += blockLength; } } return(rasterChunks); }
public CompositeImageBlock(BufferedBinaryReader br, ushort majorVersion) { this.blockSize = br.ReadUInt32(); this.attrChunkCount = br.ReadUInt32(); long dif = (long)this.blockSize - HeaderSize; if (dif > 0) { br.Position += dif; } this.attrChunks = new CompositeImageAttributesChunk[(int)this.attrChunkCount]; for (int i = 0; i < this.attrChunkCount; i++) { uint blockSig = br.ReadUInt32(); if (blockSig != PSPConstants.blockIdentifier) { throw new FormatException(Properties.Resources.InvalidBlockSignature); } ushort blockType = br.ReadUInt16(); PSPUtil.CheckBlockType(blockType, PSPBlockID.CompositeImageAttributes); #pragma warning disable IDE0059 // Value assigned to symbol is never used uint attrChunkLength = br.ReadUInt32(); #pragma warning restore IDE0059 // Value assigned to symbol is never used this.attrChunks[i] = new CompositeImageAttributesChunk(br); } for (int i = 0; i < this.attrChunkCount; i++) { uint blockSig = br.ReadUInt32(); if (blockSig != PSPConstants.blockIdentifier) { throw new FormatException(Properties.Resources.InvalidBlockSignature); } PSPBlockID blockType = (PSPBlockID)br.ReadUInt16(); #pragma warning disable IDE0059 // Value assigned to symbol is never used uint chunkLength = br.ReadUInt32(); #pragma warning restore IDE0059 // Value assigned to symbol is never used switch (blockType) { case PSPBlockID.CompositeImage: this.imageChunk = new CompositeImageInfoChunk(br, this.attrChunks[i], majorVersion); break; case PSPBlockID.JPEGImage: this.jpegChunk = new JPEGCompositeInfoChunk(br); break; } } if (this.jpegChunk.imageData != null) { using (MemoryStream ms = new MemoryStream(this.jpegChunk.imageData)) { using (System.Drawing.Bitmap th = new System.Drawing.Bitmap(ms)) { Debug.WriteLine(string.Format("JPEG thumbnail size: {0}x{1}", th.Width, th.Height)); } } } }