summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/src/jpegimage.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/src/jpegimage.c')
-rw-r--r--Build/source/texk/dvipdfm-x/src/jpegimage.c135
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)
{