aboutsummaryrefslogtreecommitdiff
path: root/dep/g3dlite/source/GImage_bmp.cpp
diff options
context:
space:
mode:
authorjackpoz <giacomopoz@gmail.com>2014-08-22 16:58:23 +0200
committerjackpoz <giacomopoz@gmail.com>2014-08-22 21:00:56 +0200
commit5e8277e923c5545a15bae7c740ab6afaa597a59f (patch)
tree4cf5212c080588a7e868ee60134fc7fff51e400a /dep/g3dlite/source/GImage_bmp.cpp
parenta63aa858dcb400eafb97eed1f590e34c27d934a4 (diff)
Core/Dependencies: Update G3D to v9.0 r4036
Diffstat (limited to 'dep/g3dlite/source/GImage_bmp.cpp')
-rw-r--r--dep/g3dlite/source/GImage_bmp.cpp717
1 files changed, 0 insertions, 717 deletions
diff --git a/dep/g3dlite/source/GImage_bmp.cpp b/dep/g3dlite/source/GImage_bmp.cpp
deleted file mode 100644
index 425a7e1a1d2..00000000000
--- a/dep/g3dlite/source/GImage_bmp.cpp
+++ /dev/null
@@ -1,717 +0,0 @@
-/**
- @file GImage_bmp.cpp
- @author Morgan McGuire, http://graphics.cs.williams.edu
- @created 2002-05-27
- @edited 2006-05-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Log.h"
-
-namespace G3D {
-
-#ifndef G3D_WIN32
-/**
- This is used by the Windows bitmap I/O.
- */
-static const int BI_RGB = 0;
-#endif
-
-void GImage::encodeBMP(
- BinaryOutput& out) const {
-
- debugAssert(m_channels == 1 || m_channels == 3);
- out.setEndian(G3D_LITTLE_ENDIAN);
-
- uint8 red;
- uint8 green;
- uint8 blue;
- int pixelBufferSize = m_width * m_height * 3;
- int fileHeaderSize = 14;
- int infoHeaderSize = 40;
- int BMScanWidth;
- int BMPadding;
-
- // First write the BITMAPFILEHEADER
- //
- // WORD bfType;
- // DWORD bfSize;
- // WORD bfReserved1;
- // WORD bfReserved2;
- // DWORD bfOffBits;
-
- // Type
- out.writeUInt8('B');
- out.writeUInt8('M');
-
- // File size
- out.writeUInt32(fileHeaderSize + infoHeaderSize + pixelBufferSize);
-
- // Two reserved fields set to zero
- out.writeUInt16(0);
- out.writeUInt16(0);
-
- // The offset, in bytes, from the BITMAPFILEHEADER structure
- // to the bitmap bits.
- out.writeUInt32(infoHeaderSize + fileHeaderSize);
-
- // Now the BITMAPINFOHEADER
- //
- // DWORD biSize;
- // LONG biWidth;
- // LONG biHeight;
- // WORD biPlanes;
- // WORD biBitCount
- // DWORD biCompression;
- // DWORD biSizeImage;
- // LONG biXPelsPerMeter;
- // LONG biYPelsPerMeter;
- // DWORD biClrUsed;
- // DWORD biClrImportant;
-
- // Size of the info header
- out.writeUInt32(infoHeaderSize);
-
- // Width and height of the image
- out.writeUInt32(m_width);
- out.writeUInt32(m_height);
-
- // Planes ("must be set to 1")
- out.writeUInt16(1);
-
- // BitCount and CompressionType
- out.writeUInt16(24);
- out.writeUInt32(BI_RGB);
-
- // Image size ("may be zero for BI_RGB bitmaps")
- out.writeUInt32(0);
-
- // biXPelsPerMeter
- out.writeUInt32(0);
- // biYPelsPerMeter
- out.writeUInt32(0);
-
- // biClrUsed
- out.writeUInt32(0);
-
- // biClrImportant
- out.writeUInt32(0);
-
- BMScanWidth = m_width * 3;
-
- if (BMScanWidth & 3) {
- BMPadding = 4 - (BMScanWidth & 3);
- } else {
- BMPadding = 0;
- }
-
- int hStart = m_height - 1;
- int hEnd = -1;
- int hDir = -1;
- int dest;
-
- // Write the pixel data
- for (int h = hStart; h != hEnd; h += hDir) {
- dest = m_channels * h * m_width;
- for (int w = 0; w < m_width; ++w) {
-
- if (m_channels == 3) {
- red = m_byte[dest];
- green = m_byte[dest + 1];
- blue = m_byte[dest + 2];
- } else {
- red = m_byte[dest];
- green = m_byte[dest];
- blue = m_byte[dest];
- }
-
- out.writeUInt8(blue);
- out.writeUInt8(green);
- out.writeUInt8(red);
-
- dest += m_channels;
- }
-
- if (BMPadding > 0) {
- out.skip(BMPadding);
- }
- }
-}
-
-
-void GImage::decodeBMP(
- BinaryInput& input) {
-
- // The BMP decoding uses these flags.
- static const uint16 PICTURE_NONE = 0x0000;
- static const uint16 PICTURE_BITMAP = 0x1000;
-
- // Compression Flags
- static const uint16 PICTURE_UNCOMPRESSED = 0x0100;
- static const uint16 PICTURE_MONOCHROME = 0x0001;
- static const uint16 PICTURE_4BIT = 0x0002;
- static const uint16 PICTURE_8BIT = 0x0004;
- static const uint16 PICTURE_16BIT = 0x0008;
- static const uint16 PICTURE_24BIT = 0x0010;
- static const uint16 PICTURE_32BIT = 0x0020;
-
- (void)PICTURE_16BIT;
- (void)PICTURE_32BIT;
-
- // This is a simple BMP loader that can handle uncompressed BMP files.
- // Verify this is a BMP file by looking for the BM tag.
- input.reset();
- std::string tag = input.readString(2);
- if (tag != "BM") {
- throw Error("Not a BMP file", input.getFilename());
- }
-
- m_channels = 3;
- // Skip to the BITMAPINFOHEADER's width and height
- input.skip(16);
-
- m_width = input.readUInt32();
- m_height = input.readUInt32();
-
- // Skip to the bit count and compression type
- input.skip(2);
-
- uint16 bitCount = input.readUInt16();
- uint32 compressionType = input.readUInt32();
-
- uint8 red;
- uint8 green;
- uint8 blue;
- uint8 blank;
-
- // Only uncompressed bitmaps are supported by this code
- if ((int32)compressionType != BI_RGB) {
- throw Error("BMP images must be uncompressed", input.getFilename());
- }
-
- uint8* palette = NULL;
-
- // Create the palette if needed
- if (bitCount <= 8) {
-
- // Skip to the palette color count in the header
- input.skip(12);
-
- int numColors = input.readUInt32();
-
- palette = (uint8*)System::malloc(numColors * 3);
- debugAssert(palette);
-
- // Skip past the end of the header to the palette info
- input.skip(4);
-
- int c;
- for(c = 0; c < numColors * 3; c += 3) {
- // Palette information in bitmaps is stored in BGR_ format.
- // That means it's blue-green-red-blank, for each entry.
- blue = input.readUInt8();
- green = input.readUInt8();
- red = input.readUInt8();
- blank = input.readUInt8();
-
- palette[c] = red;
- palette[c + 1] = green;
- palette[c + 2] = blue;
- }
- }
-
- int hStart = 0;
- int hEnd = 0;
- int hDir = 0;
-
- if (m_height < 0) {
- m_height = -m_height;
- hStart = 0;
- hEnd = m_height;
- hDir = 1;
- } else {
- //height = height;
- hStart = m_height - 1;
- hEnd = -1;
- hDir = -1;
- }
-
- m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 3);
- debugAssert(m_byte);
-
- int BMScanWidth;
- int BMPadding;
- uint8 BMGroup;
- uint8 BMPixel8;
- int currPixel;
- int dest;
- int flags = PICTURE_NONE;
-
- if (bitCount == 1) {
- // Note that this file is not necessarily grayscale, since it's possible
- // the palette is blue-and-white, or whatever. But of course most image
- // programs only write 1-bit images if they're black-and-white.
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_MONOCHROME;
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = (m_width + 7) >> 3;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- // Powers of 2
- int pow2[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 3 * h * m_width;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMGroup = input.readUInt8();
-
- // Now we read the pixels. Usually there are eight pixels per byte,
- // since each pixel is represented by one bit, but if the width
- // is not a multiple of eight, the last byte will have some bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "width" number of pixels.
- for (int i = 7; i >= 0; --i) {
- if (currPixel < m_width) {
- int src = 3 * ((BMGroup & pow2[i]) >> i);
-
- m_byte[dest] = palette[src];
- m_byte[dest + 1] = palette[src + 1];
- m_byte[dest + 2] = palette[src + 2];
-
- ++currPixel;
- dest += 3;
- }
- }
- }
- }
-
- } else if (bitCount == 4) {
-
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_4BIT;
-
- // For bitmaps, each scanline is dword-aligned.
- int BMScanWidth = (m_width + 1) >> 1;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 3 * h * m_width;
-
- for (int w = 0; w < BMScanWidth; w++) {
-
- BMGroup = input.readUInt8();
- int src[2];
- src[0] = 3 * ((BMGroup & 0xF0) >> 4);
- src[1] = 3 * (BMGroup & 0x0F);
-
- // Now we read the pixels. Usually there are two pixels per byte,
- // since each pixel is represented by four bits, but if the width
- // is not a multiple of two, the last byte will have only four bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "Width" number of pixels.
-
- for (int i = 0; i < 2; ++i) {
- if (currPixel < m_width) {
- int tsrc = src[i];
-
- m_byte[dest] = palette[tsrc];
- m_byte[dest + 1] = palette[tsrc + 1];
- m_byte[dest + 2] = palette[tsrc + 2];
-
- ++currPixel;
- dest += 3;
- }
- }
- }
- }
-
- } else if (bitCount == 8) {
-
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_8BIT;
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = m_width;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMPixel8 = input.readUInt8();
-
- if (currPixel < m_width) {
- dest = 3 * ((h * m_width) + currPixel);
- int src = 3 * BMPixel8;
-
- m_byte[dest] = palette[src];
- m_byte[dest + 1] = palette[src + 1];
- m_byte[dest + 2] = palette[src + 2];
-
- ++currPixel;
- }
- }
- }
-
- } else if (bitCount == 16) {
-
- m_memMan->free(m_byte);
- m_byte = NULL;
- System::free(palette);
- palette = NULL;
- throw Error("16-bit bitmaps not supported", input.getFilename());
-
- } else if (bitCount == 24) {
- input.skip(20);
-
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_24BIT;
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = m_width * 3;
-
- if (BMScanWidth & 3) {
- BMPadding = 4 - (BMScanWidth & 3);
- } else {
- BMPadding = 0;
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
- dest = 3 * h * m_width;
- for (int w = 0; w < m_width; ++w) {
-
- blue = input.readUInt8();
- green = input.readUInt8();
- red = input.readUInt8();
-
- m_byte[dest] = red;
- m_byte[dest + 1] = green;
- m_byte[dest + 2] = blue;
-
- dest += 3;
- }
-
- if (BMPadding) {
- input.skip(2);
- }
- }
-
- } else if (bitCount == 32) {
-
- m_memMan->free(m_byte);
- m_byte = NULL;
- System::free(palette);
- palette = NULL;
- throw Error("32 bit bitmaps not supported", input.getFilename());
-
- } else {
- // We support all possible bit depths, so if the
- // code gets here, it's not even a real bitmap.
- m_memMan->free(m_byte);
- m_byte = NULL;
- throw Error("Not a bitmap!", input.getFilename());
- }
-
- System::free(palette);
- palette = NULL;
-}
-
-
-void GImage::decodeICO(
- BinaryInput& input) {
-
- // Header
- uint16 r = input.readUInt16();
- debugAssert(r == 0);
- r = input.readUInt16();
- debugAssert(r == 1);
-
- // Read the number of icons, although we'll only load the
- // first one.
- int count = input.readUInt16();
-
- m_channels = 4;
-
- debugAssert(count > 0);
-
- const uint8* headerBuffer = input.getCArray() + input.getPosition();
- int maxWidth = 0, maxHeight = 0;
- int maxHeaderNum = 0;
- for (int currentHeader = 0; currentHeader < count; ++currentHeader) {
-
- const uint8* curHeaderBuffer = headerBuffer + (currentHeader * 16);
- int tmpWidth = curHeaderBuffer[0];
- int tmpHeight = curHeaderBuffer[1];
- // Just in case there is a non-square icon, checking area
- if ((tmpWidth * tmpHeight) > (maxWidth * maxHeight)) {
- maxWidth = tmpWidth;
- maxHeight = tmpHeight;
- maxHeaderNum = currentHeader;
- }
- }
-
- input.skip(maxHeaderNum * 16);
-
- m_width = input.readUInt8();
- m_height = input.readUInt8();
- int numColors = input.readUInt8();
-
- m_byte = (uint8*)m_memMan->alloc(m_width * m_height * m_channels);
- debugAssert(m_byte);
-
- // Bit mask for packed bits
- int mask = 0;
-
- int bitsPerPixel = 8;
-
- switch (numColors) {
- case 2:
- mask = 0x01;
- bitsPerPixel = 1;
- break;
-
- case 16:
- mask = 0x0F;
- bitsPerPixel = 4;
- break;
-
- case 0:
- numColors = 256;
- mask = 0xFF;
- bitsPerPixel = 8;
- break;
-
- default:
- throw Error("Unsupported ICO color count.", input.getFilename());
- }
-
- input.skip(5);
- // Skip 'size' unused
- input.skip(4);
-
- int offset = input.readUInt32();
-
- // Skip over any other icon descriptions
- input.setPosition(offset);
-
- // Skip over bitmap header; it is redundant
- input.skip(40);
-
- Array<Color4uint8> palette;
- palette.resize(numColors, true);
- for (int c = 0; c < numColors; ++c) {
- palette[c].b = input.readUInt8();
- palette[c].g = input.readUInt8();
- palette[c].r = input.readUInt8();
- palette[c].a = input.readUInt8();
- }
-
- // The actual image and mask follow
-
- // The XOR Bitmap is stored as 1-bit, 4-bit or 8-bit uncompressed Bitmap
- // using the same encoding as BMP files. The AND Bitmap is stored in as
- // 1-bit uncompressed Bitmap.
- //
- // Pixels are stored bottom-up, left-to-right. Pixel lines are padded
- // with zeros to end on a 32bit (4byte) boundary. Every line will have the
- // same number of bytes. Color indices are zero based, meaning a pixel color
- // of 0 represents the first color table entry, a pixel color of 255 (if there
- // are that many) represents the 256th entry.
-/*
- int bitsPerRow = width * bitsPerPixel;
- int bytesPerRow = iCeil((double)bitsPerRow / 8);
- // Rows are padded to 32-bit boundaries
- bytesPerRow += bytesPerRow % 4;
-
- // Read the XOR values into the color channel
- for (int y = height - 1; y >= 0; --y) {
- int x = 0;
- // Read the row
- for (int i = 0; i < bytesPerRow; ++i) {
- uint8 byte = input.readUInt8();
- for (int j = 0; (j < 8) && (x < width); ++x, j += bitsPerPixel) {
- int bit = ((byte << j) >> (8 - bitsPerPixel)) & mask;
- pixel4(x, y) = colorTable[bit];
- }
- }
- }
-*/
- int hStart = 0;
- int hEnd = 0;
- int hDir = 0;
-
- if (m_height < 0) {
- m_height = -m_height;
- hStart = 0;
- hEnd = m_height;
- hDir = 1;
- } else {
- //height = height;
- hStart = m_height - 1;
- hEnd = -1;
- hDir = -1;
- }
-
- int BMScanWidth;
- uint8 BMGroup;
- uint8 BMPixel8;
- int currPixel;
- int dest;
-
- if (bitsPerPixel == 1) {
- // Note that this file is not necessarily grayscale, since it's possible
- // the palette is blue-and-white, or whatever. But of course most image
- // programs only write 1-bit images if they're black-and-white.
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = (m_width + 7) >> 3;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- // Powers of 2
- int pow2[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 3 * h * m_width;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMGroup = input.readUInt8();
-
- // Now we read the pixels. Usually there are eight pixels per byte,
- // since each pixel is represented by one bit, but if the width
- // is not a multiple of eight, the last byte will have some bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "width" number of pixels.
- for (int i = 7; i >= 0; --i) {
- if (currPixel < m_width) {
- int src = ((BMGroup & pow2[i]) >> i);
-
- m_byte[dest] = palette[src].r;
- m_byte[dest + 1] = palette[src].g;
- m_byte[dest + 2] = palette[src].b;
-
- ++currPixel;
- dest += 4;
- }
- }
- }
- }
-
- } else if (bitsPerPixel == 4) {
-
- // For bitmaps, each scanline is dword-aligned.
- int BMScanWidth = (m_width + 1) >> 1;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 4 * h * m_width;
-
- for (int w = 0; w < BMScanWidth; w++) {
-
- BMGroup = input.readUInt8();
- int src[2];
- src[0] = ((BMGroup & 0xF0) >> 4);
- src[1] = (BMGroup & 0x0F);
-
- // Now we read the pixels. Usually there are two pixels per byte,
- // since each pixel is represented by four bits, but if the width
- // is not a multiple of two, the last byte will have only four bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "Width" number of pixels.
-
- for (int i = 0; i < 2; ++i) {
- if (currPixel < m_width) {
- int tsrc = src[i];
-
- m_byte[dest] = palette[tsrc].r;
- m_byte[dest + 1] = palette[tsrc].g;
- m_byte[dest + 2] = palette[tsrc].b;
-
- ++currPixel;
- dest += 4;
- }
- }
- }
- }
-
- } else if (bitsPerPixel == 8) {
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = m_width;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMPixel8 = input.readUInt8();
-
- if (currPixel < m_width) {
- dest = 4 * ((h * m_width) + currPixel);
- int src = BMPixel8;
-
- m_byte[dest] = palette[src].r;
- m_byte[dest + 1] = palette[src].g;
- m_byte[dest + 2] = palette[src].b;
-
- ++currPixel;
- }
- }
- }
- }
-
- // Read the mask into the alpha channel
- int bitsPerRow = m_width;
- int bytesPerRow = iCeil((double)bitsPerRow / 8);
-
- // For bitmaps, each scanline is dword-aligned.
- //BMScanWidth = (width + 1) >> 1;
- if (bytesPerRow & 3) {
- bytesPerRow += 4 - (bytesPerRow & 3);
- }
-
- for (int y = m_height - 1; y >= 0; --y) {
- int x = 0;
- // Read the row
- for (int i = 0; i < bytesPerRow; ++i) {
- uint8 byte = input.readUInt8();
- for (int j = 0; (j < 8) && (x < m_width); ++x, ++j) {
- int bit = (byte >> (7 - j)) & 0x01;
- pixel4(x, y).a = (1 - bit) * 0xFF;
- }
- }
- }
-
-}
-
-
-}