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
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;
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
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
00163
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 }
00177 }
00178 }
00179
00180 #endif