Exemplo n.º 1
0
        public static void WriteImage(Bitmap src, Stream stream)
        {
            IcnsType imageType = IcnsType.FindType(src.Width, src.Height, 32, IcnsType.TypeDetails.None);

            if (imageType == null)
            {
                throw new NotSupportedException($"Invalid/unsupported source: {src.Width}x{src.Height}");
            }

            Write4Bytes(stream, ICNS_MAGIC);
            Write4Bytes(stream, 4 + 4 + 4 + 4 + 4 * imageType.Width * imageType.Height + 4 + 4 + imageType.Width * imageType.Height);

            Write4Bytes(stream, imageType.Type);
            Write4Bytes(stream, 4 + 4 + 4 * imageType.Width * imageType.Height);

            BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            // the image
            for (int y = 0; y < src.Height; y++)
            {
                for (int x = 0; x < src.Width; x++)
                {
                    uint argb = IcnsDecoder.GetPixel(bitmapData, x, y);
                    stream.WriteByte(0);
                    stream.WriteByte((byte)((argb & 0x00ff0000) >> 16));
                    stream.WriteByte((byte)((argb & 0x0000ff00) >> 8));
                    stream.WriteByte((byte)((argb & 0x000000ff) >> 0));
                }
            }

            // mask
            IcnsType maskType = IcnsType.FindType(src.Width, src.Height, 8, IcnsType.TypeDetails.Mask);

            Write4Bytes(stream, maskType.Type);
            Write4Bytes(stream, 4 + 4 + imageType.Width * imageType.Width);

            for (int y = 0; y < src.Height; y++)
            {
                for (int x = 0; x < src.Width; x++)
                {
                    uint argb = IcnsDecoder.GetPixel(bitmapData, x, y);
                    stream.WriteByte((byte)((argb & 0xff000000) >> 24));
                }
            }
        }
Exemplo n.º 2
0
        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));
        }