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(); } } }
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); } }
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) } } } } }
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); }
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(); } } }
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); }