#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "exif.h" #include "jpeg.h" static char error[256]; struct exiftags *et = NULL; struct exifprop *ep = NULL; unsigned short dumplvl = 0; static int read_data(char *fname) { static char _file_name[1024] = ""; int mark, first = 0; unsigned int len, rlen; unsigned char *exifbuf = NULL; FILE *fpn; char *mode; #ifdef WIN32 mode = "rb"; #else mode = "r"; #endif if(strcmp(fname, _file_name)){ fpn = fopen(fname, mode); if (fpn) strcpy(_file_name, fname); else _file_name[0] = '\0'; } else { return 0; } if (fpn == NULL){ exifdie((const char *)strerror(errno)); return 2; } while (jpegscan(fpn, &mark, &len, !(first++))) { if (mark != JPEG_M_APP1) { if (fseek(fpn, len, SEEK_CUR)){ exifdie((const char *)strerror(errno)); free (exifbuf); fclose (fpn); return 2; } continue; } exifbuf = (unsigned char *)malloc(len); if (!exifbuf){ exifdie((const char *)strerror(errno)); free (exifbuf); fclose (fpn); return 2; } rlen = fread(exifbuf, 1, len, fpn); if (rlen != len) { exifwarn("error reading JPEG (length mismatch)"); free(exifbuf); fclose (fpn); return (1); } et = exifparse(exifbuf, len); if (et && et->props){ break; } else { exifwarn("couldn't find Exif data"); free (exifbuf); fclose (fpn); return (1); } } free (exifbuf); fclose (fpn); return (0); } static long get_props(char *field, char *value) { int pas = TRUE; if (ep && dumplvl) { /* Take care of point-and-shoot values. */ if (ep->lvl == ED_PAS) ep->lvl = pas ? ED_CAM : ED_IMG; /* For now, just treat overridden & bad values as verbose. */ if (ep->lvl == ED_OVR || ep->lvl == ED_BAD) ep->lvl = ED_VRB; if (ep->lvl == dumplvl) { strcpy(field, ep->descr ? ep->descr : ep->name); if (!ep->str) sprintf(value, "%d", ep->value); else strcpy(value, ep->str); } ep = ep->next; } return (long)ep; } static int close_application() { if (et) { exiffree(et); et = NULL; } } static int not_here(char *s) { croak("%s not implemented on this architecture", s); return -1; } static double constant(char *name, int len, int arg) { errno = EINVAL; return 0; } MODULE = Image::EXIF PACKAGE = Image::EXIF double constant(sv,arg) PREINIT: STRLEN len; INPUT: SV * sv char * s = SvPV(sv, len); int arg CODE: RETVAL = constant(s,len,arg); OUTPUT: RETVAL int c_read_file(fname) char *fname CODE: error[0] = '\0'; RETVAL = 0; RETVAL = read_data(fname); OUTPUT: RETVAL int c_get_camera_info() CODE: dumplvl = ED_CAM; if (et) ep = et->props; int c_get_image_info() CODE: dumplvl = ED_IMG; if (et) ep = et->props; int c_get_other_info() CODE: dumplvl = ED_VRB; if (et) ep = et->props; int c_get_unknown_info() CODE: dumplvl = ED_UNK; if (et) ep = et->props; int c_fetch() PPCODE: char field[256] = ""; char value[256] = ""; int rc = get_props(field, value); if (rc){ EXTEND(sp, 2); PUSHs(sv_2mortal(newSVpv((char*)field, 0))); PUSHs(sv_2mortal(newSVpv((char*)value, 0))); } int c_errstr() PPCODE: if (strlen(error)){ EXTEND(sp, 1); PUSHs(sv_2mortal(newSVpv((char*)error, 0))); } int c_close_all() PPCODE: close_application();