diff options
Diffstat (limited to 'Build/source/texk/dvipdfm-x/src/jpegimage.c')
-rw-r--r-- | Build/source/texk/dvipdfm-x/src/jpegimage.c | 135 |
1 files changed, 132 insertions, 3 deletions
diff --git a/Build/source/texk/dvipdfm-x/src/jpegimage.c b/Build/source/texk/dvipdfm-x/src/jpegimage.c index 368c759aca4..a397a373fb2 100644 --- a/Build/source/texk/dvipdfm-x/src/jpegimage.c +++ b/Build/source/texk/dvipdfm-x/src/jpegimage.c @@ -114,6 +114,7 @@ typedef enum { JM_EXP = 0xdf, JM_APP0 = 0xe0, + JM_APP1 = 0xe1, JM_APP2 = 0xe2, JM_APP14 = 0xee, JM_APP15 = 0xef, @@ -187,6 +188,7 @@ struct JPEG_info #define HAVE_APPn_JFIF (1 << 0) #define HAVE_APPn_ADOBE (1 << 1) #define HAVE_APPn_ICC (1 << 2) +#define HAVE_APPn_Exif (1 << 3) static int JPEG_scan_file (struct JPEG_info *j_info, FILE *fp); static int JPEG_copy_stream (struct JPEG_info *j_info, @@ -342,8 +344,6 @@ jpeg_include_image (pdf_ximage *ximage, FILE *fp) return 0; } -#define IS_JFIF(j) ((j)->flags & HAVE_APPn_JFIF) - static void jpeg_get_density (struct JPEG_info *j_info, double *xdensity, double *ydensity) @@ -355,7 +355,7 @@ jpeg_get_density (struct JPEG_info *j_info, *xdensity = *ydensity = 1.0; - if (IS_JFIF(j_info)) { + if (j_info->flags & HAVE_APPn_JFIF) { struct JPEG_APPn_JFIF *app_data; int i; for (i = 0; i < j_info->num_appn; i++) { @@ -539,6 +539,135 @@ read_APP14_Adobe (struct JPEG_info *j_info, FILE *fp, unsigned short length) return 7; } +#ifdef XETEX +static unsigned long +read_exif_bytes(unsigned char **p, int n, int b) +{ + unsigned long rval = 0; + unsigned char *pp = *p; + if (b) { + switch (n) { + case 4: + rval += *pp++; rval <<= 8; + rval += *pp++; rval <<= 8; + case 2: + rval += *pp++; rval <<= 8; + rval += *pp; + break; + } + } + else { + pp += n; + switch (n) { + case 4: + rval += *--pp; rval <<= 8; + rval += *--pp; rval <<= 8; + case 2: + rval += *--pp; rval <<= 8; + rval += *--pp; + break; + } + } + *p += n; + return rval; +} + +static unsigned short +read_APP1_Exif (struct JPEG_info *j_info, FILE *fp, unsigned short length) +{ + /* this doesn't save the data, just reads the tags we need */ + /* based on info from http://www.exif.org/Exif2-2.PDF */ + unsigned char *buffer = NEW(length, unsigned char); + unsigned char *p, *rp; + unsigned char *tiff_header; + char bigendian; + int i; + int num_fields, tag, type; + int value = 0, num = 0, den = 0; /* silence uninitialized warnings */ + double xres = 72.0; + double yres = 72.0; + double res_unit = 1.0; + fread(buffer, length, 1, fp); + p = buffer; + while ((p < buffer + length) && (*p == 0)) + ++p; + tiff_header = p; + if ((*p == 'M') && (*(p+1) == 'M')) + bigendian = 1; + else if ((*p == 'I') && (*(p+1) == 'I')) + bigendian = 0; + else + goto err; + p += 2; + i = read_exif_bytes(&p, 2, bigendian); + if (i != 42) + goto err; + i = read_exif_bytes(&p, 4, bigendian); + p = tiff_header + i; + num_fields = read_exif_bytes(&p, 2, bigendian); + while (num_fields-- > 0) { + tag = read_exif_bytes(&p, 2, bigendian); + type = read_exif_bytes(&p, 2, bigendian); + read_exif_bytes(&p, 4, bigendian); + switch (type) { + case 1: /* byte */ + value = *p++; + p += 3; + break; + case 3: /* short */ + value = read_exif_bytes(&p, 2, bigendian); + p += 2; + break; + case 4: /* long */ + case 9: /* slong */ + value = read_exif_bytes(&p, 4, bigendian); + break; + case 5: /* rational */ + case 10: /* srational */ + value = read_exif_bytes(&p, 4, bigendian); + rp = tiff_header + value; + num = read_exif_bytes(&rp, 4, bigendian); + den = read_exif_bytes(&rp, 4, bigendian); + break; + case 7: /* undefined */ + value = *p++; + p += 3; + break; + case 2: /* ascii */ + default: + p += 4; + break; + } + switch (tag) { + case 282: /* x res */ + if (den != 0) + xres = num / den; + break; + case 283: /* y res */ + if (den != 0) + yres = num / den; + break; + case 296: /* res unit */ + switch (value) { + case 2: + res_unit = 1.0; + break; + case 3: + res_unit = 2.54; + break; + } + } + } + + j_info->xdpi = xres * res_unit; + j_info->ydpi = yres * res_unit; + +err: + RELEASE(buffer); + return length; +} +#endif + static unsigned short read_APP0_JFIF (struct JPEG_info *j_info, FILE *fp, unsigned short length) { |