private static IcnsImage LoadWithFreeImage(IcnsImageParser.IcnsElement element, IcnsType imageType) { using (MemoryStream ms = new MemoryStream(element.data)) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_JP2; FIBITMAP fib = FreeImage.LoadFromStream(ms, ref format); Bitmap bmp = FreeImage.GetBitmap(fib); FreeImage.Unload(fib); return(new IcnsImage(bmp, imageType)); } }
private static IcnsImage TryDecodingPng(IcnsImageParser.IcnsElement element, IcnsType imageType) { if (element.data.Length < PNG_SIGNATURE.Length) { return(null); // definitely not a valid png } for (int i = 0; i < PNG_SIGNATURE.Length; i++) { if (element.data[i] != PNG_SIGNATURE[i]) { return(null); // not a png } } using (MemoryStream ms = new MemoryStream(element.data)) return(new IcnsImage((Bitmap)Image.FromStream(ms), imageType)); // cast is valid, for PNG it will be Bitmap }
private static IcnsImage DecodeImage(IcnsImageParser.IcnsElement imageElement, IcnsImageParser.IcnsElement[] icnsElements) { IcnsType imageType = IcnsType.FindType(imageElement.type, IcnsType.TypeDetails.Mask); if (imageType == null) { return(null); } IcnsType maskType = null; IcnsImageParser.IcnsElement maskElement = null; if (imageType.Details == IcnsType.TypeDetails.HasMask) { maskType = imageType; maskElement = imageElement; } else if (imageType.Details == IcnsType.TypeDetails.None) { maskType = IcnsType.FindType(imageType.Width, imageType.Height, 8, IcnsType.TypeDetails.Mask); if (maskType != null) { maskElement = FindElement(icnsElements, maskType.Type); } if (maskElement == null) { maskType = IcnsType.FindType(imageType.Width, imageType.Height, 1, IcnsType.TypeDetails.Mask); if (maskType != null) { maskElement = FindElement(icnsElements, maskType.Type); } } } if (imageType.Details == IcnsType.TypeDetails.Compressed || imageType.Details == IcnsType.TypeDetails.Retina) { IcnsImage result = TryDecodingPng(imageElement, imageType); if (result != null) { return(result); // png } if (LoadJ2kImage == null) { return(null); // couldn't be loaded } return(LoadJ2kImage(imageElement, imageType)); } int expectedSize = (imageType.Width * imageType.Height * imageType.BitsPerPixel + 7) / 8; byte[] imageData; if (imageElement.data.Length < expectedSize) { if (imageType.BitsPerPixel == 32) { imageData = Rle24Compression.Decompress(imageType.Width, imageType.Height, imageElement.data); } else { throw new Exception("Short image data but not a 32 bit compressed type"); } } else { imageData = imageElement.data; } Bitmap image = new Bitmap(imageType.Width, imageType.Height, PixelFormat.Format32bppArgb); BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); switch (imageType.BitsPerPixel) { case 1: Decode1BPPImage(imageType, imageData, bitmapData); break; case 4: Decode4BPPImage(imageType, imageData, bitmapData); break; case 8: Decode8BPPImage(imageType, imageData, bitmapData); break; case 32: if (imageType.Details == IcnsType.TypeDetails.ARGB) { Decode32BPPImageARGB(imageType, imageData, bitmapData); } else { Decode32BPPImage(imageType, imageData, bitmapData); } break; default: image.UnlockBits(bitmapData); image.Dispose(); throw new NotSupportedException("Unsupported bit depth " + imageType.BitsPerPixel); } if (maskElement != null) { switch (maskType.BitsPerPixel) { case 1: Apply1BPPMask(maskElement.data, bitmapData); break; case 8: Apply8BPPMask(maskElement.data, bitmapData); break; default: image.UnlockBits(bitmapData); image.Dispose(); throw new NotSupportedException("Unsupport mask bit depth " + maskType.BitsPerPixel); } } image.UnlockBits(bitmapData); return(new IcnsImage(image, imageType)); }