From e21ce73554809546c4d73f76a699e17d2d0edc7c Mon Sep 17 00:00:00 2001 From: "bill@Ixion" Date: Sat, 5 Sep 2009 14:07:05 -0500 Subject: [PATCH] now supports encoding to BMP as well as TGA, hooray --- src/modules/image/Image.h | 3 +- src/modules/image/devil/ImageData.cpp | 72 ++++++++++++++++++++++++--- src/modules/image/wrap_Image.cpp | 8 ++- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/modules/image/Image.h b/src/modules/image/Image.h index 9468538b3..c4509212a 100644 --- a/src/modules/image/Image.h +++ b/src/modules/image/Image.h @@ -78,7 +78,8 @@ namespace image virtual ImageData * newImageData(int width, int height, void *data) = 0; enum ImageFormat { - FORMAT_TGA + FORMAT_TGA, + FORMAT_BMP }; }; // Image diff --git a/src/modules/image/devil/ImageData.cpp b/src/modules/image/devil/ImageData.cpp index 03f1866ef..74777dd60 100644 --- a/src/modules/image/devil/ImageData.cpp +++ b/src/modules/image/devil/ImageData.cpp @@ -169,13 +169,73 @@ namespace devil ILubyte * data; ILuint w = d->getWidth(); ILuint h = d->getHeight(); - int headerLen, bpp; + int headerLen, bpp, row, size; switch (f) { - case Image::FORMAT_TGA: // MSVC issues warning when there's no case statement. - default: // since we only support one format + case Image::FORMAT_BMP: + headerLen = 54; + bpp = 3; + row = w * bpp; + int padding = row & 3; + size = h * (row + padding); + int filesize = size + headerLen; + data = new ILubyte[filesize]; + // Here's the header for the BMP file format. + data[0] = 66; // "B" + data[1] = 77; // "M" + data[2] = filesize; // size of the file + data[3] = (filesize >> 8) & 255; + data[4] = (filesize >> 16) & 255; + data[5] = (filesize >> 24) & 255; + data[6] = data[7] = data[8] = data[9] = 0; // useless reserved values + data[10] = headerLen; // offset where pixel data begins + data[11] = (headerLen >> 8) & 255; + data[12] = (headerLen >> 16) & 255; + data[13] = (headerLen >> 24) & 255; + data[14] = headerLen - 14; // length of this part of the header + data[15] = (data[14] >> 8) & 255; + data[16] = (data[14] >> 16) & 255; + data[17] = (data[14] >> 24) & 255; + data[18] = w; // width of the bitmap + data[19] = (w >> 8) & 255; + data[20] = (w >> 16) & 255; + data[21] = (w >> 24) & 255; + data[22] = -h; // negative height of the bitmap - used so we don't have to flip the data + data[23] = ((-h) >> 8) & 255; + data[24] = ((-h) >> 16) & 255; + data[25] = ((-h) >> 24) & 255; + data[26] = 1; // number of color planes + data[27] = 0; + data[28] = bpp * 8; // bits per pixel + data[29] = 0; + data[30] = data[31] = data[32] = data[33] = 0; // RGB - no compression + data[34] = (row + padding) * h; // length of the pixel data + data[35] = (data[34] >> 8) & 255; + data[36] = (data[34] >> 16) & 255; + data[37] = (data[34] >> 24) & 255; + data[38] = 2835; // horizontal pixels per meter + data[39] = (2835 >> 8) & 255; + data[40] = (2835 >> 16) & 255; + data[41] = (2835 >> 24) & 255; + data[42] = 2835; // vertical pixels per meter + data[43] = data[39]; + data[44] = data[40]; + data[45] = data[41]; + data[46] = data[47] = data[48] = data[49] = 0; // number of colors in the palette + data[50] = data[51] = data[52] = data[53] = 0; // all colors are important! + // Okay, header's done! Now for the pixel data... + data += headerLen; + d->getData(); // bind the imagedata's image + for (int i = 0; i < h; i++) { // we've got to loop through the rows, adding the pixel data plus padding + ilCopyPixels(0,i,0,w,1,1,IL_BGR,IL_UNSIGNED_BYTE,data); + data += row; + } + data -= filesize; + break; + case Image::FORMAT_TGA: + default: // TGA is the default format headerLen = 18; bpp = 3; - int size = h * w * bpp; + size = h * w * bpp; data = new ILubyte[size + headerLen]; // here's the header for the Targa file format. data[0] = 0; // ID field size @@ -199,7 +259,7 @@ namespace devil ilCopyPixels(0,0,0,w,h,1,IL_BGR,IL_UNSIGNED_BYTE,data); // convert the pixels to BGR (remember, little-endian) and copy them to data // It's Targa, so we have to flip the image. - int row = w * bpp; + row = w * bpp; ILubyte * temp = new ILubyte[row]; ILubyte * src = data - row; ILubyte * dst = data + size; @@ -210,8 +270,8 @@ namespace devil } data -= headerLen; delete [] temp; - return new love::image::EncodedImageData(data, f, size + headerLen); } + return new love::image::EncodedImageData(data, f, size + headerLen); } } // devil diff --git a/src/modules/image/wrap_Image.cpp b/src/modules/image/wrap_Image.cpp index 1bee8e730..d9c02a0b3 100644 --- a/src/modules/image/wrap_Image.cpp +++ b/src/modules/image/wrap_Image.cpp @@ -89,6 +89,12 @@ namespace image luaopen_imagedata, 0 }; + + static const Constant constants[] = { + { "format_tga", Image::FORMAT_TGA }, + { "format_bmp", Image::FORMAT_BMP }, + { 0, 0 } + }; int luaopen_love_image(lua_State * L) { @@ -110,7 +116,7 @@ namespace image w.flags = MODULE_IMAGE_T; w.functions = functions; w.types = types; - w.constants = 0; + w.constants = constants; return luax_register_module(L, w); }