Example #1
0
        public static void DoBitmapEntry(ByteReader reader, ParseContext context, IcoFrame source)
        {
            var biSize          = reader.NextUint32();
            var biWidth         = reader.NextInt32();
            var biHeight        = reader.NextInt32();
            var biPlanes        = reader.NextUint16();
            var biBitCount      = reader.NextUint16();
            var biCompression   = reader.NextUint32();
            var biSizeImage     = reader.NextUint32();
            var biXPelsPerMeter = reader.NextInt32();
            var biYPelsPerMeter = reader.NextInt32();
            var biClrUsed       = reader.NextUint32();
            var biClrImportant  = reader.NextUint32();

            if (biSize != FileFormatConstants._bitmapInfoHeaderSize)
            {
                throw new InvalidIcoFileException(IcoErrorCode.InvalidBitapInfoHeader_ciSize, $"BITMAPINFOHEADER.ciSize should be {FileFormatConstants._bitmapInfoHeaderSize}, was {biSize}.", context);
            }

            if (biXPelsPerMeter != 0)
            {
                context.Reporter.WarnLine(IcoErrorCode.InvalidBitapInfoHeader_biXPelsPerMeter, $"BITMAPINFOHEADER.biXPelsPerMeter should be 0, was {biXPelsPerMeter}.", context.DisplayedPath, context.ImageDirectoryIndex.Value);
            }

            if (biYPelsPerMeter != 0)
            {
                context.Reporter.WarnLine(IcoErrorCode.InvalidBitapInfoHeader_biYPelsPerMeter, $"BITMAPINFOHEADER.biYPelsPerMeter should be 0, was {biYPelsPerMeter}.", context.DisplayedPath, context.ImageDirectoryIndex.Value);
            }

            if (biCompression == FileFormatConstants.BI_BITFIELDS)
            {
                throw new InvalidIcoFileException(IcoErrorCode.BitfieldCompressionNotSupported, $"This tool does not implement icon bitmaps that use BI_BITFIELDS compression.  (The .ICO file may be okay, although it is certainly unusual.)", context);
            }

            if (biCompression != FileFormatConstants.BI_RGB)
            {
                throw new InvalidIcoFileException(IcoErrorCode.BitmapCompressionNotSupported, $"BITMAPINFOHEADER.biCompression is unknown value ({biCompression}).", context);
            }

            if (biHeight != source.Encoding.ClaimedHeight * 2)
            {
                context.Reporter.WarnLine(IcoErrorCode.MismatchedHeight, $"BITMAPINFOHEADER.biHeight is not exactly double ICONDIRECTORY.bHeight ({biHeight} != 2 * {source.Encoding.ClaimedHeight}).", context.DisplayedPath, context.ImageDirectoryIndex.Value);
            }

            if (biWidth != source.Encoding.ClaimedWidth)
            {
                context.Reporter.WarnLine(IcoErrorCode.MismatchedWidth, $"BITMAPINFOHEADER.biWidth is not exactly equal to ICONDIRECTORY.bWidth ({biWidth} != 2 * {source.Encoding.ClaimedWidth}).", context.DisplayedPath, context.ImageDirectoryIndex.Value);
            }

            var height = biHeight / 2;
            var width  = biWidth;

            source.Encoding.ActualHeight   = (uint)height;
            source.Encoding.ActualWidth    = (uint)width;
            source.Encoding.ActualBitDepth = biBitCount;
            source.Encoding.Type           = IcoEncodingType.Bitmap;
            source.CookedData = new Image <Rgba32>(width, height);

            switch (biBitCount)
            {
            case 1:
            case 2:
            case 4:
            case 8:
                ReadIndexedBitmap(reader, context, biBitCount, biClrUsed, height, width, source);
                break;

            case 16:
                ReadBitmap16(reader, context, height, width, source);
                break;

            case 24:
                ReadBitmap24(reader, context, biClrUsed, height, width, source);
                break;

            case 32:
                ReadBitmap32(reader, context, height, width, source);
                break;

            default:
                throw new InvalidIcoFileException(IcoErrorCode.InvalidBitapInfoHeader_biBitCount, $"BITMAPINFOHEADER.biBitCount is unknown value ({biBitCount}); expected 1, 4, 8, 16, or 32 bit depth.", context);
            }
        }