diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/im_convertbitmap.cpp | 165 | ||||
| -rw-r--r-- | src/im_file.cpp | 31 | ||||
| -rw-r--r-- | src/im_filebuffer.cpp | 4 | ||||
| -rw-r--r-- | src/im_format_gif.cpp | 6 | ||||
| -rw-r--r-- | src/im_format_png.cpp | 52 | ||||
| -rw-r--r-- | src/im_image.cpp | 203 | 
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) | 
