/* {{{ exif_module_entry
*/
zend_module_entry exif_module_entry = {
- STANDARD_MODULE_HEADER,
+#if ZEND_MODULE_API_NO >= 20010901
+ STANDARD_MODULE_HEADER,
+#endif
"exif",
exif_functions,
- NULL, NULL,
+ NULL, NULL,
NULL, NULL,
PHP_MINFO(exif),
EXIF_VERSION,
/* {{{ exif_get_tagname
Get headername for tag_num or NULL if not defined */
-static char * exif_get_tagname(int tag_num, char *ret)
+static char * exif_get_tagname(int tag_num, char *ret, int len)
{
int i,t;
+ char tmp[32];
for (i=0;;i++) {
if ( (t=TagTable[i].Tag) == tag_num || !t) {
- if (ret) {
- strcpy(ret,TagTable[i].Desc);
- if ( !t) sprintf(ret,"UndefinedTag:0x%04X", tag_num);
+ if (ret && len) {
+ if ( !t) break;
+ strncpy(ret,TagTable[i].Desc,abs(len));
+ if ( len<0) {
+ len = -len;
+ ret[len-1]='\0';
+ for(i=strlen(ret);i<len;i++)ret[i]=' ';
+ }
+ ret[len-1]='\0';
return ret;
}
return TagTable[i].Desc;
}
}
- if (ret) {
- sprintf(ret,"UndefinedTag:0x%04X", tag_num);
+ if (ret && len) {
+ sprintf(tmp,"UndefinedTag:0x%04X", tag_num);
+ strncpy(ret,tmp,abs(len));
+ if ( len<0) {
+ len = -len;
+ ret[len-1]='\0';
+ for(i=strlen(ret);i<len;i++)ret[i]=' ';
+ }
+ ret[len-1]='\0';
return ret;
}
return "";
unsigned int den;
} unsigned_rational;
-typedef struct {
- WORD tag;
- WORD format;
- DWORD length;
- union {
- char *s;
- unsigned u;
- int i;
- float f;
- double d;
- signed_rational sr;
- unsigned_rational ur;
- } value;
- char *name;
+typedef union _image_info_value {
+ char *s;
+ unsigned u;
+ int i;
+ float f;
+ double d;
+ signed_rational sr;
+ unsigned_rational ur;
+ union _image_info_value *list;
} image_info_value;
+typedef struct {
+ WORD tag;
+ WORD format;
+ DWORD length;
+ DWORD dummy; /* value ptr of tiff directory entry */
+ char *name;
+ image_info_value value;
+} image_info_data;
+
typedef struct {
int count;
- image_info_value *list;
+ image_info_data *list;
} image_info_list;
/* }}} */
for(i=0; i<SECTION_COUNT; i++) len += strlen(exif_get_sectionname(i))+2;
sections = emalloc(len+1);
+ if ( !sections) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return NULL;
+ }
sections[0] = '\0';
len = 0;
for(i=0; i<SECTION_COUNT; i++) {
} image_info_type;
/* }}} */
-/* {{{ exif_add_image_info
- Free memory allocated for image_info
+/* {{{ exif_iif_add_value
+ Add a value to image_info
*/
-void exif_add_image_info( image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value)
+void exif_iif_add_value( image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, int motorola_intel)
{
- image_info_value *info_value, *list;
+ int index;
+ image_info_value *info_value;
+ image_info_data *info_data;
+ image_info_data *list;
- list = erealloc(image_info->info_list[section_index].list,(image_info->info_list[section_index].count+1)*sizeof(image_info_value));
+ list = erealloc(image_info->info_list[section_index].list,(image_info->info_list[section_index].count+1)*sizeof(image_info_data));
if ( !list) {
- php_error(E_WARNING,"Cannot allocate memory for all data");
+ php_error(E_ERROR,"Cannot allocate memory for all data");
return;
}
image_info->info_list[section_index].list = list;
- image_info->sections_found |= 1<<section_index;
-
- info_value = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
- info_value->name = emalloc(strlen(name)+1);
- strcpy(info_value->name, name);
+ info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
+ info_data->tag = tag;
+ info_data->format = format;
+ info_data->length = length;
+ info_data->name = emalloc(strlen(name)+1);
+ if ( !info_data->name) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return;
+ }
+ info_value = &info_data->value;
+ strcpy(info_data->name, name);
- info_value->tag = tag;
- info_value->format = format;
- info_value->length = 1; /* we do not support arrays other than STRING/UNDEFINED */
switch (format) {
- case TAG_FMT_BYTE:
- info_value->value.u = *(uchar*)value;
- break;
-
case TAG_FMT_STRING:
length = php_strnlen(value,length);
- info_value->value.s = emalloc(length+1);
- strcpy(info_value->value.s,value);
- info_value->length = length;
- break;
-
- case TAG_FMT_USHORT:
- info_value->value.u = php_ifd_get16u(value,image_info->motorola_intel);
- break;
-
- case TAG_FMT_ULONG:
- info_value->value.u = php_ifd_get32u(value,image_info->motorola_intel);
- break;
-
- case TAG_FMT_URATIONAL:
- info_value->value.ur.num = php_ifd_get32u(value, image_info->motorola_intel);
- info_value->value.ur.den = php_ifd_get32u(4+(char *)value, image_info->motorola_intel);
- break;
-
- case TAG_FMT_SBYTE:
- info_value->value.i = *(char*)value;
+ info_data->length = length;
+ info_value->s = emalloc(length+1);
+ if ( !info_value->s) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return;
+ }
+ strcpy(info_value->s,value);
break;
default:
* So not return but use type UNDEFINED
* return;
*/
- info_value->tag = TAG_FMT_UNDEFINED;/* otherwise not freed from memory */
+ info_data->tag = TAG_FMT_UNDEFINED;/* otherwise not freed from memory */
+ case TAG_FMT_SBYTE:
+ case TAG_FMT_BYTE:
+ /* in contrast to strings bytes do not need to allocate buffer for NULL if length==0 */
+ if ( length<1)
+ break;
+ if ( format==TAG_FMT_BYTE && length==1)
+ {
+ info_value->u = *(uchar*)value;
+ break;
+ }
+ if ( format==TAG_FMT_SBYTE && length==1)
+ {
+ info_value->i = *(char*)value;
+ break;
+ }
case TAG_FMT_UNDEFINED:
- info_value->value.s = emalloc(length+1);
- memcpy(info_value->value.s,value,length);
- info_value->value.s[length] = '\0';
- info_value->length = length; /* not +1 !!! */
+ info_value->s = emalloc(length+1);
+ if ( !info_value->s) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return;
+ }
+ memcpy(info_value->s,value,length);
+ info_value->s[length] = '\0';
break;
+ case TAG_FMT_USHORT:
+ case TAG_FMT_ULONG:
+ case TAG_FMT_URATIONAL:
case TAG_FMT_SSHORT:
- info_value->value.i = php_ifd_get16s(value,image_info->motorola_intel);
- break;
-
case TAG_FMT_SLONG:
- info_value->value.i = php_ifd_get32s(value,image_info->motorola_intel);
- break;
-
case TAG_FMT_SRATIONAL:
- info_value->value.sr.num = php_ifd_get32u(value, image_info->motorola_intel);
- info_value->value.sr.den = php_ifd_get32u(4+(char *)value, image_info->motorola_intel);
- break;
-
case TAG_FMT_SINGLE:
- php_error(E_WARNING, "Found value of type single");
- info_value->value.f = (double)*(float *)value;
-
case TAG_FMT_DOUBLE:
- php_error(E_WARNING, "Found value of type double");
- info_value->value.d = *(double *)value;
- break;
+ if ( length==0) {
+ break;
+ } else
+ if ( length>1) {
+ info_data->value.list = emalloc(length*sizeof(image_info_value));
+ if ( !info_data->value.list) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return;
+ }
+ info_value = &info_data->value.list[0];
+ } else {
+ info_value = &info_data->value;
+ }
+ for (index=0; index<length; index++) {
+ switch (format) {
+ case TAG_FMT_USHORT:
+ info_value->u = php_ifd_get16u(value,motorola_intel);
+ break;
+
+ case TAG_FMT_ULONG:
+ info_value->u = php_ifd_get32u(value,motorola_intel);
+ break;
+
+ case TAG_FMT_URATIONAL:
+ info_value->ur.num = php_ifd_get32u(value, motorola_intel);
+ info_value->ur.den = php_ifd_get32u(4+(char *)value, motorola_intel);
+ break;
+
+ case TAG_FMT_SSHORT:
+ info_value->i = php_ifd_get16s(value,motorola_intel);
+ break;
+
+ case TAG_FMT_SLONG:
+ info_value->i = php_ifd_get32s(value,motorola_intel);
+ break;
+
+ case TAG_FMT_SRATIONAL:
+ info_value->sr.num = php_ifd_get32u(value, motorola_intel);
+ info_value->sr.den = php_ifd_get32u(4+(char *)value, motorola_intel);
+ break;
+
+ case TAG_FMT_SINGLE:
+ php_error(E_WARNING, "Found value of type single");
+ info_value->f = (double)*(float *)value;
+
+ case TAG_FMT_DOUBLE:
+ php_error(E_WARNING, "Found value of type double");
+ info_value->d = *(double *)value;
+ break;
+ }
+ info_value = &info_data->value.list[index];
+ }
+ }
+ image_info->sections_found |= 1<<section_index;
+ image_info->info_list[section_index].count++;
+}
+/* }}} */
+
+/* {{{ exif_iif_add_tag
+ Add a tag from IFD to image_info
+*/
+void exif_iif_add_tag( image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value)
+{
+ exif_iif_add_value( image_info, section_index, name, tag, format, length, value, image_info->motorola_intel);
+}
+/* }}} */
+
+/* {{{ exif_iif_add_int
+ Add a tag from IFD to image_info
+*/
+void exif_iif_add_int( image_info_type *image_info, int section_index, char *name, int value)
+{
+ int index;
+ image_info_data *info_data;
+ image_info_data *list;
+
+ list = erealloc(image_info->info_list[section_index].list,(image_info->info_list[section_index].count+1)*sizeof(image_info_data));
+ if ( !list) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return;
}
+ image_info->info_list[section_index].list = list;
+ info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
+ info_data->tag = TAG_NONE;
+ info_data->format = TAG_FMT_SLONG;
+ info_data->length = 1;
+ info_data->name = emalloc(strlen(name)+1);
+ if ( !info_data->name) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return;
+ }
+ strcpy(info_data->name, name);
+ info_data->value.i = value;
+ image_info->sections_found |= 1<<section_index;
image_info->info_list[section_index].count++;
}
/* }}} */
-/* {{{ exif_free_image_info
+/* {{{ exif_iif_free
Free memory allocated for image_info
*/
-void exif_free_image_info( image_info_type *image_info, int section_index)
+void exif_iif_free( image_info_type *image_info, int section_index)
{
int i;
for (i=0; i < image_info->info_list[section_index].count; i++)
{
efree(image_info->info_list[section_index].list[i].name);
- if ( image_info->info_list[section_index].list[i].format == TAG_FMT_STRING
- ||image_info->info_list[section_index].list[i].format == TAG_FMT_UNDEFINED
- )
+ switch(image_info->info_list[section_index].list[i].format)
{
- efree(image_info->info_list[section_index].list[i].value.s);
+ case TAG_FMT_SBYTE:
+ case TAG_FMT_BYTE:
+ /* in contrast to strings bytes do not need to allocate buffer for NULL if length==0 */
+ if (image_info->info_list[section_index].list[i].length<=1)
+ break;
+ default:
+ case TAG_FMT_UNDEFINED:
+ case TAG_FMT_STRING:
+ efree(image_info->info_list[section_index].list[i].value.s);
+ break;
+
+ case TAG_FMT_USHORT:
+ case TAG_FMT_ULONG:
+ case TAG_FMT_URATIONAL:
+ case TAG_FMT_SSHORT:
+ case TAG_FMT_SLONG:
+ case TAG_FMT_SRATIONAL:
+ case TAG_FMT_SINGLE:
+ case TAG_FMT_DOUBLE:
+ /* nothing to do here */
+ break;
}
}
efree(image_info->info_list[section_index].list);
void add_assoc_image_info( pval *value, int sub_array, image_info_type *image_info, int section_index)
{
char buffer[64];
- int idx=0;
- image_info_value *info_value;
+ int i, ap, l, b, idx=0, done;
+ image_info_value *info_value;
+ image_info_data *info_data;
+ pval *tmpi, *array;
if ( image_info->info_list[section_index].count)
{
- int i;
- pval *tmpi;
if ( sub_array) {
MAKE_STD_ZVAL(tmpi);
for(i=0; i<image_info->info_list[section_index].count; i++)
{
- info_value = &image_info->info_list[section_index].list[i];
- #ifdef EXIF_DEBUG
- php_error(E_NOTICE,"adding info #%d: '%s:%s'", i, exif_get_sectionname(section_index), info_value->name);
- #endif
- switch(info_value->format)
+ done = 0;
+ info_data = &image_info->info_list[section_index].list[i];
+ info_value = &info_data->value;
+ if (info_data->length==0)
{
- default:
- /* Standard says more types possible but skip them...
- * but allow users to handle data if they know how to
- * So not return but use type UNDEFINED
- * return;
- */
- case TAG_FMT_UNDEFINED:
- add_assoc_stringl(tmpi, info_value->name, info_value->value.s, info_value->length, 1);
- break;
+ add_assoc_null(tmpi, info_data->name);
+ } else {
+ switch (info_data->format)
+ {
+ default:
+ /* Standard says more types possible but skip them...
+ * but allow users to handle data if they know how to
+ * So not return but use type UNDEFINED
+ * return;
+ */
+ case TAG_FMT_UNDEFINED:
+ add_assoc_stringl(tmpi, info_data->name, info_value->s, info_data->length, 1);
+ break;
- case TAG_FMT_STRING:
- if (section_index==SECTION_COMMENT) {
- add_index_string(tmpi, idx++, info_value->value.s, 1);
- } else {
- add_assoc_string(tmpi, info_value->name, info_value->value.s, 1);
- }
- break;
+ case TAG_FMT_STRING:
+ if (section_index==SECTION_COMMENT) {
+ add_index_string(tmpi, idx++, info_value->s, 1);
+ } else {
+ add_assoc_string(tmpi, info_data->name, info_value->s, 1);
+ }
+ break;
- case TAG_FMT_BYTE:
- case TAG_FMT_USHORT:
- case TAG_FMT_ULONG:
- add_assoc_long(tmpi, info_value->name, (int)info_value->value.u);
+ case TAG_FMT_URATIONAL:
+ case TAG_FMT_SRATIONAL:
break;
+ case TAG_FMT_BYTE:
+ case TAG_FMT_SBYTE:
+ case TAG_FMT_USHORT:
+ case TAG_FMT_SSHORT:
+ case TAG_FMT_SINGLE:
+ case TAG_FMT_DOUBLE:
+ case TAG_FMT_ULONG:
+ case TAG_FMT_SLONG:
+ /* now the rest, first see if it becomes an array */
+ if ( (l = info_data->length) > 1) {
+ array = NULL;
+ MAKE_STD_ZVAL(array);
+ array_init(array);
+ info_value = &info_data->value.list[0];
+ }
+ for(ap=0; ap<l; ap++)
+ {
+ switch (info_data->format)
+ {
+ case TAG_FMT_BYTE:
+ if (l>1) {
+ info_value = &info_data->value;
+ for (b=0;b<l;b++)
+ {
+ add_index_long(array, b, (int)(info_value->s[b]));
+ }
+ break;
+ }
+ case TAG_FMT_USHORT:
+ case TAG_FMT_ULONG:
+ if (l==1) {
+ add_assoc_long(tmpi, info_data->name, (int)info_value->u);
+ } else {
+ add_index_long(array, ap, (int)info_value->u);
+ }
+ break;
- case TAG_FMT_URATIONAL:
- sprintf(buffer,"%i/%i", info_value->value.ur.num, info_value->value.ur.den);
- add_assoc_string(tmpi, info_value->name, buffer, 1);
- break;
+ case TAG_FMT_URATIONAL:
+ sprintf(buffer,"%i/%i", info_value->ur.num, info_value->ur.den);
+ if (l==1) {
+ add_assoc_string(tmpi, info_data->name, buffer, 1);
+ } else {
+ add_index_string(array, ap, buffer, 1);
+ }
+ break;
- case TAG_FMT_SBYTE:
- case TAG_FMT_SSHORT:
- case TAG_FMT_SLONG:
- add_assoc_long(tmpi, info_value->name, info_value->value.i);
- break;
+ case TAG_FMT_SBYTE:
+ if (l>1) {
+ info_value = &info_data->value;
+ for (b=0;b<l;b++)
+ {
+ add_index_long(array, ap, (int)info_value->s[b]);
+ }
+ break;
+ }
+ case TAG_FMT_SSHORT:
+ case TAG_FMT_SLONG:
+ if (l==1) {
+ add_assoc_long(tmpi, info_data->name, info_value->i);
+ } else {
+ add_index_long(array, ap, info_value->i);
+ }
+ break;
- case TAG_FMT_SRATIONAL:
- sprintf(buffer,"%i/%i", info_value->value.sr.num, info_value->value.sr.den);
- add_assoc_string(tmpi, info_value->name, buffer, 1);
- break;
+ case TAG_FMT_SRATIONAL:
+ sprintf(buffer,"%i/%i", info_value->sr.num, info_value->sr.den);
+ if (l==1) {
+ add_assoc_string(tmpi, info_data->name, buffer, 1);
+ } else {
+ add_index_string(array, ap, buffer, 1);
+ }
+ break;
- case TAG_FMT_SINGLE:
- add_assoc_double(tmpi, info_value->name, info_value->value.f);
- break;
+ case TAG_FMT_SINGLE:
+ if (l==1) {
+ add_assoc_double(tmpi, info_data->name, info_value->f);
+ } else {
+ add_index_double(array, ap, info_value->f);
+ }
+ break;
- case TAG_FMT_DOUBLE:
- add_assoc_double(tmpi, info_value->name, info_value->value.d);
- break;
+ case TAG_FMT_DOUBLE:
+ if (l==1) {
+ add_assoc_double(tmpi, info_data->name, info_value->d);
+ } else {
+ add_index_double(array, ap, info_value->d);
+ }
+ break;
+ }
+ info_value = &info_data->value.list[ap];
+ }
+ if ( l>1) {
+ add_assoc_zval(tmpi, info_data->name, array);
+ }
+ break;
+ }
}
}
if ( sub_array) {
*/
static void exif_process_COM (image_info_type *image_info, uchar *value, int length)
{
- exif_add_image_info( image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value);
+ exif_iif_add_tag( image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value);
}
/* }}} */
convert_to_long_ex(p_num);
tag = Z_LVAL_PP(p_num);
- szTemp = exif_get_tagname(tag,NULL);
+ szTemp = exif_get_tagname(tag,NULL,0);
if ( tag<0 || !szTemp || !szTemp[0]) {
RETURN_BOOL(FALSE);
} else {
}
ImageInfo->Thumbnail = emalloc(ImageInfo->ThumbnailSize);
if (!ImageInfo->Thumbnail) {
- php_error(E_WARNING, "Could not allocate memory for thumbnail");
+ php_error(E_ERROR, "Could not allocate memory for thumbnail");
return;
} else {
/* Check to make sure we are not going to go past the ExifLength */
*/
if (byte_count) {
(*result) = emalloc(byte_count+1);
+ if ( !*result) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return 0;
+ }
memcpy(*result, value, byte_count);
(*result)[byte_count] = '\0';
return byte_count+1;
*/
if ((byte_count=php_strnlen(value,byte_count)) > 0) {
(*result) = emalloc(byte_count+1);
+ if ( !*result) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return 0;
+ }
memcpy(*result, value, byte_count);
(*result)[byte_count] = '\0';
return byte_count+1;
}
if (l>1) {
*pszInfoPtr = emalloc(l+1);
+ if ( !*pszInfoPtr) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return 0;
+ }
wcstombs(*pszInfoPtr, (wchar_t*)(szValuePtr), l+1);
(*pszInfoPtr)[l] = '\0';
return l+1;
if (value_ptr < dir_entry) {
/* we can read this if offset_val > 0 */
/* some files have their values in other parts of the file */
- php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X < x%04X)", tag, exif_get_tagname(tag,tagname), offset_val, dir_entry);
+ php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X < x%04X)", tag, exif_get_tagname(tag,tagname,-13), offset_val, dir_entry);
} else {
/* this is for sure not allowed */
/* exception are IFD pointers */
- php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname(tag,tagname), offset_val, byte_count, offset_val+byte_count, IFDlength);
+ php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname(tag,tagname,-13), offset_val, byte_count, offset_val+byte_count, IFDlength);
}
return;
}
ImageInfo->sections_found |= FOUND_ANY_TAG;
#ifdef EXIF_DEBUG
- php_error(E_NOTICE,"process tag(x%04x=%s,@x%04X+x%04X(=%d)): %s", tag, exif_get_tagname(tag,tagname), value_ptr-offset_base, byte_count, byte_count, format==TAG_FMT_STRING?(value_ptr?value_ptr:"<no data>"):exif_get_tagformat(format));
+ php_error(E_NOTICE,"process tag(x%04X=%s,@x%04X + x%04X(=%d)): %s%s", tag, exif_get_tagname(tag,tagname,-13), offset_val, byte_count, byte_count, components&&format!=TAG_FMT_UNDEFINED&&format!=TAG_FMT_STRING?"ARRAY OF ":"", format==TAG_FMT_STRING?(value_ptr?value_ptr:"<no data>"):exif_get_tagformat(format));
#endif
if (section_index==SECTION_THUMBNAIL) {
switch(tag) {
if (byte_count>1 && (l=php_strnlen(value_ptr,byte_count)) > 0) {
if ( l<byte_count-1) {
/* When there are any characters after the first NUL */
- exif_add_image_info( ImageInfo, SECTION_COMPUTED, "Copyright.Photographer", TAG_COPYRIGHT, TAG_FMT_STRING, l, value_ptr);
- exif_add_image_info( ImageInfo, SECTION_COMPUTED, "Copyright.Editor", TAG_COPYRIGHT, TAG_FMT_STRING, byte_count-l-1, value_ptr+l+1);
+ exif_iif_add_tag( ImageInfo, SECTION_COMPUTED, "Copyright.Photographer", TAG_COPYRIGHT, TAG_FMT_STRING, l, value_ptr);
+ exif_iif_add_tag( ImageInfo, SECTION_COMPUTED, "Copyright.Editor", TAG_COPYRIGHT, TAG_FMT_STRING, byte_count-l-1, value_ptr+l+1);
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"added copyrights: %s, %s", value_ptr, value_ptr+l+1);
#endif
#endif
ImageInfo->sections_found |= FOUND_INTEROP;
sub_section_index = SECTION_INTEROP;
- /* we do not know how to handle that yet */
- /* return; */
break;
}
SubdirStart = offset_base + php_ifd_get32u(value_ptr, ImageInfo->motorola_intel);
/* correctly would be to set components as length
* but we are ignoring length for those types where it is not the same as byte_count
*/
- exif_add_image_info( ImageInfo, section_index, exif_get_tagname(tag,tagname), tag, format, byte_count, value_ptr);
+ exif_iif_add_tag( ImageInfo, section_index, exif_get_tagname(tag,tagname,sizeof(tagname)), tag, format, components, value_ptr);
}
/* }}} */
NumDirEntries = php_ifd_get16u(DirStart, ImageInfo->motorola_intel);
if ((DirStart+2+NumDirEntries*12) > (OffsetBase+IFDlength)) {
- php_error(E_WARNING, "Illegally sized directory x%04X + 2 + x%04X*12 = x%04X > x%04X", (int)DirStart+2-(int)OffsetBase, NumDirEntries, (int)DirStart+2+NumDirEntries*12-(int)OffsetBase, IFDlength);
+ php_error(E_WARNING, "Illegal directory size: x%04X + 2 + x%04X*12 = x%04X > x%04X", (int)DirStart+2-(int)OffsetBase, NumDirEntries, (int)DirStart+2+NumDirEntries*12-(int)OffsetBase, IFDlength);
return;
}
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"expect next IFD to be thumbnail");
#endif
- exif_process_IFD_in_JPEG(ImageInfo, OffsetBase + NextDirOffset, OffsetBase, IFDlength, SECTION_THUMBNAIL);/**/
+ exif_process_IFD_in_JPEG(ImageInfo, OffsetBase + NextDirOffset, OffsetBase, IFDlength, SECTION_THUMBNAIL);
}
}
/* }}} */
return;
}
+ ImageInfo->sections_found |= FOUND_IFD0;
/* First directory starts at offset 8. Offsets starts at 0. */
exif_process_IFD_in_JPEG(ImageInfo, CharBuf+8, CharBuf, length/*-14*/, SECTION_IFD0);
int l1, l2=0;
if ( (l1 = php_strnlen(buffer+2,length-2)) > 0) {
- exif_add_image_info( ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2);
+ exif_iif_add_tag( ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2);
if ( length > 2+l1+1) {
l2 = php_strnlen(buffer+2+l1+1,length-2-l1+1);
- exif_add_image_info( ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1);
+ exif_iif_add_tag( ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1);
}
}
#ifdef EXIF_DEBUG
#ifdef EXIF_DEBUG
fpos = ftell(infile);
- php_error(E_NOTICE,"search section %d at 0x%04X", ImageInfo->sections_count, fpos);
+ php_error(E_NOTICE,"needing section %d @ 0x%04X", ImageInfo->sections_count, fpos);
#endif
for (a=0;a<7;a++) {
ImageInfo->sections[ImageInfo->sections_count].Size = itemlen;
Data = (uchar *)emalloc(itemlen+1); /* Add 1 to allow sticking a 0 at the end. */
+ if ( !Data) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return FALSE;
+ }
ImageInfo->sections[ImageInfo->sections_count].Data = Data;
/* Store first two pre-read bytes. */
size = ep-cp;
Data = (uchar *)emalloc(size);
if (Data == NULL) {
- php_error(E_WARNING, "could not allocate data for entire image");
+ php_error(E_ERROR, "could not allocate data for entire image");
return FALSE;
}
break;
case M_EXIF:
- if ( !(ImageInfo->sections_found&FOUND_EXIF)) {
- ImageInfo->sections_found |= FOUND_EXIF;
+ if ( !(ImageInfo->sections_found&FOUND_IFD0)) {
+ /*ImageInfo->sections_found |= FOUND_EXIF;*/
/* Seen files from some 'U-lead' software with Vivitar scanner
that uses marker 31 later in the file (no clue what for!) */
exif_process_APP1(ImageInfo, (char *)Data, itemlen);
if ( ImageInfo->FileSize >= dir_offset+2) {
ImageInfo->sections[sn].Size = 2;
ImageInfo->sections[sn].Data = emalloc(ImageInfo->sections[sn].Size);
+ if ( !ImageInfo->sections[sn].Data) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return FALSE;
+ }
fseek(infile,dir_offset,SEEK_SET); /* we do not know the order of sections */
fread(ImageInfo->sections[sn].Data, 1, 2, infile);
num_entries = php_ifd_get16u(ImageInfo->sections[sn].Data, ImageInfo->motorola_intel);
if ( ImageInfo->FileSize >= dir_offset+dir_size) {
ImageInfo->sections[sn].Size = dir_size;
ImageInfo->sections[sn].Data = erealloc(ImageInfo->sections[sn].Data,ImageInfo->sections[sn].Size);
+ if ( !ImageInfo->sections[sn].Data) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return FALSE;
+ }
fread(ImageInfo->sections[sn].Data+2, 1, dir_size-2, infile);
next_offset = php_ifd_get32u(ImageInfo->sections[sn].Data + dir_size - 4, ImageInfo->motorola_intel);
#ifdef EXIF_DEBUG
}
ImageInfo->sections[sn].Size = ifd_size;
ImageInfo->sections[sn].Data = erealloc(ImageInfo->sections[sn].Data,ImageInfo->sections[sn].Size);
+ if ( !ImageInfo->sections[sn].Data) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ return FALSE;
+ }
if ( ImageInfo->FileSize >= ImageInfo->sections[sn].Size) {
if ( ifd_size > dir_size) {
/* read values not stored in directory itself */
case TAG_INTEROP_IFD_POINTER:
ImageInfo->sections_found |= FOUND_INTEROP;
sub_section_index = SECTION_INTEROP;
- /* we do not know how to handle that yet */
- /* return; */
break;
}
entry_offset = php_ifd_get32u(dir_entry+8, ImageInfo->motorola_intel);
#ifdef EXIF_DEBUG
- php_error(E_NOTICE,"Found other IFD: %s at x%04X", exif_get_tagname(entry_tag,tagname), entry_offset);
+ php_error(E_NOTICE,"Next IFD %s at x%04X", exif_get_sectionname(sub_section_index), entry_offset);
#endif
exif_process_IFD_in_TIFF(ImageInfo,infile,entry_offset,sub_section_index);
#ifdef EXIF_DEBUG
- php_error(E_NOTICE,"TIFF subsection %s done", exif_get_sectionname(sub_section_index));
+ php_error(E_NOTICE,"Next IFD %s done", exif_get_sectionname(sub_section_index));
#endif
} else {
exif_process_IFD_TAG(ImageInfo,dir_entry,ImageInfo->sections[sn].Data-dir_offset,ifd_size,section_index,0);
if (ImageInfo->ThumbnailOffset && ImageInfo->ThumbnailSize) {
ImageInfo->Thumbnail = emalloc(ImageInfo->ThumbnailSize);
if (!ImageInfo->Thumbnail) {
- php_error(E_WARNING, "Could not allocate memory for thumbnail");
+ php_error(E_ERROR, "Could not allocate memory for thumbnail");
} else {
fseek(infile,ImageInfo->ThumbnailOffset,SEEK_SET);
fread(ImageInfo->Thumbnail, 1, ImageInfo->ThumbnailSize, infile);
if (ImageInfo->FileName) efree(ImageInfo->FileName);
if (ImageInfo->Thumbnail) efree(ImageInfo->Thumbnail);
for (i=0; i<SECTION_COUNT; i++) {
- exif_free_image_info( ImageInfo, i);
+ exif_iif_free( ImageInfo, i);
}
php_exif_discard_sections(ImageInfo);
memset(ImageInfo, 0, sizeof(*ImageInfo));
php_error(E_WARNING, "Unable to open '%s'", FileName);
return FALSE;
}
- /* php_error(E_WARNING,"EXIF: Process %s%s: %s", read_thumbnail?"thumbs ":"", read_all?"All ":"", FileName); */
/* Start with an empty image information structure. */
memset(ImageInfo, 0, sizeof(*ImageInfo));
if(ac >= 2) {
convert_to_string_ex(p_sections_needed);
sections_str = emalloc(strlen(Z_STRVAL_PP(p_sections_needed))+3);
+ if ( !sections_str) {
+ php_error(E_ERROR,"Cannot allocate memory for all data");
+ RETURN_FALSE;
+ }
sprintf(sections_str,",%s,",Z_STRVAL_PP(p_sections_needed));
/* sections_str DOES start with , and SPACES are NOT allowed in names */
s = sections_str;
sections_str = exif_get_sectionlist(ImageInfo.sections_found);
#ifdef EXIF_DEBUG
- php_error(E_NOTICE,"Sections found: %s", sections_str[0] ? sections_str : "None");
+ php_error(E_NOTICE,"sections found: %s", sections_str[0] ? sections_str : "None");
#endif
ImageInfo.sections_found |= FOUND_COMPUTED;/* do not inform about in debug*/
}
#ifdef EXIF_DEBUG
- php_error(E_NOTICE,"Returning information");
+ php_error(E_NOTICE,"generate section FILE");
#endif
- /*************************************************************************************************/
- /* generic created information must use motorola/intel organisation from the executing processor */
- i = 1;
- ImageInfo.motorola_intel = (*(char*)&i) ? 0 : 1;
- /* no more external processing from here */
- /*************************************************************************************************/
-
/* now we can add our information */
- exif_add_image_info( &ImageInfo, SECTION_FILE, "FileName", TAG_NONE, TAG_FMT_STRING, strlen(ImageInfo.FileName), ImageInfo.FileName);
- exif_add_image_info( &ImageInfo, SECTION_FILE, "FileDateTime", TAG_NONE, TAG_FMT_SLONG, 1, &ImageInfo.FileDateTime);
- exif_add_image_info( &ImageInfo, SECTION_FILE, "FileSize", TAG_NONE, TAG_FMT_SLONG, 1, &ImageInfo.FileSize);
- exif_add_image_info( &ImageInfo, SECTION_FILE, "SectionsFound", TAG_NONE, TAG_FMT_STRING, strlen(sections_str), sections_str);
+ exif_iif_add_tag( &ImageInfo, SECTION_FILE, "FileName", TAG_NONE, TAG_FMT_STRING, strlen(ImageInfo.FileName), ImageInfo.FileName);
+ exif_iif_add_int( &ImageInfo, SECTION_FILE, "FileDateTime", ImageInfo.FileDateTime);
+ exif_iif_add_int( &ImageInfo, SECTION_FILE, "FileSize", ImageInfo.FileSize);
+ exif_iif_add_tag( &ImageInfo, SECTION_FILE, "SectionsFound", TAG_NONE, TAG_FMT_STRING, strlen(sections_str), sections_str);
+
+ #ifdef EXIF_DEBUG
+ php_error(E_NOTICE,"generate section COMPUTED");
+ #endif
if (ImageInfo.Width>0 && ImageInfo.Height>0) {
sprintf(tmp, "width=\"%d\" height=\"%d\"", ImageInfo.Width, ImageInfo.Height);
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "html", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "Height", TAG_NONE, TAG_FMT_SLONG, 1, &ImageInfo.Height);
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "Width", TAG_NONE, TAG_FMT_SLONG, 1, &ImageInfo.Width);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "html", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_int( &ImageInfo, SECTION_COMPUTED, "Height", ImageInfo.Height);
+ exif_iif_add_int( &ImageInfo, SECTION_COMPUTED, "Width", ImageInfo.Width);
}
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "IsColor", TAG_NONE, TAG_FMT_SLONG, 1, &ImageInfo.IsColor);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "IsColor", TAG_NONE, TAG_FMT_SLONG, 1, &ImageInfo.IsColor);
if (ImageInfo.FocalLength) {
sprintf(tmp, "%4.1fmm", ImageInfo.FocalLength);
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "FocalLength", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "FocalLength", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
if(ImageInfo.CCDWidth) {
sprintf(tmp, "%dmm", (int)(ImageInfo.FocalLength/ImageInfo.CCDWidth*35+0.5));
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "35mmFocalLength", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "35mmFocalLength", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
}
}
if(ImageInfo.CCDWidth) {
sprintf(tmp, "%dmm", (int)ImageInfo.CCDWidth);
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "CCDWidth", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "CCDWidth", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
}
if(ImageInfo.ExposureTime>0) {
if(ImageInfo.ExposureTime <= 0.5) {
} else {
sprintf(tmp, "%0.3f s", ImageInfo.ExposureTime);
}
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "ExposureTime", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "ExposureTime", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
}
if(ImageInfo.ApertureFNumber) {
sprintf(tmp, "f/%.1f", ImageInfo.ApertureFNumber);
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "ApertureFNumber", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "ApertureFNumber", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
}
if(ImageInfo.Distance) {
if(ImageInfo.Distance<0) {
} else {
sprintf(tmp, "%0.2fm", ImageInfo.Distance);
}
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "FocusDistance", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "FocusDistance", TAG_NONE, TAG_FMT_STRING, strlen(tmp), tmp);
}
if (ImageInfo.UserComment) {
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "UserComment", TAG_NONE, TAG_FMT_STRING, strlen(ImageInfo.UserComment), ImageInfo.UserComment);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "UserComment", TAG_NONE, TAG_FMT_STRING, strlen(ImageInfo.UserComment), ImageInfo.UserComment);
if ( (len=ImageInfo.UserCommentEncoding[0])) {
- exif_add_image_info( &ImageInfo, SECTION_COMPUTED, "UserCommentEncoding", TAG_NONE, TAG_FMT_STRING, len, ImageInfo.UserCommentEncoding);
+ exif_iif_add_tag( &ImageInfo, SECTION_COMPUTED, "UserCommentEncoding", TAG_NONE, TAG_FMT_STRING, len, ImageInfo.UserCommentEncoding);
}
}
if ( read_thumbnail && ImageInfo.ThumbnailSize) {
- exif_add_image_info( &ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.ThumbnailSize, ImageInfo.Thumbnail);
+ exif_iif_add_tag( &ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.ThumbnailSize, ImageInfo.Thumbnail);
}
efree(sections_str);
if ( !ImageInfo.Thumbnail || !ImageInfo.ThumbnailSize) {
php_exif_discard_imageinfo(&ImageInfo);
- php_error(E_NOTICE,"No thumbnail data found");
RETURN_FALSE;
}
* vim600: sw=4 ts=4 tw=78 fdm=marker
* vim<600: sw=4 ts=4 tw=78
*/
+
\ No newline at end of file