private static Size DecodeWebP(BinaryReader binaryReader) { // 'RIFF' already read binaryReader.ReadBytes(4); if (ByteHelper.ReadInt32LE(binaryReader) != 1346520407)// 1346520407 : 'WEBP' { return(Size.Empty); } switch (ByteHelper.ReadInt32LE(binaryReader)) { case 540561494: // 'VP8 ' : lossy // skip stuff we don't need binaryReader.ReadBytes(7); if (ByteHelper.ReadInt24LE(binaryReader) != 2752925) // invalid webp file { return(Size.Empty); } return(new Size(ByteHelper.ReadInt16LE(binaryReader), ByteHelper.ReadInt16LE(binaryReader))); case 1278758998: // 'VP8L' : lossless // skip stuff we don't need binaryReader.ReadBytes(4); if (binaryReader.ReadByte() != 47) // 0x2f : 47 1 byte signature { return(Size.Empty); } byte[] b = binaryReader.ReadBytes(4); return(new Size( 1 + (((b[1] & 0x3F) << 8) | b[0]), 1 + ((b[3] << 10) | (b[2] << 2) | ((b[1] & 0xC0) >> 6)))); // if something breaks put in the '& 0xF' but & oxf should do nothing in theory // because inclusive & with 1111 will leave the binary untouched // 1 + (((wh[3] & 0xF) << 10) | (wh[2] << 2) | ((wh[1] & 0xC0) >> 6)) case 1480085590: // 'VP8X' : extended // skip stuff we don't need binaryReader.ReadBytes(8); return(new Size(1 + ByteHelper.ReadInt24LE(binaryReader), 1 + ByteHelper.ReadInt24LE(binaryReader))); } return(Size.Empty); }
private static Size DecodeTiffLE(BinaryReader binaryReader) { if (binaryReader.ReadByte() != 0) { return(Size.Empty); } int idfStart = ByteHelper.ReadInt32LE(binaryReader); binaryReader.BaseStream.Seek(idfStart, SeekOrigin.Begin); int numberOfIDF = ByteHelper.ReadInt16LE(binaryReader); int width = -1; int height = -1; for (int i = 0; i < numberOfIDF; i++) { short field = ByteHelper.ReadInt16LE(binaryReader); switch (field) { // https://www.awaresystems.be/imaging/tiff/tifftags/baseline.html default: binaryReader.ReadBytes(10); break; case 256: // image width binaryReader.ReadBytes(6); width = ByteHelper.ReadInt32LE(binaryReader); break; case 257: // image length binaryReader.ReadBytes(6); height = ByteHelper.ReadInt32LE(binaryReader); break; } if (width != -1 && height != -1) { return(new Size(width, height)); } } return(Size.Empty); }
public override unsafe void Load(string path) { if (string.IsNullOrEmpty(path)) { throw new ArgumentException("ICO.Load(string)\n\tPath cannot be null or empty"); } if (!File.Exists(path)) { throw new ArgumentException("ICO.Load(string)\n\tFile does not exist"); } this.Clear(); using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] bytes = new byte[6]; fileStream.Read(bytes, 0, bytes.Length); if (!ByteHelper.StartsWith(bytes, IdentifierBytes_1)) { throw new Exception("ICO.Load(string)\n\tInvalid .ico file"); } int imageCount = ByteHelper.ReadInt16LE(bytes, 4); this.Images = new Bitmap[imageCount]; this.selectedImageIndex = 0; long streamPosition = -1; for (int i = 0; i < imageCount; i++) { try { byte[] imageDirectory = new byte[8]; fileStream.Read(imageDirectory, 0, imageDirectory.Length); int width = 0; int height = 0; // if the width is 256 its saved as 0x00 if (imageDirectory[0] == 0x00) { width = 256; } else { width = (byte)imageDirectory[0]; } // if the height is 256 its saved as 0x00 if (imageDirectory[1] == 0x00) { height = 256; } else { height = (byte)imageDirectory[1]; } // reserved should be 0 if (imageDirectory[3] != 0x00) { continue; } int colorPlanes = ByteHelper.ReadInt16LE(imageDirectory, 4); // should be 0 or 1 if (colorPlanes != 0 && colorPlanes != 1) { continue; } int bitsPerPixel = ByteHelper.ReadInt16LE(imageDirectory, 6); int imageDataSize = ByteHelper.ReadInt32LE(fileStream); int imageDataOffset = ByteHelper.ReadInt32LE(fileStream); streamPosition = fileStream.Position; // seek to the image data start fileStream.Seek(imageDataOffset, SeekOrigin.Begin); // get the image data byte[] imageData = new byte[imageDataSize]; fileStream.Read(imageData, 0, imageData.Length); // reset the position fileStream.Seek(streamPosition, SeekOrigin.Begin); // if the image is stored as a png, use a memory stream to read the image if (ByteHelper.StartsWith(imageData, PNG.IdentifierBytes_1)) { MemoryStream mem = new MemoryStream(); mem.Write(imageData, 0, imageData.Length); this.Images[i] = (Bitmap)System.Drawing.Image.FromStream(mem); continue; } int dipHeaderSize = ByteHelper.ReadInt32LE(imageData, 0); int index = dipHeaderSize; Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); this.Images[i] = bmp; BitmapData dstBD = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte *pDst = (byte *)(void *)dstBD.Scan0; for (int ii = 0; ii < bmp.Width * bmp.Height; ii++) { *pDst = (byte)(imageData[index]); // B pDst++; index++; *pDst = (byte)(imageData[index]); // G pDst++; index++; *pDst = (byte)(imageData[index]); // R pDst++; index++; if (bitsPerPixel == 32) { *pDst = (byte)(imageData[index]); // a index++; } else { *pDst = (byte)255; // a } pDst++; } bmp.UnlockBits(dstBD); // since the ico stores the bitmap data upside down // flip the image bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); } catch { // chances are the error was thrown when building the image // so at least try and get the others if (streamPosition != -1) { fileStream.Seek(streamPosition, SeekOrigin.Begin); } continue; } } } }