add functions to load&scale pictures and to get exif information
authorFelix Domke <tmbinc@elitedvb.net>
Sat, 18 Nov 2006 13:14:57 +0000 (13:14 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Sat, 18 Nov 2006 13:14:57 +0000 (13:14 +0000)
lib/gdi/Makefile.am
lib/gdi/picexif.cpp [new file with mode: 0644]
lib/gdi/picexif.h [new file with mode: 0644]
lib/gdi/picload.cpp [new file with mode: 0644]
lib/gdi/picload.h [new file with mode: 0644]
lib/python/enigma_python.i

index d5f7d97..ff688af 100644 (file)
@@ -5,7 +5,7 @@ noinst_LIBRARIES = libenigma_gdi.a
 
 libenigma_gdi_a_SOURCES = \
        region.cpp grc.cpp epng.cpp erect.cpp fb.cpp font.cpp font_arabic.cpp gfbdc.cpp  \
-       glcddc.cpp gpixmap.cpp lcd.cpp gfont.cpp accel.cpp 
+       glcddc.cpp gpixmap.cpp lcd.cpp gfont.cpp accel.cpp picload.cpp picexif.cpp
 
 
 #      ati/2dablt.cpp ati/2dcore.cpp ati/ati_core.cpp ati/test.cpp ati/2dutil.cpp
diff --git a/lib/gdi/picexif.cpp b/lib/gdi/picexif.cpp
new file mode 100644 (file)
index 0000000..844673c
--- /dev/null
@@ -0,0 +1,630 @@
+#include "picexif.h"
+
+#define M_SOF0  0xC0
+#define M_SOF1  0xC1
+#define M_SOF2  0xC2
+#define M_SOF3  0xC3
+#define M_SOF5  0xC5
+#define M_SOF6  0xC6
+#define M_SOF7  0xC7
+#define M_SOF9  0xC9
+#define M_SOF10 0xCA
+#define M_SOF11 0xCB
+#define M_SOF13 0xCD
+#define M_SOF14 0xCE
+#define M_SOF15 0xCF
+#define M_SOI   0xD8
+#define M_EOI   0xD9
+#define M_SOS   0xDA
+#define M_JFIF  0xE0
+#define M_EXIF  0xE1
+#define M_COM   0xFE
+
+#define NUM_FORMATS   12
+#define FMT_BYTE       1
+#define FMT_STRING     2
+#define FMT_USHORT     3
+#define FMT_ULONG      4
+#define FMT_URATIONAL  5
+#define FMT_SBYTE      6
+#define FMT_UNDEFINED  7
+#define FMT_SSHORT     8
+#define FMT_SLONG      9
+#define FMT_SRATIONAL 10
+#define FMT_SINGLE    11
+#define FMT_DOUBLE    12
+
+#define TAG_EXIF_VERSION      0x9000
+#define TAG_EXIF_OFFSET       0x8769
+#define TAG_INTEROP_OFFSET    0xa005
+#define TAG_MAKE              0x010F
+#define TAG_MODEL             0x0110
+#define TAG_ORIENTATION       0x0112
+#define TAG_XRESOLUTION       0x011A
+#define TAG_YRESOLUTION       0x011B
+#define TAG_RESOLUTIONUNIT    0x0128
+#define TAG_EXPOSURETIME      0x829A
+#define TAG_FNUMBER           0x829D
+#define TAG_SHUTTERSPEED      0x9201
+#define TAG_APERTURE          0x9202
+#define TAG_BRIGHTNESS        0x9203
+#define TAG_MAXAPERTURE       0x9205
+#define TAG_FOCALLENGTH       0x920A
+#define TAG_DATETIME_ORIGINAL 0x9003
+#define TAG_USERCOMMENT       0x9286
+#define TAG_SUBJECT_DISTANCE  0x9206
+#define TAG_FLASH             0x9209
+#define TAG_FOCALPLANEXRES    0xa20E
+#define TAG_FOCALPLANEYRES    0xa20F
+#define TAG_FOCALPLANEUNITS   0xa210
+#define TAG_EXIF_IMAGEWIDTH   0xA002
+#define TAG_EXIF_IMAGELENGTH  0xA003
+#define TAG_EXPOSURE_BIAS     0x9204
+#define TAG_WHITEBALANCE      0x9208
+#define TAG_METERING_MODE     0x9207
+#define TAG_EXPOSURE_PROGRAM  0x8822
+#define TAG_ISO_EQUIVALENT    0x8827
+#define TAG_COMPRESSION_LEVEL 0x9102
+#define TAG_THUMBNAIL_OFFSET  0x0201
+#define TAG_THUMBNAIL_LENGTH  0x0202
+
+
+Cexif::Cexif()
+{
+}
+
+Cexif::~Cexif()
+{
+       //ClearExif();
+}
+
+void Cexif::ClearExif()
+{
+       if(freeinfo)
+       {
+               for(int i=0;i<MAX_SECTIONS;i++)
+                       if(Sections[i].Data) free(Sections[i].Data);
+                               delete m_exifinfo;
+               freeinfo = false;
+       }
+}
+
+bool Cexif::DecodeExif(const char *filename)
+{
+       FILE * hFile = fopen(filename, "r");
+       if(!hFile) return false;
+
+
+       m_exifinfo = new EXIFINFO;
+       memset(m_exifinfo,0,sizeof(EXIFINFO));
+       freeinfo = true;
+
+       m_szLastError[0]='\0';
+       ExifImageWidth = MotorolaOrder = SectionsRead=0;
+       memset(&Sections, 0, MAX_SECTIONS * sizeof(Section_t));
+
+       int HaveCom = 0;
+       int a = fgetc(hFile);
+       strcpy(m_szLastError,"EXIF-Data not found");
+
+       if (a != 0xff || fgetc(hFile) != M_SOI) return false;
+
+       for(;;)
+       {
+               int marker = 0;
+               int ll,lh, got, itemlen;
+               unsigned char * Data;
+
+               if (SectionsRead >= MAX_SECTIONS)
+               {
+                       strcpy(m_szLastError,"Too many sections in jpg file"); return false;
+               }
+
+               for (a=0;a<7;a++)
+               {
+                       marker = fgetc(hFile);
+                       if (marker != 0xff) break;
+
+                       if (a >= 6)
+                       {
+                               strcpy(m_szLastError,"too many padding unsigned chars\n"); return false;
+                       }
+               }
+
+               if (marker == 0xff)
+               {
+                       strcpy(m_szLastError,"too many padding unsigned chars!"); return false;
+               }
+
+               Sections[SectionsRead].Type = marker;
+
+               lh = fgetc(hFile);
+               ll = fgetc(hFile);
+
+               itemlen = (lh << 8) | ll;
+
+               if (itemlen < 2)
+               {
+                       strcpy(m_szLastError,"invalid marker"); return false;
+               }
+               Sections[SectionsRead].Size = itemlen;
+
+               Data = (unsigned char *)malloc(itemlen);
+               if (Data == NULL)
+               {
+                       strcpy(m_szLastError,"Could not allocate memory"); return false;
+               }
+               Sections[SectionsRead].Data = Data;
+
+
+               Data[0] = (unsigned char)lh;
+               Data[1] = (unsigned char)ll;
+
+               got = fread(Data+2, 1, itemlen-2,hFile);
+               if (got != itemlen-2)
+               {
+                       strcpy(m_szLastError,"Premature end of file?"); return false;
+               }
+               SectionsRead += 1;
+
+               switch(marker)
+               {
+               case M_SOS:
+                       return true;
+               case M_EOI:
+                       printf("No image in jpeg!\n");
+                       return false;
+               case M_COM:
+                       if (HaveCom)
+                       {
+                               free(Sections[--SectionsRead].Data);
+                               Sections[SectionsRead].Data=0;
+                       }
+                       else
+                       {
+                               process_COM(Data, itemlen);
+                               HaveCom = 1;
+                       }
+                       break;
+               case M_JFIF:
+                       free(Sections[--SectionsRead].Data);
+                       Sections[SectionsRead].Data=0;
+                       break;
+               case M_EXIF:
+                       if (memcmp(Data+2, "Exif", 4) == 0)
+                       {
+                               m_exifinfo->IsExif = process_EXIF((unsigned char *)Data+2, itemlen);
+                       }
+                       else
+                       {
+                               free(Sections[--SectionsRead].Data);
+                               Sections[SectionsRead].Data=0;
+                       }
+                       break;
+               case M_SOF0:
+               case M_SOF1:
+               case M_SOF2:
+               case M_SOF3:
+               case M_SOF5:
+               case M_SOF6:
+               case M_SOF7:
+               case M_SOF9:
+               case M_SOF10:
+               case M_SOF11:
+               case M_SOF13:
+               case M_SOF14:
+               case M_SOF15:
+                       process_SOFn(Data, marker);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       fclose(hFile);
+       return true;
+}
+
+bool Cexif::process_EXIF(unsigned char * CharBuf, unsigned int length)
+{
+       m_exifinfo->Comments[0] = '\0';
+       ExifImageWidth = 0;
+
+       static const unsigned char ExifHeader[] = "Exif\0\0";
+       if(memcmp(CharBuf+0, ExifHeader,6))
+       {
+               strcpy(m_szLastError,"Incorrect Exif header"); return false;
+       }
+
+       if (memcmp(CharBuf+6,"II",2) == 0) MotorolaOrder = 0;
+       else
+       {
+               if (memcmp(CharBuf+6,"MM",2) == 0) MotorolaOrder = 1;
+               else
+               {
+                       strcpy(m_szLastError,"Invalid Exif alignment marker."); return false;
+               }
+       }
+
+       if (Get16u(CharBuf+8) != 0x2a)
+       {
+               strcpy(m_szLastError,"Invalid Exif start (1)"); return false;
+       }
+       int FirstOffset = Get32u(CharBuf+10);
+       if (FirstOffset < 8 || FirstOffset > 16)
+       {
+               strcpy(m_szLastError,"Suspicious offset of first IFD value"); return 0;
+       }
+       unsigned char * LastExifRefd = CharBuf;
+
+       if (!ProcessExifDir(CharBuf+14, CharBuf+6, length-6, m_exifinfo, &LastExifRefd)) return false;
+
+       if (m_exifinfo->FocalplaneXRes != 0)
+               m_exifinfo->CCDWidth = (float)(ExifImageWidth * m_exifinfo->FocalplaneUnits / m_exifinfo->FocalplaneXRes);
+
+       return true;
+}
+
+int Cexif::Get16m(void * Short)
+{
+       return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
+}
+
+int Cexif::Get16u(void * Short)
+{
+       if (MotorolaOrder)
+       {
+               return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
+       }
+       else
+       {
+               return (((unsigned char *)Short)[1] << 8) | ((unsigned char *)Short)[0];
+       }
+}
+
+long Cexif::Get32s(void * Long)
+{
+       if (MotorolaOrder)
+       {
+               return  ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16) | (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 );
+       }
+       else
+       {
+               return  ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16) | (((unsigned char *)Long)[1] << 8 ) | (((unsigned char *)Long)[0] << 0 );
+       }
+}
+
+unsigned long Cexif::Get32u(void * Long)
+{
+       return (unsigned long)Get32s(Long) & 0xffffffff;
+}
+
+bool Cexif::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, EXIFINFO * const m_exifinfo, unsigned char ** const LastExifRefdP )
+{
+       int de, a, NumDirEntries;
+       unsigned ThumbnailOffset = 0;
+       unsigned ThumbnailSize = 0;
+
+       NumDirEntries = Get16u(DirStart);
+
+       if ((DirStart+2+NumDirEntries*12) > (OffsetBase+ExifLength))
+       {
+               strcpy(m_szLastError,"Illegally sized directory"); return 0;
+       }
+
+       for (de=0;de<NumDirEntries;de++)
+       {
+               int Tag, Format, Components;
+               unsigned char * ValuePtr;
+               int BytesCount;
+               unsigned char * DirEntry;
+               DirEntry = DirStart+2+12*de;
+               Tag = Get16u(DirEntry);
+               Format = Get16u(DirEntry+2);
+               Components = Get32u(DirEntry+4);
+
+               if ((Format-1) >= NUM_FORMATS)
+               {
+                       strcpy(m_szLastError,"Illegal format code in EXIF dir"); return 0;
+               }
+
+               BytesCount = Components * BytesPerFormat[Format];
+
+               if (BytesCount > 4)
+               {
+                       unsigned OffsetVal;
+                       OffsetVal = Get32u(DirEntry+8);
+                       if (OffsetVal+BytesCount > ExifLength)
+                       {
+                               strcpy(m_szLastError,"Illegal pointer offset value in EXIF."); return 0;
+                       }
+                       ValuePtr = OffsetBase+OffsetVal;
+               }
+               else ValuePtr = DirEntry+8;
+
+               if (*LastExifRefdP < ValuePtr+BytesCount) *LastExifRefdP = ValuePtr+BytesCount;
+
+               switch(Tag)
+               {
+               case TAG_MAKE:
+                       strncpy(m_exifinfo->CameraMake, (char*)ValuePtr, 31);
+                       break;
+               case TAG_MODEL:
+                       strncpy(m_exifinfo->CameraModel, (char*)ValuePtr, 39);
+                       break;
+               case TAG_EXIF_VERSION:
+                       strncpy(m_exifinfo->Version,(char*)ValuePtr, 4);
+                       break;
+               case TAG_DATETIME_ORIGINAL:
+                       strncpy(m_exifinfo->DateTime, (char*)ValuePtr, 19);
+                       break;
+               case TAG_USERCOMMENT:
+                       for (a=BytesCount;;)
+                       {
+                               a--;
+                               if (((char*)ValuePtr)[a] == ' ') ((char*)ValuePtr)[a] = '\0';
+                               else break;
+
+                               if (a == 0) break;
+                       }
+
+                       if (memcmp(ValuePtr, "ASCII",5) == 0)
+                       {
+                               for (a=5;a<10;a++)
+                               {
+                                       char c;
+                                       c = ((char*)ValuePtr)[a];
+                                       if (c != '\0' && c != ' ')
+                                       {
+                                               strncpy(m_exifinfo->Comments, (char*)ValuePtr+a, 199);
+                                               break;
+                                       }
+                               }
+
+                       }
+                       else strncpy(m_exifinfo->Comments, (char*)ValuePtr, 199);
+                       break;
+               case TAG_FNUMBER:
+                       m_exifinfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_APERTURE:
+               case TAG_MAXAPERTURE:
+                       if (m_exifinfo->ApertureFNumber == 0)
+                       {
+                               //m_exifinfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2)*0.5);
+                       }
+                       break;
+               case TAG_BRIGHTNESS:
+                       m_exifinfo->Brightness = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_FOCALLENGTH:
+                       m_exifinfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_SUBJECT_DISTANCE:
+                       m_exifinfo->Distance = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_EXPOSURETIME:
+                       m_exifinfo->ExposureTime = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_SHUTTERSPEED:
+                       if (m_exifinfo->ExposureTime == 0)
+                       {
+                               //m_exifinfo->ExposureTime = (float) (1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2)));
+                       }
+                       break;
+               case TAG_FLASH:
+                       if ((int)ConvertAnyFormat(ValuePtr, Format) & 7) strcpy(m_exifinfo->FlashUsed,"fire");
+                       else strcpy(m_exifinfo->FlashUsed,"not fired");
+                       break;
+               case TAG_ORIENTATION:
+                       m_exifinfo->Orient = (int)ConvertAnyFormat(ValuePtr, Format);
+                       switch((int)ConvertAnyFormat(ValuePtr, Format))
+                       {
+                       case 1:         strcpy(m_exifinfo->Orientation,"Top-Left"); break;
+                       case 2:         strcpy(m_exifinfo->Orientation,"Top-Right"); break;
+                       case 3:         strcpy(m_exifinfo->Orientation,"Bottom-Right"); break;
+                       case 4:         strcpy(m_exifinfo->Orientation,"Bottom-Left"); break;
+                       case 5:         strcpy(m_exifinfo->Orientation,"Left-Top"); break;
+                       case 6:         strcpy(m_exifinfo->Orientation,"Right-Top"); break;
+                       case 7:         strcpy(m_exifinfo->Orientation,"Right-Bottom"); break;
+                       case 8:         strcpy(m_exifinfo->Orientation,"Left-Bottom"); break;
+                       default:        strcpy(m_exifinfo->Orientation,"Undefined rotation value");
+                       }
+                       break;
+               case TAG_EXIF_IMAGELENGTH:
+               case TAG_EXIF_IMAGEWIDTH:
+                       a = (int)ConvertAnyFormat(ValuePtr, Format);
+                       if (ExifImageWidth < a) ExifImageWidth = a;
+                       break;
+               case TAG_FOCALPLANEXRES:
+                       m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_FOCALPLANEYRES:
+                       m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_RESOLUTIONUNIT:
+                       switch((int)ConvertAnyFormat(ValuePtr, Format))
+                       {
+                               case 2: strcpy(m_exifinfo->ResolutionUnit,"inches"); break;
+                               case 3: strcpy(m_exifinfo->ResolutionUnit,"centimeters"); break;
+                               default: strcpy(m_exifinfo->ResolutionUnit,"reserved");
+                       }
+                       break;
+               case TAG_FOCALPLANEUNITS:
+                       switch((int)ConvertAnyFormat(ValuePtr, Format))
+                       {
+                               case 1: m_exifinfo->FocalplaneUnits = 1.0f; break;
+                               case 2: m_exifinfo->FocalplaneUnits = 1.0f; break;
+                               case 3: m_exifinfo->FocalplaneUnits = 0.3937007874f; break;
+                               case 4: m_exifinfo->FocalplaneUnits = 0.03937007874f; break;
+                               case 5: m_exifinfo->FocalplaneUnits = 0.00003937007874f;
+                       }
+                       break;
+               case TAG_EXPOSURE_BIAS:
+                       m_exifinfo->ExposureBias = (float) ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_WHITEBALANCE:
+                       switch((int)ConvertAnyFormat(ValuePtr, Format))
+                       {
+                               case 0: strcpy(m_exifinfo->LightSource,"unknown"); break;
+                               case 1: strcpy(m_exifinfo->LightSource,"Daylight"); break;
+                               case 2: strcpy(m_exifinfo->LightSource,"Fluorescent"); break;
+                               case 3: strcpy(m_exifinfo->LightSource,"Tungsten"); break;
+                               case 17: strcpy(m_exifinfo->LightSource,"Standard light A"); break;
+                               case 18: strcpy(m_exifinfo->LightSource,"Standard light B"); break;
+                               case 19: strcpy(m_exifinfo->LightSource,"Standard light C"); break;
+                               case 20: strcpy(m_exifinfo->LightSource,"D55"); break;
+                               case 21: strcpy(m_exifinfo->LightSource,"D65"); break;
+                               case 22: strcpy(m_exifinfo->LightSource,"D75"); break;
+                               default: strcpy(m_exifinfo->LightSource,"other"); break;
+                       }
+                       break;
+               case TAG_METERING_MODE:
+                       switch((int)ConvertAnyFormat(ValuePtr, Format))
+                       {
+                               case 0: strcpy(m_exifinfo->MeteringMode,"unknown"); break;
+                               case 1: strcpy(m_exifinfo->MeteringMode,"Average"); break;
+                               case 2: strcpy(m_exifinfo->MeteringMode,"Center-Weighted-Average"); break;
+                               case 3: strcpy(m_exifinfo->MeteringMode,"Spot"); break;
+                               case 4: strcpy(m_exifinfo->MeteringMode,"MultiSpot"); break;
+                               case 5: strcpy(m_exifinfo->MeteringMode,"Pattern"); break;
+                               case 6: strcpy(m_exifinfo->MeteringMode,"Partial"); break;
+                               default: strcpy(m_exifinfo->MeteringMode,"other"); break;
+                       }
+                       break;
+               case TAG_EXPOSURE_PROGRAM:
+                       switch((int)ConvertAnyFormat(ValuePtr, Format))
+                       {
+                               case 0: strcpy(m_exifinfo->ExposureProgram,"not defined"); break;
+                               case 1: strcpy(m_exifinfo->ExposureProgram,"Manual"); break;
+                               case 2: strcpy(m_exifinfo->ExposureProgram,"Normal program"); break;
+                               case 3: strcpy(m_exifinfo->ExposureProgram,"Aperture priority"); break;
+                               case 4: strcpy(m_exifinfo->ExposureProgram,"Shutter priority"); break;
+                               case 5: strcpy(m_exifinfo->ExposureProgram,"Creative program"); break;
+                               case 6: strcpy(m_exifinfo->ExposureProgram,"Action program"); break;
+                               case 7: strcpy(m_exifinfo->ExposureProgram,"Portrait mode"); break;
+                               case 8: strcpy(m_exifinfo->ExposureProgram,"Landscape mode"); break;
+                               default: strcpy(m_exifinfo->ExposureProgram,"reserved"); break;
+                       }
+                       break;
+               case TAG_ISO_EQUIVALENT:
+                       m_exifinfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
+                       if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
+                       break;
+               case TAG_COMPRESSION_LEVEL:
+                       m_exifinfo->CompressionLevel = (int)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_XRESOLUTION:
+                       m_exifinfo->Xresolution = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_YRESOLUTION:
+                       m_exifinfo->Yresolution = (float)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_THUMBNAIL_OFFSET:
+                       ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               case TAG_THUMBNAIL_LENGTH:
+                       ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format);
+                       break;
+               }
+
+               if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET)
+               {
+                       unsigned char * SubdirStart;
+                       SubdirStart = OffsetBase + Get32u(ValuePtr);
+                       if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength)
+                       {
+                               strcpy(m_szLastError,"Illegal subdirectory link"); return 0;
+                       }
+                       ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP);
+                       continue;
+               }
+       }
+
+
+       unsigned char * SubdirStart;
+       unsigned Offset;
+       Offset = Get16u(DirStart+2+12*NumDirEntries);
+       if (Offset)
+       {
+               SubdirStart = OffsetBase + Offset;
+               if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength)
+               {
+                       strcpy(m_szLastError,"Illegal subdirectory link"); return 0;
+               }
+               ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP);
+        }
+
+       if (ThumbnailSize && ThumbnailOffset)
+       {
+               if (ThumbnailSize + ThumbnailOffset <= ExifLength)
+               {
+                       m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset;
+                       m_exifinfo->ThumbnailSize = ThumbnailSize;
+               }
+       }
+
+       return 1;
+}
+
+double Cexif::ConvertAnyFormat(void * ValuePtr, int Format)
+{
+       double Value = 0;
+
+       switch(Format)
+       {
+               case FMT_SBYTE:         Value = *(signed char *)ValuePtr;       break;
+               case FMT_BYTE:          Value = *(unsigned char *)ValuePtr;     break;
+               case FMT_USHORT:        Value = Get16u(ValuePtr);               break;
+               case FMT_ULONG:         Value = Get32u(ValuePtr);               break;
+               case FMT_URATIONAL:
+               case FMT_SRATIONAL:
+               {
+                       int Num = Get32s(ValuePtr);
+                       int Den = Get32s(4+(char *)ValuePtr);
+                       if (Den == 0) Value = 0;
+                       else Value = (double)Num/Den;
+                       break;
+               }
+               case FMT_SSHORT:        Value = (signed short)Get16u(ValuePtr); break;
+               case FMT_SLONG:         Value = Get32s(ValuePtr);               break;
+               case FMT_SINGLE:        Value = (double)*(float *)ValuePtr;     break;
+               case FMT_DOUBLE:        Value = *(double *)ValuePtr;            break;
+       }
+       return Value;
+}
+
+void Cexif::process_COM (const unsigned char * Data, int length)
+{
+       int ch,a;
+       char Comment[MAX_COMMENT+1];
+       int nch=0;
+
+       if (length > MAX_COMMENT) length = MAX_COMMENT;
+
+       for (a=2;a<length;a++)
+       {
+               ch = Data[a];
+               if (ch == '\r' && Data[a+1] == '\n') continue;
+               if ((ch>=0x20) || ch == '\n' || ch == '\t') Comment[nch++] = (char)ch;
+               else Comment[nch++] = '?';
+       }
+       Comment[nch] = '\0';
+       strcpy(m_exifinfo->Comments,Comment);
+}
+
+void Cexif::process_SOFn (const unsigned char * Data, int marker)
+{
+       int data_precision, num_components;
+
+       data_precision = Data[2];
+       m_exifinfo->Height = Get16m((void*)(Data+3));
+       m_exifinfo->Width = Get16m((void*)(Data+5));
+       num_components = Data[7];
+
+       if (num_components == 3) strcpy(m_exifinfo->IsColor,"yes");
+       else strcpy(m_exifinfo->IsColor,"no");
+
+       m_exifinfo->Process = marker;
+}
+
diff --git a/lib/gdi/picexif.h b/lib/gdi/picexif.h
new file mode 100644 (file)
index 0000000..cd321d7
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef __exif_h__
+#define __exif_h__
+
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <stdio.h>
+
+#define MAX_COMMENT 1000
+#define MAX_SECTIONS 20
+
+
+typedef struct tag_ExifInfo {
+       char  Version        [5];
+       char  CameraMake     [32];
+       char  CameraModel    [40];
+       char  DateTime       [20];
+       char  Orientation    [20];
+       char  MeteringMode   [30];
+       char  Comments[MAX_COMMENT];
+       char  FlashUsed      [20];
+       char  IsColor        [5];
+       char  ResolutionUnit [20];
+       char  ExposureProgram[30];
+       char  LightSource    [20];
+       float Xresolution;
+       float Yresolution;
+       float Brightness;
+       float ExposureTime;
+       float ExposureBias;
+       float Distance;
+       float CCDWidth;                 //in milimeters
+       float FocalplaneXRes;
+       float FocalplaneYRes;
+       float FocalplaneUnits;
+       float FocalLength;
+       float ApertureFNumber;
+       int   Height, Width;
+       int   CompressionLevel;
+       int   ISOequivalent;
+       int   Process;
+       int   Orient;
+       unsigned char * ThumbnailPointer;
+       unsigned ThumbnailSize;
+       bool  IsExif;
+} EXIFINFO;
+
+static const int BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
+
+class Cexif
+{
+       typedef struct tag_Section_t{
+       unsigned char* Data;
+       int Type;
+       unsigned Size;
+       } Section_t;
+public:
+       EXIFINFO* m_exifinfo;
+       char m_szLastError[256];
+       Cexif();
+       ~Cexif();
+       bool DecodeExif(const char *filename);
+       void ClearExif();
+protected:
+       bool process_EXIF(unsigned char * CharBuf, unsigned int length);
+       void process_COM (const unsigned char * Data, int length);
+       void process_SOFn (const unsigned char * Data, int marker);
+       int Get16u(void * Short);
+       int Get16m(void * Short);
+       long Get32s(void * Long);
+       unsigned long Get32u(void * Long);
+       double ConvertAnyFormat(void * ValuePtr, int Format);
+       bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, EXIFINFO * const pInfo, unsigned         char ** const LastExifRefdP);
+       int ExifImageWidth;
+       int MotorolaOrder;
+       Section_t Sections[MAX_SECTIONS];
+       int SectionsRead;
+       bool freeinfo;
+};
+
+#endif// __exif_h__
diff --git a/lib/gdi/picload.cpp b/lib/gdi/picload.cpp
new file mode 100644 (file)
index 0000000..28a8991
--- /dev/null
@@ -0,0 +1,535 @@
+#include "picload.h"
+#include "picexif.h"
+
+#include <png.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C" {
+#include <jpeglib.h>
+//#include "transupp.h"
+}
+#include <setjmp.h>
+
+unsigned char *pic_buffer=NULL;
+
+static unsigned char *simple_resize(unsigned char * orgin, int ox, int oy, int dx, int dy)
+{
+       unsigned char *cr, *p, *l;
+       int i, j, k, ip;
+       cr = new unsigned char[dx * dy * 3]; 
+       if (cr == NULL)
+       {
+               printf("[RESIZE] Error: malloc\n");
+               return(orgin);
+       }
+       l = cr;
+
+       for (j = 0; j < dy; j++,l += dx * 3)
+       {
+               p = orgin + (j * oy / dy * ox * 3);
+               for (i = 0, k = 0; i < dx; i++, k += 3)
+               {
+                       ip = i * ox / dx * 3;
+                       l[k] = p[ip];
+                       l[k+1] = p[ip + 1];
+                       l[k+2] = p[ip + 2];
+               }
+       }
+       delete [] orgin;
+       return(cr);
+}
+
+static unsigned char *color_resize(unsigned char * orgin, int ox, int oy, int dx, int dy)
+{
+       unsigned char *cr, *p, *q;
+       int i, j, k, l, xa, xb, ya, yb;
+       int sq, r, g, b;
+       cr = new unsigned char[dx * dy * 3];
+       if (cr == NULL)
+       {
+               printf("[RESIZE] Error: malloc\n");
+               return(orgin);
+       }
+       p = cr;
+
+       for (j = 0; j < dy; j++)
+       {
+               for (i = 0; i < dx; i++, p += 3)
+               {
+                       xa = i * ox / dx;
+                       ya = j * oy / dy;
+                       xb = (i + 1) * ox / dx; 
+                       if (xb >= ox)
+                               xb = ox - 1;
+                       yb = (j + 1) * oy / dy; 
+                       if (yb >= oy)
+                               yb = oy - 1;
+                       for (l = ya, r = 0, g = 0, b = 0, sq = 0; l <= yb; l++)
+                       {
+                               q = orgin + ((l * ox + xa) * 3);
+                               for (k = xa; k <= xb; k++, q += 3, sq++)
+                               {
+                                       r += q[0]; g += q[1]; b += q[2];
+                               }
+                       }
+                       p[0] = r / sq; p[1] = g / sq; p[2] = b / sq;
+               }
+       }
+       delete [] orgin;
+       return(cr);
+}
+
+//-------------------------------------------------------------------
+
+struct r_jpeg_error_mgr
+{
+       struct jpeg_error_mgr pub;
+       jmp_buf envbuffer;
+};
+
+void jpeg_cb_error_exit(j_common_ptr cinfo)
+{
+       struct r_jpeg_error_mgr *mptr;
+       mptr = (struct r_jpeg_error_mgr *) cinfo->err;
+       (*cinfo->err->output_message) (cinfo);
+       longjmp(mptr->envbuffer, 1);
+}
+
+static int jpeg_save(unsigned char *image_buffer, const char * filename, int quality, int image_height, int image_width)
+{
+       struct jpeg_compress_struct cinfo;
+       struct jpeg_error_mgr jerr;
+       FILE * outfile;         /* target file */
+       JSAMPROW row_pointer[1];/* pointer to JSAMPLE row[s] */
+       int row_stride;         /* physical row width in image buffer */
+       cinfo.err = jpeg_std_error(&jerr);
+       jpeg_create_compress(&cinfo);
+       if ((outfile = fopen(filename, "wb")) == NULL) 
+       {
+               eDebug("[JPEG] can't open %s", filename);
+               return -1;
+       }
+       jpeg_stdio_dest(&cinfo, outfile);
+       cinfo.image_width = image_width;
+       cinfo.image_height = image_height;
+       cinfo.input_components = 3;
+       cinfo.in_color_space = JCS_RGB;
+       jpeg_set_defaults(&cinfo);
+       jpeg_set_quality(&cinfo, quality, TRUE );
+       jpeg_start_compress(&cinfo, TRUE);
+       row_stride = image_width * 3;
+       while (cinfo.next_scanline < cinfo.image_height) 
+       {
+               row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+               (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+       }
+       jpeg_finish_compress(&cinfo);
+       fclose(outfile);
+       jpeg_destroy_compress(&cinfo);
+       return 0;
+}
+
+
+static int jpeg_load(const char *filename, int *x, int *y)
+{
+       struct jpeg_decompress_struct cinfo;
+       struct jpeg_decompress_struct *ciptr = &cinfo;
+       struct r_jpeg_error_mgr emgr;
+       FILE *fh;
+
+       if (!(fh = fopen(filename, "rb")))
+               return 0;
+
+       ciptr->err = jpeg_std_error(&emgr.pub);
+       emgr.pub.error_exit = jpeg_cb_error_exit;
+       if (setjmp(emgr.envbuffer) == 1)
+       {
+               jpeg_destroy_decompress(ciptr);
+               fclose(fh);
+               return 0;
+       }
+
+       jpeg_create_decompress(ciptr);
+       jpeg_stdio_src(ciptr, fh);
+       jpeg_read_header(ciptr, TRUE);
+       ciptr->out_color_space = JCS_RGB;
+       ciptr->scale_denom = 1;
+
+       jpeg_start_decompress(ciptr);
+       
+       *x=ciptr->output_width;
+       *y=ciptr->output_height;
+
+       if(ciptr->output_components == 3)
+       {
+               JSAMPLE *lb = (JSAMPLE *)(*ciptr->mem->alloc_small)((j_common_ptr) ciptr, JPOOL_PERMANENT, ciptr->output_width * ciptr->output_components);
+               pic_buffer = new unsigned char[ciptr->output_height * ciptr->output_width * ciptr->output_components];
+               unsigned char *bp = pic_buffer;
+
+               while (ciptr->output_scanline < ciptr->output_height)
+               {
+                       jpeg_read_scanlines(ciptr, &lb, 1);
+                       memcpy(bp, lb, ciptr->output_width * ciptr->output_components);
+                       bp += ciptr->output_width * ciptr->output_components;
+               }
+       }
+       jpeg_finish_decompress(ciptr);
+       jpeg_destroy_decompress(ciptr);
+       fclose(fh);
+       return 1;
+}
+
+//---------------------------------------------------------------------------------------------
+
+#define BMP_TORASTER_OFFSET 10
+#define BMP_SIZE_OFFSET 18
+#define BMP_BPP_OFFSET 28
+#define BMP_RLE_OFFSET 30
+#define BMP_COLOR_OFFSET 54
+
+#define fill4B(a) ((4 - ((a) % 4 )) & 0x03)
+
+static int bmp_load(const char *filename,  int *x, int *y)
+{
+       unsigned char buff[4];
+
+       int fd = open(filename, O_RDONLY);
+       if (fd == -1) return 0;
+       if (lseek(fd, BMP_SIZE_OFFSET, SEEK_SET) == -1) return 0;
+       read(fd, buff, 4);
+       *x = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
+       read(fd, buff, 4);
+       *y = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
+       if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) return 0;
+       read(fd, buff, 4);
+       int raster = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
+       if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) return 0;
+       read(fd, buff, 2);
+       int bpp = buff[0] + (buff[1] << 8);
+
+       //printf("x=%d, y=%d,bpp=%d\n",*x, *y, bpp);
+       pic_buffer = new unsigned char[(*x) * (*y) * 3];
+       unsigned char *wr_buffer = pic_buffer + (*x) * ((*y) - 1) * 3;
+       
+       switch (bpp)
+       {
+               case 24:
+               {
+                       int skip = fill4B((*x) * 3);
+                       lseek(fd, raster, SEEK_SET);
+                       unsigned char c;
+                       for (int i = 0; i < (*y); i++) 
+                       {
+                               read(fd, wr_buffer, (*x) * 3);
+                               for (int j = 0; j < (*x) * 3 ; j = j + 3)
+                               {
+                                       c = wr_buffer[j];
+                                       wr_buffer[j] = wr_buffer[j + 2];
+                                       wr_buffer[j + 2] = c;
+                               }
+                               if (skip)
+                                       read(fd, buff, skip);
+                               wr_buffer -= (*x) * 3;
+                       }
+                       break;
+               }
+               default:
+                       return 0;
+       }
+
+       close(fd);
+       return 1;
+}
+
+//---------------------------------------------------------------------------------------------
+
+static int png_load(const char *filename,  int *x, int *y)
+{
+       static const png_color_16 my_background = {0, 0, 0, 0, 0};
+
+       png_structp png_ptr;
+       png_infop info_ptr;
+       png_uint_32 width, height;
+       unsigned int i;
+       int bit_depth, color_type, interlace_type;
+       int number_passes, pass;
+       png_byte * fbptr;
+       FILE * fh;
+
+       if (!(fh = fopen(filename, "rb"))) return 0;
+
+       png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (png_ptr == NULL)
+               return 0;
+       info_ptr = png_create_info_struct(png_ptr);
+       if (info_ptr == NULL)
+       {
+               png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+               fclose(fh); 
+               return 0;
+       }
+
+       if (setjmp(png_ptr->jmpbuf))
+       {
+               png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+               fclose(fh); 
+               return 0;
+       }
+
+       png_init_io(png_ptr, fh);
+
+       png_read_info(png_ptr, info_ptr);
+       png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
+
+       if (color_type == PNG_COLOR_TYPE_PALETTE)
+       {
+               png_set_palette_to_rgb(png_ptr);
+               png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+       }
+
+       if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+       {
+               png_set_gray_to_rgb(png_ptr);
+               png_set_background(png_ptr, (png_color_16 *)&my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+       }
+
+       if (color_type & PNG_COLOR_MASK_ALPHA)
+               png_set_strip_alpha(png_ptr);
+
+       if (bit_depth < 8)      png_set_packing(png_ptr);
+       if (bit_depth == 16)    png_set_strip_16(png_ptr);
+
+       number_passes = png_set_interlace_handling(png_ptr);
+       png_read_update_info(png_ptr, info_ptr);
+
+       if (width * 3 != png_get_rowbytes(png_ptr, info_ptr))
+       {
+               eDebug("[PNG] Error processing");
+               return 0;
+       }
+       
+       pic_buffer = new unsigned char[width * height * 3];
+       *x=width;
+       *y=height;
+
+       for(pass = 0; pass < number_passes; pass++)
+       {
+               fbptr = (png_byte *)pic_buffer;
+               for (i = 0; i < height; i++, fbptr += width * 3)
+                       png_read_row(png_ptr, fbptr, NULL);
+       }
+       png_read_end(png_ptr, info_ptr);
+       png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+       fclose(fh);
+       return 1;
+}
+
+//---------------------------------------------------------------------------------------------
+
+PyObject *getExif(const char *filename)
+{
+       PyObject *list = PyList_New(0);
+       Cexif *m_exif = new Cexif();
+       if(m_exif->DecodeExif(filename))
+       {
+               
+               if(m_exif->m_exifinfo->IsExif)
+               {
+                       char tmp[256];
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->Version));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->CameraMake));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->CameraModel));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->DateTime));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->Comments));
+                       PyList_Append(list, PyString_FromFormat("%d x %d", m_exif->m_exifinfo->Width, m_exif->m_exifinfo->Height));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->Orientation));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->MeteringMode));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->ExposureProgram));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->LightSource));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->FlashUsed));
+                       PyList_Append(list, PyString_FromFormat("%d", m_exif->m_exifinfo->CompressionLevel));
+                       PyList_Append(list, PyString_FromFormat("%d", m_exif->m_exifinfo->ISOequivalent));
+                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->Xresolution);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->Yresolution);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       PyList_Append(list, PyString_FromString(m_exif->m_exifinfo->ResolutionUnit));
+                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->Brightness);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f sec.", m_exif->m_exifinfo->ExposureTime);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f", m_exif->m_exifinfo->ExposureBias);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f", m_exif->m_exifinfo->Distance);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       sprintf(tmp, "%.5f", m_exif->m_exifinfo->CCDWidth);
+                       PyList_Append(list, PyString_FromString(tmp));
+                       sprintf(tmp, "%.2f", m_exif->m_exifinfo->ApertureFNumber);
+                       PyList_Append(list, PyString_FromString(tmp));
+               }
+               else    PyList_Append(list, PyString_FromString(m_exif->m_szLastError));
+
+               m_exif->ClearExif();
+       }
+       else    PyList_Append(list, PyString_FromString(m_exif->m_szLastError));
+
+       delete m_exif;
+       
+       return list;
+}
+
+//---------------------------------------------------------------------------------------------
+
+int loadPic(ePtr<gPixmap> &result, std::string filename, int w, int h, int aspect, int resize_mode, int rotate, int background, std::string cachefile)
+{
+       result = 0;
+       int ox=0, oy=0, imx, imy;
+       pic_buffer=NULL;
+       bool cache=false;
+
+       if(cachefile.length())
+       {
+               cache = true;
+               if(jpeg_load(cachefile.c_str(), &ox, &oy))
+                       eDebug("[CACHEPIC] x-size=%d, y-size=%d", ox, oy);
+       }
+
+       if(pic_buffer==NULL)
+       {
+               unsigned int pos = filename.find_last_of(".");
+               if (pos == std::string::npos)
+                       pos = filename.length() - 1;
+               std::string ext = filename.substr(pos);
+               std::transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int)) toupper);
+               if(ext == ".JPEG" || ext == ".JPG")
+                       jpeg_load(filename.c_str(), &ox, &oy);
+               else if(ext == ".BMP")
+                       bmp_load(filename.c_str(), &ox, &oy);
+               else if(ext == ".PNG")
+                       png_load(filename.c_str(), &ox, &oy);
+               else
+               {
+                       eDebug("[PIC] <format not supportet>");
+                       return 0;
+               }
+       
+               eDebug("[FULLPIC] x-size=%d, y-size=%d", ox, oy);
+
+               if(pic_buffer==NULL)
+                       return 0;
+
+               double aspect_ratio;
+               switch(aspect)
+               {
+                       case 1:         aspect_ratio = 1.777 / ((double)720/576); break; //16:9
+                       case 2:         aspect_ratio = 1.600 / ((double)720/576); break; //16:10
+                       //case 3:       aspect_ratio = 1.250 / ((double)720/576); break; //5:4
+                       default:        aspect_ratio = 1.333 / ((double)720/576); //4:3
+               }
+
+               if((aspect_ratio * oy * w / ox) <= h)
+               {
+                       imx = w;
+                       imy = (int)(aspect_ratio*oy*w/ox);
+               }
+               else
+               {
+                       imx = (int)((1.0/aspect_ratio)*ox*h/oy);
+                       imy = h;
+               }
+
+               if(resize_mode) pic_buffer = color_resize(pic_buffer, ox, oy, imx, imy);
+               else            pic_buffer = simple_resize(pic_buffer, ox, oy, imx, imy);
+
+               ox = imx;
+               oy = imy;
+               
+               if(cache)
+               {
+                       jpeg_save(pic_buffer, cachefile.c_str(), 50, oy, ox);
+                       eDebug("[SAVEPIC] x-size=%d, y-size=%d", ox, oy);
+               }
+               
+       }
+
+       
+       result=new gPixmap(eSize(w, h), 32);
+       gSurface *surface = result->surface;
+       int a=0, b=0;
+       int nc=0, oc=0;
+       int o_y=0, u_y=0, v_x=0, h_x=0;
+       unsigned char clear[4] = {0x00,0x00,0x00,0x00};
+       if(background)  clear[3]=0xFF;
+       unsigned char *tmp_buffer = new unsigned char[4];
+
+       if(oy < h)
+       {
+               o_y=(h-oy)/2;
+               u_y=h-oy-o_y;
+       }
+       if(ox < w)
+       {
+               v_x=(w-ox)/2;
+               h_x=w-ox-v_x;
+       }
+       
+       //eDebug("o_y=%d u_y=%d v_x=%d h_x=%d", o_y, u_y, v_x, h_x);
+
+       if(oy < h)
+               for(a=0; a<(o_y*ox)+1; a++, nc+=4)
+               {
+                       memcpy(tmp_buffer, clear, sizeof(clear));
+                       tmp_buffer=((unsigned char *)(surface->data)) + nc;
+               }
+       
+       for(a=0; a<oy; a++)
+       {
+               if(ox < w)
+                       for(b=0; b<v_x; b++, nc+=4)
+                       {
+                               memcpy(tmp_buffer, clear, sizeof(clear));
+                               tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                       }
+
+               for(b=0; b<(ox*3); b+=3, nc+=4)
+               {
+                       tmp_buffer[3]=0xFF;
+                       tmp_buffer[2]=pic_buffer[oc++];
+                       tmp_buffer[1]=pic_buffer[oc++];
+                       tmp_buffer[0]=pic_buffer[oc++];
+
+                       tmp_buffer=((unsigned char *)(surface->data)) + nc;
+               }
+               
+               if(ox < w)
+                       for(b=0; b<h_x; b++, nc+=4)
+                       {
+                               memcpy(tmp_buffer, clear, sizeof(clear));
+                               tmp_buffer=((unsigned char *)(surface->data)) + nc;
+                       }
+       }
+
+       if(oy < h)
+               for(a=0; a<(u_y*ox)+1; a++, nc+=4)
+               {
+                       memcpy(tmp_buffer, clear, sizeof(clear));
+                       tmp_buffer=((unsigned char *)(surface->data)) + nc;
+               }
+       
+       //eDebug("[PIC] buffer=%d, nc=%d oc=%d ox=%d, oy=%d",w*h*4, nc, oc, ox, oy);
+       
+       surface->clut.data=0;
+       surface->clut.colors=0;
+       surface->clut.start=0;
+       
+       delete [] pic_buffer;
+
+       return 0;
+}
diff --git a/lib/gdi/picload.h b/lib/gdi/picload.h
new file mode 100644 (file)
index 0000000..7d5d8b2
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __picload_h__
+#define __picload_h__
+
+#include "Python.h"
+#include <lib/gdi/gpixmap.h>
+#include <lib/gdi/epng.h>
+
+SWIG_VOID(int) loadPic(ePtr<gPixmap> &SWIG_OUTPUT, std::string filename, int x, int y, int aspect, int resize_mode=0, int rotate=0, int background=0, std::string cachefile="");
+PyObject *getExif(const char *filename);
+
+#endif // __picload_h__
index cb87359..3772a23 100644 (file)
@@ -88,6 +88,8 @@ is usually caused by not marking PSignals as immutable.
 #include <lib/gdi/lcd.h>
 #include <lib/dvb_ci/dvbci_ui.h>
 #include <lib/python/python.h>
+#include <lib/gdi/picexif.h>
+#include <lib/gdi/picload.h>
 
 extern void runMainloop();
 extern void quitMainloop(int exit_code);
@@ -207,6 +209,8 @@ typedef long time_t;
 %include <lib/dvb_ci/dvbci_ui.h>
 %include <lib/dvb/db.h>
 %include <lib/python/python.h>
+%include <lib/gdi/picexif.h>
+%include <lib/gdi/picload.h>
 /**************  eptr  **************/
 
 %template(eActionMapPtr) ePtr<eActionMap>;