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 #ifdef JPG_USED
00020 static jmp_buf gReadJpgJmpbuf;
00021
00022 static inline void
00023 JpgLinkErrorFunc(j_common_ptr cinfo)
00024 {
00025 (*cinfo->err->output_message) (cinfo);
00026 longjmp(gReadJpgJmpbuf, 1);
00027 }
00028 #endif
00029
00030 inline void
00031 ReadJpgFromMemory(Array2dScalarInt32*& dst, char *buf, int bufsize)
00032 {
00033 ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00034 ILOG_ERROR("ReadJpgFromMemory: array type not supported");
00035 }
00036
00037 inline void
00038 ReadJpgFromMemory(Array2dScalarReal64*& dst, char *buf, int bufsize)
00039 {
00040 ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00041 ILOG_ERROR("ReadJpgFromMemory: array type not supported");
00042 }
00043
00044 inline void
00045 ReadJpgFromMemory(Array2dVec3Real64*& dst, char *buf, int bufsize)
00046 {
00047 ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00048 ILOG_ERROR("ReadJpgFromMemory: array type not supported");
00049 }
00050
00051 #ifdef JPG_USED
00052 template <class ArrayT>
00053 inline void
00054 ReadJpgFromMemory(ArrayT*& dst, char *buf, int bufsize)
00055 {
00056 ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00057 struct jpeg_decompress_struct cinfo;
00058 struct jpeg_error_mgr pub;
00059 cinfo.err = jpeg_std_error(&pub);
00060 pub.error_exit = JpgLinkErrorFunc;
00061 if (setjmp(gReadJpgJmpbuf))
00062 {
00063 ILOG_ERROR("setjmp");
00064 jpeg_destroy_decompress(&cinfo);
00065 return;
00066 }
00067 jpeg_create_decompress(&cinfo);
00068 jpeg_memory_src(&cinfo, (const JOCTET *)buf, bufsize);
00069 jpeg_read_header(&cinfo, TRUE);
00070 jpeg_start_decompress(&cinfo);
00071
00072 if (cinfo.output_components == 4)
00073 {
00074 ILOG_ERROR("CMYK images not supported");
00075 jpeg_abort_decompress(&cinfo);
00076 jpeg_destroy_decompress(&cinfo);
00077 return;
00078 }
00079
00080 int width = cinfo.output_width;
00081 int height = cinfo.output_height;
00082 int row_stride = cinfo.output_width * cinfo.output_components;
00083 JSAMPARRAY jpgdata =
00084 (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE,
00085 row_stride, 1);
00086
00087 bool gray = (cinfo.output_components == 1) ? true : false;
00088 if (dst == 0)
00089 dst = ArrayCreate<ArrayT>(width, height);
00090
00091 UInt8* dataPtr;
00092 while (cinfo.output_scanline < cinfo.output_height)
00093 {
00094 dataPtr = dst->CPB(0, cinfo.output_scanline);
00095 int nrRead = jpeg_read_scanlines(&cinfo, &dataPtr, 1);
00096 if (nrRead != 1)
00097 ILOG_ERROR("jpeg_read_scanlines couldn't read line");
00098 if (gray)
00099 {
00100 UInt8* endLine = dataPtr + width * 3 - 1;
00101 UInt8* endData = dataPtr + width - 1;
00102 for (int i=0 ; i<width ; i++)
00103 {
00104 *endLine-- = *endData;
00105 *endLine-- = *endData;
00106 *endLine-- = *endData--;
00107 }
00108 }
00109 }
00110
00111 jpeg_finish_decompress(&cinfo);
00112 jpeg_destroy_decompress(&cinfo);
00113 }
00114
00115 #else
00116
00117 template <class ArrayT>
00118 inline void
00119 ReadJpgFromMemory(ArrayT*& dst, char *buf, int bufsize)
00120 {
00121 ILOG_VAR(Impala.Core.Array.ReadJpgFromMemory);
00122 ILOG_ERROR("ReadJpg is not available");
00123 }
00124
00125 #endif // JPG_USED
00126
00127 template <class ArrayT>
00128 inline void
00129 ReadJpg(ArrayT*& dst, Util::IOBuffer* buffer, int memBufSize = 10000000)
00130 {
00131 ILOG_VAR(Impala.Core.Array.ReadJpg);
00132 char* buf = new char[memBufSize];
00133 size_t nrRead = buffer->Read(buf, memBufSize);
00134 if (nrRead >= memBufSize)
00135 {
00136 ILOG_ERROR("Buffer to small");
00137 delete buf;
00138 return;
00139 }
00140 ReadJpgFromMemory(dst, buf, memBufSize);
00141 delete buf;
00142 }
00143
00144 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00145
00146 template <class ArrayT>
00147 inline void
00148 ReadJpg(ArrayT*& dst, String fileName, Util::Database* db,
00149 int memBufSize = 10000000)
00150 {
00151 Util::IOBuffer* buf = db->GetIOBuffer(fileName, true, false, "");
00152 if (buf)
00153 {
00154 ReadJpg(dst, buf, memBufSize);
00155 delete buf;
00156 }
00157 }
00158 #endif // REPOSITORY_USED
00159
00160
00161 template <class ArrayT>
00162 inline void
00163 ReadJpg(ArrayT*& dst, Persistency::File file, int memBufSize = 10000000)
00164 {
00165 Util::IOBuffer* buf = file.GetReadBuffer();
00166 if (buf)
00167 {
00168 ReadJpg(dst, buf, memBufSize);
00169 delete buf;
00170 }
00171 }
00172
00173 }
00174 }
00175 }
00176
00177 #endif