* Fall back to rudimentary XMP parsing when getting image dates from EXIF fails.

This commit is contained in:
Justin Maggard 2009-11-05 23:15:29 +00:00
parent c8fe23d838
commit a26802539f
3 changed files with 97 additions and 8 deletions

View File

@ -35,6 +35,7 @@
#include <jpeglib.h> #include <jpeglib.h>
#include <endian.h> #include <endian.h>
#include "upnpreplyparse.h"
#include "image_utils.h" #include "image_utils.h"
#include "log.h" #include "log.h"
@ -282,6 +283,91 @@ image_get_jpeg_resolution(const char * path, int * width, int * height)
return ret; return ret;
} }
int
image_get_jpeg_date_xmp(const char * path, char ** date)
{
FILE *img;
unsigned char buf[8];
char *data = NULL;
u_int16_t offset;
struct NameValueParserData xml;
char * exif;
int ret = 1;
img = fopen(path, "r");
if( !img )
return(-1);
fread(&buf, 2, 1, img);
if( (buf[0] != 0xFF) || (buf[1] != 0xD8) )
{
fclose(img);
return(-1);
}
memset(&buf, 0, sizeof(buf));
while( !feof(img) )
{
while( buf[0] != 0xFF && !feof(img) )
fread(&buf, 1, 1, img);
while( buf[0] == 0xFF && !feof(img) )
fread(&buf, 1, 1, img);
if( feof(img) )
break;
if( buf[0] == 0xE1 ) // APP1 marker
{
offset = 0;
fread(&buf, 2, 1, img);
memcpy(&offset, buf, 2);
offset = SWAP16(offset) - 2;
if( offset < 30 )
{
fseek(img, offset, SEEK_CUR);
continue;
}
data = realloc(data, 30);
fread(data, 29, 1, img);
offset -= 29;
if( strcmp(data, "http://ns.adobe.com/xap/1.0/") != 0 )
{
fseek(img, offset, SEEK_CUR);
continue;
}
data = realloc(data, offset+1);
fread(data, offset, 1, img);
ParseNameValue(data, offset, &xml);
exif = GetValueFromNameValueList(&xml, "DateTimeOriginal");
if( !exif )
break;
*date = realloc(*date, strlen(exif)+1);
strcpy(*date, exif);
ClearNameValueList(&xml);
ret = 0;
break;
}
else
{
offset = 0;
fread(&buf, 2, 1, img);
memcpy(&offset, buf, 2);
offset = SWAP16(offset) - 2;
fseek(img, offset, SEEK_CUR);
}
}
fclose(img);
if( data )
free(data);
return ret;
}
image * image *
image_new(int32_t width, int32_t height) image_new(int32_t width, int32_t height)
{ {

View File

@ -20,6 +20,9 @@ typedef struct {
void void
image_free(image *pimage); image_free(image *pimage);
int
image_get_jpeg_date_xmp(const char * path, char ** date);
int int
image_get_jpeg_resolution(const char * path, int * width, int * height); image_get_jpeg_resolution(const char * path, int * width, int * height);

View File

@ -406,7 +406,6 @@ GetImageMetadata(const char * path, char * name)
ExifData *ed; ExifData *ed;
ExifEntry *e = NULL; ExifEntry *e = NULL;
ExifLoader *l; ExifLoader *l;
ExifTag tag;
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr; struct jpeg_error_mgr jerr;
FILE *infile; FILE *infile;
@ -436,9 +435,8 @@ GetImageMetadata(const char * path, char * name)
if( !ed ) if( !ed )
goto no_exifdata; goto no_exifdata;
tag = EXIF_TAG_DATE_TIME_ORIGINAL; e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], tag); if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) ) {
if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_DATE_TIME)) ) {
date = strdup(exif_entry_get_value(e, b, sizeof(b))); date = strdup(exif_entry_get_value(e, b, sizeof(b)));
if( strlen(date) > 10 ) if( strlen(date) > 10 )
{ {
@ -451,15 +449,17 @@ GetImageMetadata(const char * path, char * name)
date = NULL; date = NULL;
} }
} }
else {
/* One last effort to get the date from XMP */
image_get_jpeg_date_xmp(path, &date);
}
//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", date); //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", date);
tag = EXIF_TAG_MAKE; e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], tag);
if( e ) if( e )
{ {
strncpy(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make)); strncpy(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
tag = EXIF_TAG_MODEL; e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], tag);
if( e ) if( e )
{ {
strncpy(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model)); strncpy(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));