Пример #1
0
        private static void Read24BitImage(BinaryReader aReader, BMPImage bmp)
        {
            int w         = Mathf.Abs(bmp.info.width);
            int h         = Mathf.Abs(bmp.info.height);
            int rowLength = ((24 * w + 31) / 32) * 4;
            int count     = rowLength * h;
            int pad       = rowLength - w * 3;

            Color32[] data = bmp.imageData = new Color32[w * h];
            if (aReader.BaseStream.Position + count > aReader.BaseStream.Length)
            {
                Debug.LogError("Unexpected end of file. (Have " + (aReader.BaseStream.Position + count) + " bytes, expected " + aReader.BaseStream.Length + " bytes)");
                return;
            }
            int shiftR = GetShiftCount(bmp.rMask);
            int shiftG = GetShiftCount(bmp.gMask);
            int shiftB = GetShiftCount(bmp.bMask);

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    uint v = aReader.ReadByte() | ((uint)aReader.ReadByte() << 8) | ((uint)aReader.ReadByte() << 16);
                    byte r = (byte)((v & bmp.rMask) >> shiftR);
                    byte g = (byte)((v & bmp.gMask) >> shiftG);
                    byte b = (byte)((v & bmp.bMask) >> shiftB);
                    data[x + y * w] = new Color32(r, g, b, 255);
                }
                for (int i = 0; i < pad; i++)
                {
                    aReader.ReadByte();
                }
            }
        }
Пример #2
0
        private static void Read32BitImage(BinaryReader aReader, BMPImage bmp)
        {
            int w = Mathf.Abs(bmp.info.width);
            int h = Mathf.Abs(bmp.info.height);

            Color32[] data = bmp.imageData = new Color32[w * h];
            if (aReader.BaseStream.Position + w * h * 4 > aReader.BaseStream.Length)
            {
                Debug.LogError("Unexpected end of file.");
                return;
            }
            int  shiftR = GetShiftCount(bmp.rMask);
            int  shiftG = GetShiftCount(bmp.gMask);
            int  shiftB = GetShiftCount(bmp.bMask);
            int  shiftA = GetShiftCount(bmp.aMask);
            byte a      = 255;

            for (int i = 0; i < data.Length; i++)
            {
                uint v = aReader.ReadUInt32();
                byte r = (byte)((v & bmp.rMask) >> shiftR);
                byte g = (byte)((v & bmp.gMask) >> shiftG);
                byte b = (byte)((v & bmp.bMask) >> shiftB);
                if (bmp.bMask != 0)
                {
                    a = (byte)((v & bmp.aMask) >> shiftA);
                }
                data[i] = new Color32(r, g, b, a);
            }
        }
Пример #3
0
        private static void ReadIndexedImageRLE8(BinaryReader aReader, BMPImage bmp)
        {
            int w = Mathf.Abs(bmp.info.width);
            int h = Mathf.Abs(bmp.info.height);

            Color32[] data    = bmp.imageData = new Color32[w * h];
            int       x       = 0;
            int       y       = 0;
            int       yOffset = 0;

            while (aReader.BaseStream.Position < aReader.BaseStream.Length - 1)
            {
                int  count = (int)aReader.ReadByte();
                byte d     = aReader.ReadByte();
                if (count > 0)
                {
                    for (int i = count; i > 0; i--)
                    {
                        data[x++ + yOffset] = bmp.palette[d];
                    }
                }
                else
                {
                    if (d == 0)
                    {
                        x       = 0;
                        y      += 1;
                        yOffset = y * w;
                    }
                    else if (d == 1)
                    {
                        break;
                    }
                    else if (d == 2)
                    {
                        x      += aReader.ReadByte();
                        y      += aReader.ReadByte();
                        yOffset = y * w;
                    }
                    else
                    {
                        for (int i = d; i > 0; i--)
                        {
                            data[x++ + yOffset] = bmp.palette[aReader.ReadByte()];
                        }
                        if ((d & 0x01) > 0)
                        {
                            aReader.ReadByte(); // padding (word alignment)
                        }
                    }
                }
            }
        }
Пример #4
0
        public static List <Color32> ReadPalette(BinaryReader aReader, BMPImage aBmp, bool aReadAlpha)
        {
            uint count = aBmp.info.nPaletteColors;

            if (count == 0u)
            {
                count = 1u << aBmp.info.nBitsPerPixel;
            }
            var palette = new List <Color32>((int)count);

            for (int i = 0; i < count; i++)
            {
                byte b = aReader.ReadByte();
                byte g = aReader.ReadByte();
                byte r = aReader.ReadByte();
                byte a = aReader.ReadByte();
                if (!aReadAlpha)
                {
                    a = 255;
                }
                palette.Add(new Color32(r, g, b, a));
            }
            return(palette);
        }
