Пример #1
0
        public static void ReadRgb16(ImageBinReader reader, Span <byte> destination)
        {
            Debug.Assert(reader != null);

            const ushort fiveBitMask = 31;
            var          px          = (ushort)reader.ReadInt16LE();
            int          b           = px & fiveBitMask;
            int          g           = (px >> 5) & fiveBitMask;
            int          r           = (px >> 10) & fiveBitMask;

            destination[2] = (byte)(b * 255 / 31);
            destination[1] = (byte)(g * 255 / 31);
            destination[0] = (byte)(r * 255 / 31);
        }
Пример #2
0
        public static BmpInfo?ParseHeader(ImageBinReader s, ReadState ri)
        {
            if (s == null)
            {
                throw new ArgumentNullException(nameof(s));
            }
            if (ri == null)
            {
                throw new ArgumentNullException(nameof(ri));
            }

            Span <byte> tmp = stackalloc byte[HeaderSize];

            if (!s.TryReadBytes(tmp))
            {
                return(null);
            }

            if (!Test(tmp))
            {
                throw new StbImageReadException(ErrorCode.UnknownFormat);
            }

            var info = new BmpInfo();

            s.ReadInt32LE();
            s.ReadInt16LE();
            s.ReadInt16LE();

            info.offset     = s.ReadInt32LE();
            info.headerSize = s.ReadInt32LE();
            info.mr         = info.mg = info.mb = info.ma = 0;

            if (info.headerSize != 12 &&
                info.headerSize != 40 &&
                info.headerSize != 56 &&
                info.headerSize != 108 &&
                info.headerSize != 124)
            {
                throw new StbImageReadException(ErrorCode.UnknownHeader);
            }

            if (info.headerSize == 12)
            {
                ri.Width  = s.ReadInt16LE();
                ri.Height = s.ReadInt16LE();
            }
            else
            {
                ri.Width  = s.ReadInt32LE();
                ri.Height = s.ReadInt32LE();
            }

            ri.Orientation = ri.Height > 0
                ? ImageOrientation.BottomLeftOrigin
                : ImageOrientation.TopLeftOrigin;

            ri.Height = Math.Abs(ri.Height);

            if (s.ReadInt16LE() != 1)
            {
                throw new StbImageReadException(ErrorCode.BadColorPlane);
            }

            info.bitsPerPixel = s.ReadInt16LE();
            if (info.bitsPerPixel == 1)
            {
                throw new StbImageReadException(ErrorCode.MonochromeNotSupported);
            }

            if (info.headerSize != 12)
            {
                int compress = s.ReadInt32LE();
                if ((compress == 1) || (compress == 2))
                {
                    throw new StbImageReadException(ErrorCode.RLENotSupported);
                }

                s.ReadInt32LE();
                s.ReadInt32LE();
                s.ReadInt32LE();
                s.ReadInt32LE();
                s.ReadInt32LE();

                if (info.headerSize == 40 ||
                    info.headerSize == 56)
                {
                    if (info.headerSize == 56)
                    {
                        s.ReadInt32LE();
                        s.ReadInt32LE();
                        s.ReadInt32LE();
                        s.ReadInt32LE();
                    }

                    if ((info.bitsPerPixel == 16) || (info.bitsPerPixel == 32))
                    {
                        if (compress == 0)
                        {
                            if (info.bitsPerPixel == 32)
                            {
                                info.mr = 0xffu << 16;
                                info.mg = 0xffu << 8;
                                info.mb = 0xffu << 0;
                                info.ma = 0xffu << 24;
                            }
                            else
                            {
                                info.mr = 31 << 10;
                                info.mg = 31 << 5;
                                info.mb = 31 << 0;
                            }
                        }
                        else if (compress == 3)
                        {
                            info.mr = s.ReadUInt32LE();
                            info.mg = s.ReadUInt32LE();
                            info.mb = s.ReadUInt32LE();

                            if ((info.mr == info.mg) && (info.mg == info.mb))
                            {
                                throw new StbImageReadException(ErrorCode.BadMasks);
                            }
                        }
                        else
                        {
                            throw new StbImageReadException(ErrorCode.BadCompression);
                        }
                    }
                }
                else
                {
                    if (info.headerSize != 108 &&
                        info.headerSize != 124)
                    {
                        throw new StbImageReadException(ErrorCode.UnknownHeader);
                    }

                    info.mr = s.ReadUInt32LE();
                    info.mg = s.ReadUInt32LE();
                    info.mb = s.ReadUInt32LE();
                    info.ma = s.ReadUInt32LE();

                    s.ReadInt32LE();

                    for (int i = 0; i < 12; ++i)
                    {
                        s.ReadInt32LE();
                    }

                    if (info.headerSize == 124)
                    {
                        for (int i = 0; i < 4; ++i)
                        {
                            s.ReadInt32LE();
                        }
                    }
                }
            }

            if (info.bitsPerPixel == 24 &&
                info.ma == 0xffu << 24)
            {
                ri.Components = 3;
            }
            else
            {
                ri.Components = info.ma != 0 ? 4 : 3;
            }

            ri.Depth = info.bitsPerPixel / ri.Components;

            return(info);
        }
