pngenc.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: pngenc.cpp,v 1.0 2000/04/23 14:56:23 root Exp $
00004  *
00005  *
00006  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00007  *
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation under the terms of the GNU General Public License is hereby 
00010  * granted. No representations are made about the suitability of this software 
00011  * for any purpose. It is provided "as is" without express or implied warranty.
00012  * See the GNU General Public License for more details.
00013  *
00014  * Documents produced by Doxygen are derivative works derived from the
00015  * input used in their production; they are not affected by this license.
00016  *
00017  * ---------------------------------------------------------------------------
00018  *
00019  * The Portable Network Graphic format is an ISO Standard.
00020  * Most of the code below was donated by Bernhard Ristow.
00021  */
00022 
00023 #ifndef png_jmpbuf
00024 #  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
00025 #endif
00026 
00027 #define ALL_STATIC
00028 #include <../libpng/png.h>
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #include <errno.h>
00033 #include "pngenc.h"
00034 #include "message.h"
00035 
00036 #undef jmpbuf
00037 
00038 static void user_error_fn(png_structp, png_const_charp error_msg)
00039 {
00040     err("%s\n", error_msg);
00041 }
00042 
00043 static void user_warning_fn(png_structp, png_const_charp warning_msg)
00044 {
00045     err("%s\n", warning_msg);
00046 }
00047 
00048 PngEncoder::PngEncoder(Byte *rawBytes, Color *p, int w, int h, Byte d, int t) : 
00049      data(rawBytes), palette(p), width(w), height(h), depth(d), transIndex(t)
00050 {
00051    numPixels = w*h;
00052    dataPtr   = data;
00053 }
00054 
00055 PngEncoder::~PngEncoder()
00056 {
00057 }
00058 
00059 void PngEncoder::write(const char *name)
00060 {
00061    FILE           * file               = NULL;
00062    unsigned char ** rows               = 0;
00063    unsigned char  * cmap               = 0;
00064    short            numOfColors        = (1<<depth);
00065    short            bit_depth          = 4;
00066    long             i                  = 0;
00067    long             j                  = 0;
00068    png_structp      png_ptr;
00069    png_infop        info_ptr;
00070    char             user_error_ptr[]   = "PngEncoder";
00071    png_colorp       png_palette;
00072    png_byte         ti[1];
00073 
00074    png_ptr = png_create_write_struct
00075              ( PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
00076                user_error_fn, user_warning_fn);
00077    if (!png_ptr) 
00078    {
00079       err("Can not allocate writing structure!\n");
00080       return;
00081    }
00082 
00083    info_ptr = png_create_info_struct(png_ptr);
00084    if (!info_ptr) 
00085    {
00086       png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00087       err("Can not allocate writing structure!\n");
00088       return;
00089    }
00090 
00091    if (setjmp(png_jmpbuf(png_ptr))) 
00092    {
00093      png_destroy_write_struct(&png_ptr, &info_ptr);
00094      return;
00095    }
00096    else
00097    {
00098      png_palette = (png_colorp) png_malloc(png_ptr,
00099          PNG_MAX_PALETTE_LENGTH*sizeof(png_color));
00100      memset(png_palette,0,PNG_MAX_PALETTE_LENGTH*sizeof(png_color));
00101      for (i=0; i<numOfColors; i++) 
00102      {
00103        png_palette[i].red   = palette[i].red;
00104        png_palette[i].green = palette[i].green;
00105        png_palette[i].blue  = palette[i].blue;
00106      }
00107      png_set_PLTE(png_ptr, info_ptr, png_palette, numOfColors);
00108      png_set_IHDR( png_ptr, info_ptr, width, height, bit_depth,
00109          PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
00110          PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE
00111                  );
00112      free(png_palette);
00113      ti[0] = transIndex;
00114      png_set_tRNS(png_ptr,info_ptr,ti,1,NULL);
00115      rows    = (unsigned char **) calloc(sizeof(unsigned char*),height);
00116      rows[0] = (unsigned char  *) calloc(sizeof(unsigned char),height*width);
00117      for (i=1; i<height; i++) 
00118      {
00119        rows[i] = rows[i-1] + width;
00120      }
00121      for (i=0, dataPtr=data; i<height; i++) 
00122      {
00123        for (j=0; j<width; j++) 
00124        {
00125          if (j%2)
00126          {
00127            rows[i][j/2] = ( rows[i][j/2] | *dataPtr );
00128          }
00129          else
00130          {
00131            rows[i][j/2] = (*dataPtr) << 4;
00132          }
00133          dataPtr++;
00134        }
00135      }
00136      png_set_rows(png_ptr,info_ptr,rows);
00137 
00138      file = fopen(name,"wb");
00139      if (file==0)
00140      {
00141        err("Error opening png file %s for writing: %s!\n",name,strerror(errno));
00142      }
00143      else
00144      {
00145        png_init_io(png_ptr,file);
00146        png_write_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,NULL);
00147      }
00148    }
00149 
00150    png_destroy_write_struct(&png_ptr, &info_ptr);
00151 
00152    if (file)
00153    {
00154       fclose (file);
00155    }
00156    if (cmap)
00157    {
00158       free(cmap);
00159    }
00160    if (rows) 
00161    {
00162       if (rows[0])
00163       {
00164          free(rows[0]);
00165       }
00166       free(rows);
00167    }
00168    return;
00169 }
00170 



Generated on Mon Mar 31 10:58:41 2008 by  doxygen 1.5.1