Пример #5
0
        private static void ReadIndexedImage(BinaryReader aReader, BMPImage bmp)
        {
            int w         = Mathf.Abs(bmp.info.width);
            int h         = Mathf.Abs(bmp.info.height);
            int bitCount  = bmp.info.nBitsPerPixel;
            int rowLength = ((bitCount * w + 31) / 32) * 4;
            int count     = rowLength * h;
            int pad       = rowLength - (w * bitCount + 7) / 8;

            Color32[] data = bmp.imageData = new Color32[w * h];
            if (aReader.BaseStream.Position + count > aReader.BaseStream.Length)
            {
                Debug.LogError("Unexpected end of file. (Have " + (aReader.BaseStream.Position + count) + " bytes, expected " + aReader.BaseStream.Length + " bytes)");
                return;
            }
            BitStreamReader bitReader = new BitStreamReader(aReader);

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    int v = (int)bitReader.ReadBits(bitCount);
                    if (v >= bmp.palette.Count)
                    {
                        Debug.LogError("Indexed bitmap has indices greater than it's color palette");
                        return;
                    }
                    data[x + y * w] = bmp.palette[v];
                }
                bitReader.Flush();
                for (int i = 0; i < pad; i++)
                {
                    aReader.ReadByte();
                }
            }
        }
Пример #6
0
        public BMPImage LoadBMP(BinaryReader aReader)
        {
            BMPImage bmp = new BMPImage();

            if (!ReadFileHeader(aReader, ref bmp.header))
            {
                Debug.LogError("Not a BMP file");
                return(null);
            }
            if (!ReadInfoHeader(aReader, ref bmp.info))
            {
                Debug.LogError("Unsupported header format");
                return(null);
            }
            if (bmp.info.compressionMethod != BMPComressionMode.BI_RGB &&
                bmp.info.compressionMethod != BMPComressionMode.BI_BITFIELDS &&
                bmp.info.compressionMethod != BMPComressionMode.BI_ALPHABITFIELDS &&
                bmp.info.compressionMethod != BMPComressionMode.BI_RLE4 &&
                bmp.info.compressionMethod != BMPComressionMode.BI_RLE8
                )
            {
                Debug.LogError("Unsupported image format: " + bmp.info.compressionMethod);
                return(null);
            }
            long offset = 14 + bmp.info.size;

            aReader.BaseStream.Seek(offset, SeekOrigin.Begin);
            if (bmp.info.nBitsPerPixel < 24)
            {
                bmp.rMask = 0x00007C00;
                bmp.gMask = 0x000003E0;
                bmp.bMask = 0x0000001F;
            }

            if (bmp.info.compressionMethod == BMPComressionMode.BI_BITFIELDS || bmp.info.compressionMethod == BMPComressionMode.BI_ALPHABITFIELDS)
            {
                bmp.rMask = aReader.ReadUInt32();
                bmp.gMask = aReader.ReadUInt32();
                bmp.bMask = aReader.ReadUInt32();
            }
            if (ForceAlphaReadWhenPossible)
            {
                bmp.aMask = GetMask(bmp.info.nBitsPerPixel) ^ (bmp.rMask | bmp.gMask | bmp.bMask);
            }

            if (bmp.info.compressionMethod == BMPComressionMode.BI_ALPHABITFIELDS)
            {
                bmp.aMask = aReader.ReadUInt32();
            }

            if (bmp.info.nPaletteColors > 0 || bmp.info.nBitsPerPixel <= 8)
            {
                bmp.palette = ReadPalette(aReader, bmp, ReadPaletteAlpha || ForceAlphaReadWhenPossible);
            }


            aReader.BaseStream.Seek(bmp.header.offset, SeekOrigin.Begin);
            bool uncompressed = bmp.info.compressionMethod == BMPComressionMode.BI_RGB ||
                                bmp.info.compressionMethod == BMPComressionMode.BI_BITFIELDS ||
                                bmp.info.compressionMethod == BMPComressionMode.BI_ALPHABITFIELDS;

            if (bmp.info.nBitsPerPixel == 32 && uncompressed)
            {
                Read32BitImage(aReader, bmp);
            }
            else if (bmp.info.nBitsPerPixel == 24 && uncompressed)
            {
                Read24BitImage(aReader, bmp);
            }
            else if (bmp.info.nBitsPerPixel == 16 && uncompressed)
            {
                Read16BitImage(aReader, bmp);
            }
            else if (bmp.info.compressionMethod == BMPComressionMode.BI_RLE4 && bmp.info.nBitsPerPixel == 4 && bmp.palette != null)
            {
                ReadIndexedImageRLE4(aReader, bmp);
            }
            else if (bmp.info.compressionMethod == BMPComressionMode.BI_RLE8 && bmp.info.nBitsPerPixel == 8 && bmp.palette != null)
            {
                ReadIndexedImageRLE8(aReader, bmp);
            }
            else if (uncompressed && bmp.info.nBitsPerPixel <= 8 && bmp.palette != null)
            {
                ReadIndexedImage(aReader, bmp);
            }
            else
            {
                Debug.LogError("Unsupported file format: " + bmp.info.compressionMethod + " BPP: " + bmp.info.nBitsPerPixel);
                return(null);
            }
            return(bmp);
        }