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

Generated on Fri Mar 19 09:31:03 2010 for ImpalaSrc by  doxygen 1.5.1