From 380fdb5d8c80d094e5a8bc82bfc091bc87e6c43e Mon Sep 17 00:00:00 2001 From: scuri Date: Thu, 13 Aug 2009 22:34:25 +0000 Subject: *** empty log message *** --- src/im_convertbitmap.cpp | 165 +++++++++++++++++++++++++++++++++++++- src/im_file.cpp | 31 +++++++- src/im_filebuffer.cpp | 4 +- src/im_format_gif.cpp | 6 +- src/im_format_png.cpp | 52 ++++++++---- src/im_image.cpp | 203 +---------------------------------------------- 6 files changed, 237 insertions(+), 224 deletions(-) (limited to 'src') diff --git a/src/im_convertbitmap.cpp b/src/im_convertbitmap.cpp index c9570d7..9d3c720 100644 --- a/src/im_convertbitmap.cpp +++ b/src/im_convertbitmap.cpp @@ -2,7 +2,7 @@ * \brief Image Conversion * * See Copyright Notice in im_lib.h - * $Id: im_convertbitmap.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $ + * $Id: im_convertbitmap.cpp,v 1.2 2009/08/13 22:34:25 scuri Exp $ */ #include "im.h" @@ -119,3 +119,166 @@ void imConvertPacking(const void* src_data, void* dst_data, int width, int heigh } } +static void iImageMakeGray(imbyte *map, int count, int step) +{ + for(int i = 0; i < count; i++) + { + if (*map) + *map = 255; + map += step; + } +} + +static void iImageCopyMapAlpha(imbyte *map, imbyte *gldata, int depth, int count) +{ + /* gldata can be GL_RGBA or GL_LUMINANCE_ALPHA */ + gldata += depth-1; /* position at first alpha */ + for(int i = 0; i < count; i++) + { + *gldata = *map; + map++; + gldata += depth; /* skip to next alpha */ + } +} + +static void iImageSetTranspMap(imbyte *map, imbyte *gldata, int count, imbyte *transp_map, int transp_count) +{ + /* gldata is GL_RGBA */ + gldata += 3; /* position at first alpha */ + for(int i = 0; i < count; i++) + { + if (*map < transp_count) + *gldata = transp_map[*map]; + else + *gldata = 255; /* opaque */ + + map++; + gldata += 4; + } +} + +static void iImageSetTranspColor(imbyte *gldata, int count, imbyte r, imbyte g, imbyte b) +{ + /* gldata is GL_RGBA */ + for(int i = 0; i < count; i++) + { + if (*(gldata+0) == r && + *(gldata+1) == g && + *(gldata+2) == b) + *(gldata+3) = 0; /* transparent */ + else + *(gldata+3) = 255; /* opaque */ + gldata += 4; + } +} + +static void iImageSetTranspIndex(imbyte *map, imbyte *gldata, int depth, int count, imbyte index) +{ + /* gldata can be GL_RGBA or GL_LUMINANCE_ALPHA */ + gldata += depth-1; /* position at first alpha */ + for(int i = 0; i < count; i++) + { + if (*map == index) + *gldata = 0; /* full transparent */ + else + *gldata = 255; /* opaque */ + + map++; + gldata += depth; /* skip to next alpha */ + } +} + +/* To avoid including gl.h */ +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +void* imImageGetOpenGLData(const imImage* image, int *format) +{ + if (!imImageIsBitmap(image)) + return NULL; + + int transp_count; + imbyte* transp_index = (imbyte*)imImageGetAttribute(image, "TransparencyIndex", NULL, NULL); + imbyte* transp_map = (imbyte*)imImageGetAttribute(image, "TransparencyMap", NULL, &transp_count); + imbyte* transp_color = (imbyte*)imImageGetAttribute(image, "TransparencyColor", NULL, NULL); + + int glformat; + switch(image->color_space) + { + case IM_MAP: + if (image->has_alpha || transp_map || transp_index) + glformat = GL_RGBA; + else + glformat = GL_RGB; + break; + case IM_RGB: + if (image->has_alpha || transp_color) + glformat = GL_RGBA; + else + glformat = GL_RGB; + break; + case IM_BINARY: + default: /* IM_GRAY */ + if (image->has_alpha || transp_index) + glformat = GL_LUMINANCE_ALPHA; + else + glformat = GL_LUMINANCE; + break; + } + + int depth; + switch (glformat) + { + case GL_RGB: + depth = 3; + break; + case GL_RGBA: + depth = 4; + break; + case GL_LUMINANCE_ALPHA: + depth = 2; + break; + default: /* GL_LUMINANCE */ + depth = 1; + break; + } + + int size = image->count*depth; + imImageSetAttribute(image, "GLDATA", IM_BYTE, size, NULL); + imbyte* gldata = (imbyte*)imImageGetAttribute(image, "GLDATA", NULL, NULL); + + if (image->color_space == IM_RGB) + { + if (image->has_alpha) + imConvertPacking(image->data[0], gldata, image->width, image->height, 4, IM_BYTE, 0); + else + { + imConvertPacking(image->data[0], gldata, image->width, image->height, 3, IM_BYTE, 0); + + if (transp_color) + iImageSetTranspColor(gldata, image->count, *(transp_color+0), *(transp_color+1), *(transp_color+2)); + } + } + else + { + memcpy(gldata, image->data[0], image->size); + + if (image->color_space == IM_MAP) + imConvertMapToRGB(gldata, image->count, depth, 1, image->palette, image->palette_count); + else if (image->color_space == IM_BINARY) + iImageMakeGray(gldata, image->count, (glformat==GL_LUMINANCE_ALPHA)? 2: 1); + + if (image->has_alpha) + iImageCopyMapAlpha((imbyte*)image->data[1], gldata, depth, image->count); + else if (transp_map) + iImageSetTranspMap((imbyte*)image->data[0], gldata, image->count, transp_map, transp_count); + else if (transp_index) + iImageSetTranspIndex((imbyte*)image->data[0], gldata, depth, image->count, *transp_index); + } + + if (format) *format = glformat; + return gldata; +} + diff --git a/src/im_file.cpp b/src/im_file.cpp index a43b0d4..81e0e1b 100644 --- a/src/im_file.cpp +++ b/src/im_file.cpp @@ -2,7 +2,7 @@ * \brief File Access * * See Copyright Notice in im_lib.h - * $Id: im_file.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $ + * $Id: im_file.cpp,v 1.3 2009/08/13 22:34:25 scuri Exp $ */ #include @@ -176,13 +176,28 @@ void imFileGetInfo(imFile* ifile, char* format, char* compression, int *image_co static int iFileCheckPaletteGray(imFile* ifile) { + int i; imbyte r, g, b; - for (int i = 0; i < ifile->palette_count; i++) + imbyte remaped[256]; + memset(remaped, 0, 256); + + for (i = 0; i < ifile->palette_count; i++) { imColorDecode(&r, &g, &b, ifile->palette[i]); - if (i != r || r != g || g != b) + /* if there are colors abort */ + if (r != g || g != b) return 0; + + /* grays out of order, will be remapped, but must be unique, + if there are duplicates maybe they are used for different pourposes */ + if (i != r) + { + if (!remaped[r]) + remaped[r] = 1; + else + return 0; + } } return 1; @@ -305,6 +320,16 @@ static void iFileCheckConvertGray(imFile* ifile, imbyte* data) *data = remap[*data]; data++; } + + int transp_count; + imbyte* transp_map = (imbyte*)imFileGetAttribute(ifile, "TransparencyMap", NULL, &transp_count); + if (transp_map) + { + imbyte new_transp_map[256]; + for (i=0; i @@ -53,7 +53,7 @@ static void iDoFillLineBuffer(int width, int height, int line, int plane, // file is packed // NO color space conversion, color_space must match - // If ignore alpha if necessary. + // Ignore alpha if necessary. int depth = IM_MIN(file_depth, data_depth); for (int d = 0; d < depth; d++) { diff --git a/src/im_format_gif.cpp b/src/im_format_gif.cpp index 390271a..8489331 100644 --- a/src/im_format_gif.cpp +++ b/src/im_format_gif.cpp @@ -2,7 +2,7 @@ * \brief GIF - Graphics Interchange Format * * See Copyright Notice in im_lib.h - * $Id: im_format_gif.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $ + * $Id: im_format_gif.cpp,v 1.3 2009/08/13 22:34:25 scuri Exp $ */ #include "im_format.h" @@ -659,7 +659,7 @@ static void iGIFReadGraphicsControl(imBinFile* handle, imAttribTable* attrib_tab if (word_value) attrib_table->Set("Delay", IM_USHORT, 1, &word_value); - /* transparency color */ + /* transparency index */ if (byte_value & 0x01) { imBinFileRead(handle, &byte_value, 1, 1); @@ -908,7 +908,7 @@ static int iGIFWriteGraphicsControl(imBinFile* handle, imAttribTable* attrib_tab imBinFileWrite(handle, &word_value, 1, 2); - /* transparency color */ + /* transparency index */ if (attrib_transparency) { byte_value = *(unsigned char*)attrib_transparency; diff --git a/src/im_format_png.cpp b/src/im_format_png.cpp index 314f07f..5c508e1 100644 --- a/src/im_format_png.cpp +++ b/src/im_format_png.cpp @@ -3,7 +3,7 @@ * * See Copyright Notice in im_lib.h * See libPNG Copyright Notice in png.h - * $Id: im_format_png.cpp,v 1.2 2008/12/03 15:45:34 scuri Exp $ + * $Id: im_format_png.cpp,v 1.3 2009/08/13 22:34:25 scuri Exp $ */ #include "im_format.h" @@ -277,14 +277,25 @@ void imFileFormatPNG::iReadAttrib(imAttribTable* attrib_table) attrib_table->Set("CalibrationParam", IM_BYTE, total_size+1, param_buf); } - int num_trans; - png_bytep trans; - png_color_16p trans_values; + int num_trans = 0; + png_bytep trans = NULL; + png_color_16p trans_values = NULL; if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values)) { if (imColorModeSpace(file_color_mode) == IM_MAP) { - attrib_table->Set("TransparencyIndex", IM_BYTE, num_trans, trans); + int i, min_alpha = 256; + imbyte transp_index = 0; + attrib_table->Set("TransparencyMap", IM_BYTE, num_trans, trans); + for (i=0; iSet("TransparencyIndex", IM_BYTE, 1, &transp_index); } else if (imColorModeSpace(file_color_mode) == IM_RGB) { @@ -292,12 +303,12 @@ void imFileFormatPNG::iReadAttrib(imAttribTable* attrib_table) transp_color[0] = (imbyte)(trans_values->red >> 8); transp_color[1] = (imbyte)(trans_values->green >> 8); transp_color[2] = (imbyte)(trans_values->blue >> 8); - attrib_table->Set("TransparentColor", IM_BYTE, 3, transp_color); + attrib_table->Set("TransparencyColor", IM_BYTE, 3, transp_color); } - else + else if (imColorModeSpace(file_color_mode) == IM_GRAY) { - imbyte bvalue = (imbyte)(trans_values->gray >> 8); - attrib_table->Set("TransparencyIndex", IM_BYTE, 1, &bvalue); + imbyte transp_index = (imbyte)(trans_values->gray >> 8); + attrib_table->Set("TransparencyIndex", IM_BYTE, 1, &transp_index); } } @@ -499,24 +510,37 @@ void imFileFormatPNG::iWriteAttrib(imAttribTable* attrib_table) png_set_pCAL(png_ptr, info_ptr, name, limits[0], limits[1], *equation, nparams, units, pparams); } - int transp_count; - attrib_data = attrib_table->Get("TransparencyIndex", NULL, &transp_count); + attrib_data = attrib_table->Get("TransparencyIndex", NULL, NULL); if (attrib_data) { - png_color_16 trans_values; if (imColorModeSpace(file_color_mode) == IM_MAP) { - png_set_tRNS(png_ptr, info_ptr, (imbyte*)attrib_data, transp_count, NULL); + int i; + imbyte transp_index = *(imbyte*)attrib_data; + imbyte transp_map[256]; + for (i=0; i<256; i++) + transp_map[i] = 255; + transp_map[transp_index] = 0; + png_set_tRNS(png_ptr, info_ptr, transp_map, 256, NULL); } else if (imColorModeSpace(file_color_mode) == IM_GRAY) { + png_color_16 trans_values; imbyte *transp_color = (imbyte*)attrib_data; trans_values.gray = (png_uint_16)(transp_color[0] << 8); png_set_tRNS(png_ptr, info_ptr, NULL, 1, &trans_values); } } - attrib_data = attrib_table->Get("TransparentColor"); + int transp_count; + attrib_data = attrib_table->Get("TransparencyMap", NULL, &transp_count); + if (attrib_data) + { + if (imColorModeSpace(file_color_mode) == IM_MAP) + png_set_tRNS(png_ptr, info_ptr, (imbyte*)attrib_data, transp_count, NULL); + } + + attrib_data = attrib_table->Get("TransparencyColor"); if (attrib_data) { if (imColorModeSpace(file_color_mode) == IM_RGB) diff --git a/src/im_image.cpp b/src/im_image.cpp index 7bc20de..1fb993d 100644 --- a/src/im_image.cpp +++ b/src/im_image.cpp @@ -2,7 +2,7 @@ * \brief Image Manipulation * * See Copyright Notice in im_lib.h - * $Id: im_image.cpp,v 1.3 2009/08/13 02:27:10 scuri Exp $ + * $Id: im_image.cpp,v 1.4 2009/08/13 22:34:25 scuri Exp $ */ #include @@ -15,7 +15,6 @@ #include "im_util.h" #include "im_attrib.h" #include "im_file.h" -#include "im_convert.h" int imImageCheckFormat(int color_mode, int data_type) @@ -335,125 +334,7 @@ imImage* imImageClone(const imImage* image) return new_image; } -static void iImageMakeGray(imbyte *map, int count, int step) -{ - for(int i = 0; i < count; i++) - { - if (*map) - *map = 255; - map += step; - } -} - -static void iImageCopyMapAlpha(imbyte *map, imbyte *gldata, int depth, int count) -{ - gldata += depth-1; /* position at first alpha */ - for(int i = 0; i < count; i++) - { - *gldata = *map; - map++; - gldata += depth; /* skip to next alpha */ - } -} - -static void iImageExpandTranspIndex(imbyte *map, imbyte *gldata, int depth, int count, imbyte index) -{ - gldata += depth-1; /* position at first alpha */ - for(int i = 0; i < count; i++) - { - if (*map == index) - *gldata = 255; - - map++; - gldata += depth; /* skip to next alpha */ - } -} - -/* To avoid including gl.h */ -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A - -void* imImageGetOpenGLData(imImage* image, int *format) -{ - if (!imImageIsBitmap(image)) - return NULL; - - int transp_count; - imbyte* transp_index = (imbyte*)imImageGetAttribute(image, "TransparencyIndex", NULL, &transp_count); - - int glformat; - switch(image->color_space) - { - case IM_MAP: - if (image->has_alpha || transp_index) - glformat = GL_RGBA; - else - glformat = GL_RGB; - break; - case IM_RGB: - if (image->has_alpha) - glformat = GL_RGBA; - else - glformat = GL_RGB; - break; - case IM_BINARY: - default: /* IM_GRAY */ - if (image->has_alpha || transp_index) - glformat = GL_LUMINANCE_ALPHA; - else - glformat = GL_LUMINANCE; - break; - } - - int depth; - switch (glformat) - { - case GL_RGB: - depth = 3; - break; - case GL_RGBA: - depth = 4; - break; - case GL_LUMINANCE_ALPHA: - depth = 2; - break; - default: /* GL_LUMINANCE */ - depth = 1; - break; - } - - int size = image->count*depth; - imImageSetAttribute(image, "GLDATA", IM_BYTE, size, NULL); - imbyte* gldata = (imbyte*)imImageGetAttribute(image, "GLDATA", NULL, NULL); - - if (image->color_space == IM_RGB) - imConvertPacking(image->data[0], gldata, image->width, image->height, depth, IM_BYTE, 0); - else - { - memcpy(gldata, image->data[0], image->size); - - if (image->color_space == IM_MAP) - imConvertMapToRGB(gldata, image->count, depth, 1, image->palette, image->palette_count); - else if (image->color_space == IM_BINARY) - iImageMakeGray(gldata, image->count, (glformat==GL_LUMINANCE_ALPHA)? 2: 1); - - if (image->has_alpha) - iImageCopyMapAlpha((imbyte*)image->data[1], gldata, depth, image->count); - else if (transp_index) - { - int i; - for (i=0; idata[0], gldata, depth, image->count, transp_index[i]); - } - } - - if (format) *format = glformat; - return gldata; -} - -void imImageSetAttribute(imImage* image, const char* attrib, int data_type, int count, const void* data) +void imImageSetAttribute(const imImage* image, const char* attrib, int data_type, int count, const void* data) { assert(image); assert(attrib); @@ -622,92 +503,12 @@ void imImageMakeGray(imImage *image) } } -static void iImageGrayCheckChange(imImage *image) -{ - int i, do_remap = 0; - imbyte remap[256]; - imbyte r, g, b; - - for (i = 0; i < image->palette_count; i++) - { - imColorDecode(&r, &g, &b, image->palette[i]); - - if (r != g || g != b) - return; - - remap[i] = r; - - if (r != i) - do_remap = 1; - } - - if (do_remap) - { - imbyte *map = (imbyte*)image->data[0]; - for(i = 0; i < image->count; i++) - { - *map = remap[*map]; - map++; - } - } - - image->color_space = IM_GRAY; - image->palette_count = 256; - - for (i = 0; i < 256; i++) - image->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i); -} - -static int iImageCheckBinary(const imImage* image) -{ - if (image->color_space == IM_MAP && image->palette_count == 2) - { - long black = imColorEncode(0, 0, 0); - long white = imColorEncode(255, 255, 255); - if ((image->palette[0] == black || image->palette[0] == white) && - (image->palette[1] == black || image->palette[1] == white)) - { - return 1; - } - } - - if (image->color_space == IM_GRAY && image->data_type == IM_BYTE) - { - imbyte* map = (imbyte*)image->data[0]; - for (int i = 0; i < image->count; i++) - { - if (*map != 0 && *map != 255 && *map != 1) // allow 255 and 1 - return 0; - - map++; - } - - return 1; - } - else - return 0; -} - static void iLoadImageData(imFile* ifile, imImage* image, int *error, int bitmap) { iAttributeTableCopy(ifile->attrib_table, image->attrib_table); - *error = imFileReadImageData(ifile, image->data[0], bitmap, image->has_alpha); - if (image->color_space == IM_MAP) - { imFileGetPalette(ifile, image->palette, &image->palette_count); - - // convert to gray if all colors are grays - iImageGrayCheckChange(image); - } - - // since Binary is a special case of Gray, check this - if (iImageCheckBinary(image)) - { - imImageSetBinary(image); - imImageMakeBinary(image); - } } imImage* imFileLoadImage(imFile* ifile, int index, int *error) -- cgit v1.2.3