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

ReadJpg.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_ReadJpg_h
00002 #define Impala_Core_Array_ReadJpg_h
00003 
00004 #include <string>
00005 #include "Basis/Timer.h"
00006 #include "Persistency/File.h"
00007 #include "Core/Array/Arrays.h"
00008 #ifdef JPG_USED
00009 #include "Link/Jpeg/CxJpegLink.h"
00010 #endif
00011 
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace Array
00017 {
00018 
00019 
00020 inline void
00021 ReadJpgFromMemory(Array2dScalarInt32*& dst, char *buf, int bufsize)
00022 {
00023     ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00024     ILOG_ERROR("ReadJpgFromMemory: array type not supported");
00025 }
00026 
00027 inline void
00028 ReadJpgFromMemory(Array2dScalarReal64*& dst, char *buf, int bufsize)
00029 {
00030     ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00031     ILOG_ERROR("ReadJpgFromMemory: array type not supported");
00032 }
00033 
00034 inline void
00035 ReadJpgFromMemory(Array2dVec3Real64*& dst, char *buf, int bufsize)
00036 {
00037     ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00038     ILOG_ERROR("ReadJpgFromMemory: array type not supported");
00039 }
00040 
00041 #ifdef JPG_USED
00042 
00043 static jmp_buf gReadJpgJmpbuf;
00044 static char gJpgErrorBuffer[JMSG_LENGTH_MAX];
00045 
00046 static inline void 
00047 JpgLinkErrorFunc(j_common_ptr cinfo)
00048 {
00049     /* Create the message */
00050     (*cinfo->err->format_message) (cinfo, gJpgErrorBuffer);
00051     longjmp(gReadJpgJmpbuf, 1);
00052 }
00053 
00054 String
00055 JpgColorSpace2String(J_COLOR_SPACE cSpace)
00056 {
00057     switch (cSpace)
00058     {
00059     case JCS_UNKNOWN: return "JCS_UNKNOWN";
00060     case JCS_GRAYSCALE: return "JCS_GRAYSCALE";
00061     case JCS_RGB: return "JCS_RGB";
00062     case JCS_YCbCr: return "JCS_YCbCr";
00063     case JCS_CMYK: return "JCS_CMYK";
00064     case JCS_YCCK: return "JCS_YCCK";
00065     }
00066     return "NO_JCS_VALUE";
00067 }
00068 
00069 template <class ArrayT>
00070 inline void
00071 ReadJpgFromMemory(ArrayT*& dst, char *buf, int bufsize)
00072 {
00073     ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00074     struct jpeg_decompress_struct cinfo;
00075     struct jpeg_error_mgr pub;
00076     cinfo.err = jpeg_std_error(&pub);
00077     pub.error_exit = JpgLinkErrorFunc;
00078     sprintf(gJpgErrorBuffer, "Something is wrong");
00079     if (setjmp(gReadJpgJmpbuf))
00080     {
00081         //ILOG_ERROR("jmp: " << String(gJpgErrorBuffer));
00082         ILOG_WARN("jmp: " << String(gJpgErrorBuffer));
00083         jpeg_destroy_decompress(&cinfo);
00084         return;
00085     }
00086     jpeg_create_decompress(&cinfo);
00087     jpeg_memory_src(&cinfo, (const JOCTET *)buf, bufsize);
00088     jpeg_read_header(&cinfo, TRUE);
00089 
00090     if (cinfo.num_components == 4)
00091         cinfo.out_color_space = JCS_CMYK;
00092     jpeg_calc_output_dimensions(&cinfo);
00093     jpeg_start_decompress(&cinfo);
00094 
00095     ILOG_DEBUG("color_space = " << JpgColorSpace2String(cinfo.jpeg_color_space));
00096     ILOG_DEBUG("MAXJSAMPLE = " << MAXJSAMPLE);
00097     ILOG_DEBUG("CENTERJSAMPLE = " << CENTERJSAMPLE);
00098 
00099     if ((cinfo.num_components == 4) && (!cinfo.saw_Adobe_marker))
00100         ILOG_WARN("Never tested non-inverted CMYK format");
00101 
00102     int width = cinfo.output_width;
00103     int height = cinfo.output_height;
00104     int row_stride = cinfo.output_width * cinfo.output_components;
00105     bool gray = (cinfo.output_components == 1) ? true : false;
00106     UInt8* c4Buf = (cinfo.output_components == 4) ? new UInt8[row_stride] : 0;
00107     if (dst == 0)
00108         dst = ArrayCreate<ArrayT>(width, height);
00109 
00110     while (cinfo.output_scanline < cinfo.output_height)
00111     {
00112         UInt8* dataPtr = dst->CPB(0, cinfo.output_scanline);
00113         UInt8* bufPtr = (c4Buf) ? c4Buf : dataPtr;
00114         int nrRead = jpeg_read_scanlines(&cinfo, &bufPtr, 1);
00115         if (nrRead != 1)
00116             ILOG_ERROR("jpeg_read_scanlines couldn't read line");
00117         if (c4Buf)
00118         {
00119             if (cinfo.saw_Adobe_marker)
00120             {
00121                 for (int i=0 ; i<width ; i++)
00122                 {
00123                     int k = 255 - bufPtr[3];
00124 
00125                     int val = bufPtr[0] - k;
00126                     dataPtr[0] = (val < 0) ? 0 : val;
00127                     val = bufPtr[1] - k;
00128                     dataPtr[1] = (val < 0) ? 0 : val;
00129                     val = bufPtr[2] - k;
00130                     dataPtr[2] = (val < 0) ? 0 : val;
00131 
00132                     dataPtr += 3;
00133                     bufPtr += 4;
00134                 }
00135             }
00136             else
00137             {
00138                 for (int i=0 ; i<width ; i++)
00139                 {
00140                     int k = 255 - bufPtr[3];
00141 
00142                     int val = k - bufPtr[0];
00143                     dataPtr[0] = (val < 0) ? 0 : val;
00144                     val = k - bufPtr[1];
00145                     dataPtr[1] = (val < 0) ? 0 : val;
00146                     val = k - bufPtr[2];
00147                     dataPtr[2] = (val < 0) ? 0 : val;
00148 
00149                     dataPtr += 3;
00150                     bufPtr += 4;
00151                 }
00152             }
00153         }
00154         if (gray)
00155         {
00156             UInt8* endLine = dataPtr + width * 3 - 1;
00157             UInt8* endData = dataPtr + width - 1;
00158             for (int i=0 ; i<width ; i++)
00159             {
00160                 *endLine-- = *endData;
00161                 *endLine-- = *endData;
00162                 *endLine-- = *endData--;
00163             }
00164         }
00165     }
00166     if (c4Buf)
00167         delete c4Buf;
00168     jpeg_finish_decompress(&cinfo);
00169     jpeg_destroy_decompress(&cinfo);
00170 }
00171 
00172 #else
00173 
00174 template <class ArrayT>
00175 inline void
00176 ReadJpgFromMemory(ArrayT*& dst, char *buf, int bufsize)
00177 {
00178     ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00179     ILOG_ERROR("ReadJpg is not available");
00180 }
00181 
00182 #endif // JPG_USED
00183 
00184 template <class ArrayT>
00185 inline void
00186 ReadJpg(ArrayT*& dst, Util::IOBuffer* buffer)
00187 {
00188     ILOG_VAR(Impala.Core.Array.ReadJpg);
00189     size_t memBufSize = buffer->Size();
00190     char* buf = new char[memBufSize];
00191     size_t nrRead = buffer->Read(buf, memBufSize);
00192     if (nrRead != memBufSize)
00193     {
00194         ILOG_ERROR("Buffer read failed");
00195         delete buf;
00196         return;
00197     }
00198     ReadJpgFromMemory(dst, buf, memBufSize);
00199     delete buf;
00200 }
00201 
00202 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00203 // TODO : not really a template function since ArrayT has to be UInt8 based.
00204 template <class ArrayT>
00205 inline void
00206 ReadJpg(ArrayT*& dst, String fileName, Util::Database* db)
00207 {
00208     Util::IOBuffer* buf = db->GetIOBuffer(fileName, true, false, "");
00209     if (buf)
00210     {
00211         ReadJpg(dst, buf);
00212         delete buf;
00213     }
00214 }
00215 #endif // REPOSITORY_USED
00216 
00217 // TODO : not really a template function since ArrayT has to be UInt8 based.
00218 template <class ArrayT>
00219 inline void
00220 ReadJpg(ArrayT*& dst, Persistency::File file)
00221 {
00222     Util::IOBuffer* buf = file.GetReadBuffer();
00223     if (buf)
00224     {
00225         ReadJpg(dst, buf);
00226         delete buf;
00227     }
00228 }
00229 
00230 } // namespace Array
00231 } // namespace Core
00232 } // namespace Impala
00233 
00234 #endif

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