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

ReadImage.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_ReadImage_h
00002 #define Impala_Core_Array_ReadImage_h
00003 
00004 #include "Core/Array/Arrays.h"
00005 #include "Core/Array/ReadPng.h"
00006 #include "Core/Array/ReadJpg.h"
00007 
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Array
00013 {
00014 
00015 
00016 static const int cImageTypeUnknown = 0;
00017 static const int cImageTypeJpg     = 1;
00018 static const int cImageTypePng     = 2;
00019 
00020 
00025 inline int
00026 ReadImageIdentity(char* buf, int bufSize)
00027 {
00028     ILOG_VAR(Impala.Core.Array.ReadImageIdentity);
00029     if (bufSize < 14)
00030     {
00031         ILOG_ERROR("Buffer size too small (" << bufSize << ") to identify file");
00032         return cImageTypeUnknown;
00033     }
00034 
00035     // PNG image (first 8 bytes are always the same)
00036     if (((buf[0] == -119) || (buf[0] == 137)) &&  // 0x89 (signed stuff is...)
00037         (buf[1] == 0x50) &&
00038         (buf[2] == 0x4e) &&
00039         (buf[3] == 0x47) &&
00040         (buf[4] == 0x0d) &&
00041         (buf[5] == 0x0a) &&
00042         (buf[6] == 0x1a) &&
00043         (buf[7] == 0x0a))
00044     {
00045         return cImageTypePng;
00046     }
00047 
00048     // ordinary JFIF JPEG
00049     if ((buf[0] == -1) &&      // 0xff
00050         (buf[1] == -40) &&     // 0xd8
00051         (buf[2] == -1) &&      // 0xff application marker
00052         //(buf[3] == 0xe0) &&  // application marker
00053         //                     // (this part can be e0..ef or anything?)
00054         (buf[6] == 0x4a) &&    // J
00055         (buf[7] == 0x46) &&    // F
00056         (buf[8] == 0x49) &&    // I
00057         (buf[9] == 0x46) &&    // F
00058         (buf[10] == 0x00))
00059     {
00060         return cImageTypeJpg;
00061     }
00062 
00063     // Exif JPEG ...not tested...
00064     //is the "Exif" part required to be in this exact location?
00065     if ((buf[0] == -1) &&       // 0xff
00066         (buf[1] == -40) &&      // 0xd8
00067         (buf[2] == -1) &&       // 0xff application marker
00068         (buf[3] == -31) &&      // 0xe1 application marker
00069                                 // (this part has to be e1 for exif)
00070         (buf[8] == 0x45) &&     // E
00071         (buf[9] == 0x78) &&     // x
00072         (buf[10] == 0x69) &&    // i
00073         (buf[11] == 0x66) &&    // f
00074         (buf[12] == 0x00) &&    // \0
00075         (buf[13] == 0x00))      // \0
00076     {
00077         return cImageTypeJpg;
00078     }
00079     // Exif JPEG 2nd form: Exif 2 bytes back
00080     //is the "Exif" part required to be in this exact location?
00081     if ((buf[0] == -1) &&       // 0xff
00082         (buf[1] == -40) &&      // 0xd8
00083         (buf[2] == -1) &&       // 0xff application marker
00084         (buf[3] == -31) &&      // 0xe1 application marker
00085                                 // (this part has to be e1 for exif)
00086         (buf[6] == 0x45) &&     // E
00087         (buf[7] == 0x78) &&     // x
00088         (buf[8] == 0x69) &&     // i
00089         (buf[9] == 0x66) &&     // f
00090         (buf[10] == 0x00) &&    // \0
00091         (buf[11] == 0x00))      // \0
00092     {
00093         return cImageTypeJpg;
00094     }
00095 
00096 
00097     // Only these 3 bytes seem to be enough for JPEG?
00098     if ((buf[0] == -1) &&       // 0xff
00099         (buf[1] == -40) &&      // 0xd8
00100         (buf[2] == -1))       // 0xff application marker
00101     {
00102         return cImageTypeJpg;
00103     }
00104 
00105 
00106     ILOG_ERROR("Unknown image file format! 0:" << int(buf[0]) << " 1:" <<
00107                int(buf[1]) << " 2:" << int(buf[2]) << " 3:" << int(buf[3]) <<
00108                " 4:" << int(buf[4]) << " 5:" << int(buf[5]) << " 6:" <<
00109                int(buf[6]) << " 7:" << int(buf[7]) << " 8:" << int(buf[8]) <<
00110                " 9:" << int(buf[9]) << " 10:" << int(buf[10]) << " 11:" <<
00111                int(buf[11]) << " 12:" << int(buf[12]) << " 13:" << int(buf[13]));
00112 
00113     std::ostringstream oss;
00114     oss << "header:" << std::endl;
00115     for (int i=0 ; i<14 ; i++)
00116     {
00117         oss << "header[" << std::dec << i << "] = " << std::hex << "0x"
00118             << UInt8(buf[i]) << " = " << std::dec << int(buf[i]) << " = "
00119             << buf[i] << std::endl;
00120     }
00121     ILOG_INFO(oss.str());
00122 
00123     return cImageTypeUnknown;
00124 }
00125 template <class ArrayT>
00126 inline void
00127 ReadImageFromMemory(ArrayT*& dst, char* buf, int bufSize)
00128 {
00129     ILOG_VAR(Impala.Core.Array.ReadImageFromMemory);
00130     int imType = ReadImageIdentity(buf, bufSize);
00131 
00132     if (imType == cImageTypePng)
00133     {
00134         ReadPngFromMemory(dst, buf, bufSize);
00135         return;
00136     }
00137     if (imType == cImageTypeJpg)
00138     {
00139         ReadJpgFromMemory(dst, buf, bufSize);
00140         return;
00141     }
00142 }
00143 
00144 template <class ArrayT>
00145 inline void
00146 ReadImage(ArrayT*& dst, Persistency::File file)
00147 {
00148     ILOG_VAR(Impala.Core.Array.ReadImage);
00149     Util::IOBuffer* ioBuf = file.GetReadBuffer();
00150     if (!ioBuf)
00151         return;
00152 
00153     size_t bufSize = ioBuf->Size();
00154     char* buf = new char[bufSize];
00155     size_t nrRead = ioBuf->Read(buf, bufSize);
00156     if (nrRead != bufSize)
00157     {
00158         ILOG_ERROR("Buffer read failed");
00159         delete buf;
00160         delete ioBuf;
00161         return;
00162     }
00163 
00164     int imType = ReadImageIdentity(buf, bufSize);
00165     String nameExt = FileNameExt(file.GetPath(), true);
00166     if (imType == cImageTypePng)
00167     {
00168         if ((nameExt == "jpg") || (nameExt == "jpeg"))
00169             ILOG_WARN("File seems to contain a PNG instead of a JPG image");
00170         ReadPngFromMemory(dst, buf, bufSize);
00171     }
00172     else if (imType == cImageTypeJpg)
00173     {
00174         if (nameExt == "png")
00175             ILOG_WARN("File seems to contain a JPG instead of a PNG image");
00176         ReadJpgFromMemory(dst, buf, bufSize);
00177     }
00178     else
00179     {
00180         ILOG_ERROR("Don't understand " << file.GetPath());
00181     }
00182 
00183     delete buf;
00184     delete ioBuf;
00185 }
00186 
00187 } // namespace Array
00188 } // namespace Core
00189 } // namespace Impala
00190 
00191 #endif

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