* 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 <endian.h>
#include "upnpreplyparse.h"
#include "image_utils.h"
#include "log.h"
@ -282,6 +283,91 @@ image_get_jpeg_resolution(const char * path, int * width, int * height)
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_new(int32_t width, int32_t height)
{

View File

@ -20,6 +20,9 @@ typedef struct {
void
image_free(image *pimage);
int
image_get_jpeg_date_xmp(const char * path, char ** date);
int
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;
ExifEntry *e = NULL;
ExifLoader *l;
ExifTag tag;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *infile;
@ -436,9 +435,8 @@ GetImageMetadata(const char * path, char * name)
if( !ed )
goto no_exifdata;
tag = 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_0], EXIF_TAG_DATE_TIME)) ) {
e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) ) {
date = strdup(exif_entry_get_value(e, b, sizeof(b)));
if( strlen(date) > 10 )
{
@ -451,15 +449,17 @@ GetImageMetadata(const char * path, char * name)
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);
tag = EXIF_TAG_MAKE;
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], tag);
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
if( e )
{
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], tag);
e = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
if( e )
{
strncpy(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));