]> granicus.if.org Git - php/commitdiff
Attempt by Matt Bonneau to get thumbnail extraction working
authorRasmus Lerdorf <rasmus@php.net>
Fri, 15 Dec 2000 17:25:20 +0000 (17:25 +0000)
committerRasmus Lerdorf <rasmus@php.net>
Fri, 15 Dec 2000 17:25:20 +0000 (17:25 +0000)
(no need to bring this into the 4.0.4 branch)

ext/exif/exif.c

index dc416235a4dd1f9a7623e88ee19912de2e6495bd..d4e17cf6a7803b393c7251efc31677f3bc7a3b2f 100644 (file)
@@ -86,6 +86,7 @@ typedef struct {
        char Software[32];
        char *Thumbnail;
        int ThumbnailSize;
+       int ThumbnailOffset;
        /* Olympus vars */
        int SpecialMode;
        int JpegQual;
@@ -471,12 +472,34 @@ static double ConvertAnyFormat(void *ValuePtr, int Format, int MotorolaOrder)
     return Value;
 }
 
+/* Grab the thumbnail - by Matt Bonneau */
+static void ExtractThumbnail(ImageInfoType *ImageInfo, char *OffsetBase, unsigned ExifLength) {
+       /* according to exif2.1, the thumbnail is not supposed to be greater than 64K */
+       if (ImageInfo->ThumbnailSize > 65536) {
+               php_error(E_ERROR,"Illegal thumbnail size");
+       }
+
+       ImageInfo->Thumbnail = emalloc(ImageInfo->ThumbnailSize);
+       if (!ImageInfo->Thumbnail) {
+               php_error(E_ERROR,"Could not allocate memory for thumbnail");
+       } else {
+               /* Check to make sure we are not going to go past the ExifLength */
+               if (ImageInfo->ThumbnailOffset + ImageInfo->ThumbnailSize > ExifLength) {
+                       php_error(E_ERROR,"Thumbnail goes beyond exif header boundary");
+               } else {
+                       memcpy(ImageInfo->Thumbnail, OffsetBase + ImageInfo->ThumbnailOffset, ImageInfo->ThumbnailSize);
+               }
+       }
+}
+
 /* Process one of the nested EXIF directories. */
 static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *OffsetBase, unsigned ExifLength, char *LastExifRefd)
 {
     int de;
     int a;
     int NumDirEntries;
+    int NextDirOffset;
+    
 
     NumDirEntries = Get16u(DirStart, ImageInfo->MotorolaOrder);
 
@@ -681,12 +704,24 @@ static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *Offse
                 ImageInfo->SpecialMode = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->SpecialMode);
                                break;
 
-                       case TAG_JPEGQUAL:
-                ImageInfo->JpegQual = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->JpegQual);
+                       case TAG_JPEGQUAL: /* I think that this is a pointer to the thumbnail - let's see */
+                               ImageInfo->ThumbnailOffset = (int)ConvertAnyFormat(ValuePtr, Format, ImageInfo->ThumbnailOffset);
+                               
+                               /* see if we know the size */
+                               if (ImageInfo->ThumbnailSize) {
+                                       ExtractThumbnail(ImageInfo, OffsetBase, ExifLength);
+                               }
+                /*ImageInfo->JpegQual = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->JpegQual);*/
                                break;
 
-                       case TAG_MACRO:
-                ImageInfo->Macro = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->Macro);
+                       case TAG_MACRO: /* I think this is the size of the Thumbnail */
+                               ImageInfo->ThumbnailSize = (int)ConvertAnyFormat(ValuePtr, Format, ImageInfo->ThumbnailSize);
+
+                               /* see if we have the offset */
+                               if (ImageInfo->ThumbnailOffset) {
+                                       ExtractThumbnail(ImageInfo, OffsetBase, ExifLength);
+                               }
+                /*ImageInfo->Macro = (int)ConvertAnyFormat(ValuePtr, Format,ImageInfo->Macro);*/
                                break;
 
                        case TAG_DIGIZOOM:
@@ -716,6 +751,17 @@ static void ProcessExifDir(ImageInfoType *ImageInfo, char *DirStart, char *Offse
             continue;
         }
     }
+    /*
+     * Hack to make it process IDF1 I hope
+     * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail
+     */
+    NextDirOffset = Get32u(DirStart+2+12*de, ImageInfo->MotorolaOrder);
+    if (NextDirOffset) {
+            if (OffsetBase + NextDirOffset < OffsetBase || OffsetBase + NextDirOffset > OffsetBase+ExifLength) {
+                php_error(E_ERROR,"Illegal directory offset");
+            }
+           ProcessExifDir(ImageInfo, OffsetBase + NextDirOffset, OffsetBase, ExifLength, LastExifRefd);
+    }
 }
 
 /* 
@@ -731,6 +777,10 @@ static void process_EXIF (ImageInfoType *ImageInfo, char *CharBuf, unsigned int
     ImageInfo->FocalplaneUnits = 0;
     ImageInfo->ExifImageWidth = 0;
 
+    /* set the thumbnail stuff to nothing so we can test to see if they get set up */
+    ImageInfo->Thumbnail = NULL;
+    ImageInfo->ThumbnailSize = 0;
+
     {   /* Check the EXIF header component */
         static const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
         if (memcmp(CharBuf+2, ExifHeader,6)) {
@@ -759,6 +809,9 @@ static void process_EXIF (ImageInfoType *ImageInfo, char *CharBuf, unsigned int
     /* First directory starts 16 bytes in.  Offsets start at 8 bytes in. */
     ProcessExifDir(ImageInfo, CharBuf+16, CharBuf+8, length-6, LastExifRefd);
 
+    /* MB: This is where I will make my attempt to get the tumbnail */
+
+
     /* Compute the CCD width, in milimeters. */
     if (ImageInfo->FocalplaneXRes != 0) {
         ImageInfo->CCDWidth = (float)(ImageInfo->ExifImageWidth * ImageInfo->FocalplaneUnits / ImageInfo->FocalplaneXRes);
@@ -1010,8 +1063,9 @@ PHP_FUNCTION(read_exif_data) {
        ImageInfoType ImageInfo;
        char tmp[64];
 
-       ImageInfo.Thumbnail = NULL;
+       /*ImageInfo.Thumbnail = NULL;
        ImageInfo.ThumbnailSize = 0;
+       */
 
     if (ac != 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE)
                WRONG_PARAM_COUNT;