summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/im_convertbitmap.cpp165
-rw-r--r--src/im_file.cpp31
-rw-r--r--src/im_filebuffer.cpp4
-rw-r--r--src/im_format_gif.cpp6
-rw-r--r--src/im_format_png.cpp52
-rw-r--r--src/im_image.cpp203
6 files changed, 237 insertions, 224 deletions
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 <stdlib.h>
@@ -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<transp_count; i++)
+ new_transp_map[i] = transp_map[remap[i]];
+ imFileSetAttribute(ifile, "TransparencyMap", IM_BYTE, transp_count, new_transp_map);
+ }
}
static void iFileCheckConvertBinary(imFile* ifile, imbyte* data)
diff --git a/src/im_filebuffer.cpp b/src/im_filebuffer.cpp
index 9ab2fda..09c5ad4 100644
--- a/src/im_filebuffer.cpp
+++ b/src/im_filebuffer.cpp
@@ -2,7 +2,7 @@
* \brief File Access - Buffer Management
*
* See Copyright Notice in im_lib.h
- * $Id: im_filebuffer.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ * $Id: im_filebuffer.cpp,v 1.2 2009/08/13 22:34:25 scuri Exp $
*/
#include <stdlib.h>
@@ -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; i<num_trans; i++)
+ {
+ if (trans[i] < min_alpha)
+ {
+ min_alpha = trans[i];
+ transp_index = (imbyte)i;
+ }
+ }
+ attrib_table->Set("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 <stdlib.h>
@@ -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; i<transp_count; i++)
- iImageExpandTranspIndex((imbyte*)image->data[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)