Пример #3
0
        public static TgaInfo ParseHeader(ImageBinReader reader, ReadState state)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            Span <byte> tmp = stackalloc byte[HeaderSize];

            if (!reader.TryReadBytes(tmp))
            {
                throw new EndOfStreamException();
            }

            bool test = TestCore(tmp, out var info);

            if (info.colormap_type == 1)
            {
                if (info.image_type != 1 &&
                    info.image_type != 9)
                {
                    throw new StbImageReadException(ErrorCode.BadImageType);
                }

                info.palette_start = reader.ReadInt16LE();
                info.palette_len   = reader.ReadInt16LE();
                info.palette_bpp   = reader.ReadByte();

                if (info.palette_bpp != 8 &&
                    info.palette_bpp != 15 &&
                    info.palette_bpp != 16 &&
                    info.palette_bpp != 24 &&
                    info.palette_bpp != 32)
                {
                    throw new StbImageReadException(ErrorCode.BadPalette);
                }
            }
            else
            {
                if (info.image_type != 2 &&
                    info.image_type != 3 &&
                    info.image_type != 10 &&
                    info.image_type != 11)
                {
                    throw new StbImageReadException(ErrorCode.BadImageType);
                }

                reader.Skip(5);
                // 16bit: Color Map Origin
                // 16bit: Color Map Length
                // 8bit:  Color Map Entry Size
            }

            Debug.Assert(test); // Prior checks should throw if test was unsucessful.

            info.x_origin = reader.ReadInt16LE();
            info.y_origin = reader.ReadInt16LE();

            state.Width = reader.ReadUInt16LE();
            if (state.Width < 1)
            {
                throw new StbImageReadException(ErrorCode.ZeroWidth);
            }

            state.Height = reader.ReadUInt16LE();
            if (state.Height < 1)
            {
                throw new StbImageReadException(ErrorCode.ZeroHeight);
            }

            info.bits_per_pixel = reader.ReadByte();

            info.inverted = reader.ReadByte();
            info.inverted = 1 - ((info.inverted >> 5) & 1);

            // use the number of bits from the palette if paletted
            if (info.palette_bpp != 0)
            {
                if (info.bits_per_pixel != 8 &&
                    info.bits_per_pixel != 16)
                {
                    throw new StbImageReadException(ErrorCode.BadBitsPerPixel);
                }

                state.Components = GetComponentCount(
                    info.palette_bpp, false, out state.Depth);
            }
            else
            {
                state.Components = GetComponentCount(
                    info.bits_per_pixel, info.image_type == 3, out state.Depth);
            }

            if (state.Components == 0)
            {
                throw new StbImageReadException(ErrorCode.BadComponentCount);
            }

            state.OutComponents = state.Components;
            state.OutDepth      = state.Depth;

            state.Orientation =
                ImageOrientation.LeftToRight |
                (info.inverted != 0 ? ImageOrientation.BottomToTop : ImageOrientation.TopToBottom);

            state.StateReady();
            return(info);
        }