Home || Visual Search || Applications || Architecture || Important Messages || OGL || Src

WritePng.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_WritePng_h
00002 #define Impala_Core_Array_WritePng_h
00003 
00004 #include "Core/Array/Arrays.h"
00005 #include "Core/Array/MakeFromData.h"
00006 #include "Persistency/File.h"
00007 
00008 #ifdef PNG_USED
00009 #include "Link/Png/CxPngLink.h"
00010 #endif
00011 
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Array
00017 {
00018 
00019 
00020 #ifdef PNG_USED
00021 static jmp_buf gWritePngJmpbuf;
00022 
00023 static inline void 
00024 errorFuncWritePng(png_structp png_ptr, png_const_charp msg)
00025 {
00026     ILOG_VAR(Impala.Core.Array.WritePng);
00027     ILOG_ERROR("PNG Error: " << msg);    
00028     //longjmp(png_ptr->jmpbuf, 1);
00029     longjmp(gWritePngJmpbuf, 1);
00030 }
00031 
00032 static inline void 
00033 warnFuncWritePng(png_structp png_ptr, png_const_charp msg)
00034 {
00035     ILOG_VAR(Impala.Core.Array.WritePng);
00036     ILOG_WARN("PNG Warning: " << msg);
00037 }
00038 
00039 static inline void
00040 WritePngDataFunc(png_structp png_ptr, png_bytep data, png_size_t length)
00041 {
00042     char* buf = (char*) png_ptr->io_ptr;
00043     memcpy(png_ptr->io_ptr, data, length);
00044     buf += length;
00045     png_ptr->io_ptr = buf;
00046 }
00047 
00048 static inline void
00049 FlushPngDataFunc(png_structp png_ptr)
00050 {
00051 }
00052 
00053 
00054 template <class ArrayT>
00055 inline bool
00056 WritePngToMemory(ArrayT* src, char* buf, size_t memBufSize, size_t* outSize)
00057 {
00058     ILOG_VAR(Impala.Core.Array.WritePngToMemory);
00059     png_structp png;
00060     png_infop   pngInfo;
00061     png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
00062                                   errorFuncWritePng, warnFuncWritePng);
00063     if (!png)
00064     {
00065         ILOG_ERROR("png_create_write_struct error");
00066         return false;
00067     }
00068 
00069     pngInfo = png_create_info_struct(png);
00070     if (!pngInfo)
00071     {
00072         ILOG_ERROR("png_create_info_struct error");
00073         png_destroy_write_struct(&png, NULL);
00074         return false;
00075     }
00076 
00077     if (setjmp(gWritePngJmpbuf))
00078     {
00079         ILOG_ERROR("setjmp");
00080         png_destroy_write_struct(&png, &pngInfo);
00081         return false;
00082     }
00083 
00084     png_set_write_fn(png, buf, WritePngDataFunc, FlushPngDataFunc);
00085     png->io_ptr = buf; // This should have been done by png_set_write_fn ?!?
00086 
00087     int colorType;
00088     if (ArrayT::ElemSize() == 1)
00089         colorType = PNG_COLOR_TYPE_GRAY;
00090     else
00091         colorType = PNG_COLOR_TYPE_RGB;
00092     int bitDepth = 8;
00093     png_uint_32 width = src->CW();
00094     png_uint_32 height = src->CH();
00095 
00096     png_set_IHDR(png, pngInfo, width, height, bitDepth, colorType,
00097                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
00098                  PNG_FILTER_TYPE_BASE);
00099     png_write_info(png, pngInfo);
00100 
00101     for (int row=0 ; row<src->CH() ; row++)
00102     {
00103         UInt8* dataPtr = src->CPB(0, row);
00104         //if (setjmp(png->jmpbuf)) {
00105         if (setjmp(gWritePngJmpbuf))
00106         {
00107             ILOG_ERROR("Error writing png data");
00108             return false;
00109         }
00110         png_write_row(png, dataPtr);
00111     }
00112     png_write_end(png, pngInfo);
00113     char* endBuf = (char*) png->io_ptr;
00114     *outSize = (endBuf - buf);
00115     png_destroy_write_struct(&png, &pngInfo);
00116     return true;
00117 }
00118 
00119 #else
00120 
00121 template <class ArrayT>
00122 inline bool
00123 WritePngToMemory(ArrayT* src, char* buf, size_t memBufSize, size_t* outSize)
00124 {
00125     ILOG_VAR(Impala.Core.Array.WritePngToMemory);
00126     ILOG_ERROR("WritePng not available.");
00127     return false;
00128 }
00129 
00130 #endif // PNG_USED
00131 
00132 template <class ArrayT>
00133 inline Array2dScalarUInt8*
00134 WritePng(ArrayT* src)
00135 {
00136     Array2dScalarUInt8* res = 0;
00137     size_t bufSize = src->CW() * src->CH() * 3 + 1024;
00138     char* buf = new char[bufSize];
00139     size_t outSize;
00140     if (!WritePngToMemory(src, buf, bufSize, &outSize))
00141     {
00142         delete buf;
00143         return res;
00144     }
00145     res = MakeFromData<Array2dScalarUInt8>((UInt8*) buf, bufSize, 1);
00146     delete buf;
00147     return res;
00148 }
00149 
00150 template <class ArrayT>
00151 inline bool
00152 WritePng(ArrayT* src, Util::IOBuffer* buffer)
00153 {
00154     size_t memBufSize = src->CW() * src->CH() * 3 + 1024;
00155     char* buf = new char[memBufSize];
00156     size_t outSize;
00157     if (!WritePngToMemory(src, buf, memBufSize, &outSize))
00158     {
00159         delete buf;
00160         return false;
00161     }
00162     buffer->Write(buf, outSize);
00163     delete buf;
00164     return true;
00165 }
00166 
00167 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00168 template <class ArrayT>
00169 inline bool
00170 WritePng(ArrayT* src, String fileName, Util::Database* db)
00171 {
00172     Util::IOBuffer* buf = db->GetIOBuffer(fileName, false, false, "tmp");
00173     if (!buf)
00174         return false;
00175     bool res = WritePng(src, buf);
00176     delete buf;
00177     return res;
00178 }
00179 #endif // REPOSITORY_USED
00180 
00181 // TODO : not really a template function since ArrayT has to be UInt8 based.
00182 // Handles Vec3UInt8 images only
00183 template <class ArrayT>
00184 inline bool
00185 WritePng(ArrayT* src, Persistency::File file)
00186 {
00187     Util::IOBuffer* buf = file.GetWriteBuffer();
00188     if (!buf)
00189         return false;
00190     bool res = WritePng(src, buf);
00191     delete buf;
00192     return res;
00193 }
00194 
00195 } // namespace Array
00196 } // namespace Core
00197 } // namespace Impala
00198 
00199 #endif

Generated on Thu Jan 13 09:04:21 2011 for ImpalaSrc by  doxygen 1.5.1