w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

jpegimage.c
Go to the documentation of this file.
1 /****************************************************************************\
2  Part of the XeTeX typesetting system
3  Copyright (c) 1994-2017 by SIL International
4 
5  SIL Author(s): Jonathan Kew
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 \****************************************************************************/
21 
22 /* this file is derived from the dvipdfmx project;
23  the original header follows... */
24 
25 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
26 
27  Copyright (C) 2002-2017 by Jin-Hwan Cho and Shunsaku Hirata,
28  the dvipdfmx project team.
29 
30  Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
31 
32  This program is free software; you can redistribute it and/or modify
33  it under the terms of the GNU General Public License as published by
34  the Free Software Foundation; either version 2 of the License, or
35  (at your option) any later version.
36 
37  This program is distributed in the hope that it will be useful,
38  but WITHOUT ANY WARRANTY; without even the implied warranty of
39  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40  GNU General Public License for more details.
41 
42  You should have received a copy of the GNU General Public License
43  along with this program; if not, write to the Free Software
44  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
45 */
46 
47 /*
48  * JPEG SUPPORT
49  *
50  * Accroding to Libjpeg document:
51  *
52  * CAUTION: it appears that Adobe Photoshop writes inverted data in CMYK
53  * JPEG files: 0 represents 100% ink coverage, rather than 0% ink as you'd
54  * expect....
55  *
56  * To wrok with this problem, we must detect whether CMYK JPEG file is
57  * created by Photoshop. But there are no reliable way to determine this.
58  *
59  * According to Adobe Technical Note #5516,
60  * "Supporting the DCT Filters in PostScript Level 2", Section 18, p.27.
61  *
62  * DCTDecode ignores and skips any APPE marker segment does not begin with
63  * the `Adobe' 5-character string.
64  *
65  * PDF Reference Manual 4th ed., p.61-62.
66  *
67  * The JPEG filter implementation in Adobe Acrobat products does not
68  * support features of the JPEG standard that are irrelevant to images.
69  * In addition, certain choices have been made regarding reserved marker
70  * codes and other optional features of the standard. For details, see
71  * Adobe Technical Note #5116, Supporting the DCT Filters in PostScript
72  * Level 2.
73  */
74 
75 #if HAVE_CONFIG_H
76 #include <w2c/config.h>
77 #endif
78 
79 #include "mfileio.h"
80 #include "numbers.h"
81 #include "jpegimage.h"
82 
83 #define JPEG_DEBUG_STR "JPEG"
84 #define JPEG_DEBUG 3
85 
86 #define HAVE_APPn_JFIF (1 << 0)
87 #define HAVE_APPn_ADOBE (1 << 1)
88 #define HAVE_APPn_ICC (1 << 2)
89 #define HAVE_APPn_Exif (1 << 3)
90 
91 #define RELEASE(p) free(p)
92 #define NEW(n, t) (t*)xmalloc(n * sizeof(t))
93 #define RENEW(p, n, t) ((p) ? (t*)xrealloc(p, (n) * sizeof(t)) : NEW(n, t))
94 
95 int
97 {
98  unsigned char jpeg_sig[2];
99 
100  rewind(fp);
101  if (fread(jpeg_sig, sizeof(unsigned char), 2, fp) != 2)
102  return 0;
103  else if (jpeg_sig[0] != 0xff || jpeg_sig[1] != JM_SOI)
104  return 0;
105 
106  return 1;
107 }
108 
109 static void
110 JPEG_info_init (struct JPEG_info *j_info)
111 {
112  j_info->width = 0;
113  j_info->height = 0;
114  j_info->bits_per_component = 0;
115  j_info->num_components = 0;
116 
117  j_info->xdpi = 0.0;
118  j_info->ydpi = 0.0;
119 
120  j_info->flags = 0;
121  j_info->num_appn = 0;
122  j_info->max_appn = 0;
123  j_info->appn = NULL;
124 
125  memset(j_info->skipbits, 0, MAX_COUNT / 8 + 1);
126 }
127 
128 static JPEG_marker
130 {
131  int c;
132 
133  c = fgetc(fp);
134  if (c != 255)
135  return -1;
136 
137  for (;;) {
138  c = fgetc(fp);
139  if (c < 0)
140  return -1;
141  else if (c > 0 && c < 255) {
142  return c;
143  }
144  }
145 
146  return -1;
147 }
148 
149 static int
150 add_APPn_marker (struct JPEG_info *j_info,
151  JPEG_marker marker, int app_sig, void *app_data)
152 {
153  int n;
154 
155  if (j_info->num_appn >= j_info->max_appn) {
156  j_info->max_appn += 16;
157  j_info->appn = RENEW(j_info->appn, j_info->max_appn, struct JPEG_ext);
158  }
159  n = j_info->num_appn;
160 
161  j_info->appn[n].marker = marker;
162  j_info->appn[n].app_sig = app_sig;
163  j_info->appn[n].app_data = app_data;
164 
165  j_info->num_appn += 1;
166 
167  return n;
168 }
169 
170 static unsigned short
171 read_APP14_Adobe (struct JPEG_info *j_info, FILE *fp)
172 {
173  struct JPEG_APPn_Adobe *app_data;
174 
175  app_data = NEW(1, struct JPEG_APPn_Adobe);
176  app_data->version = get_unsigned_pair(fp);
177  app_data->flag0 = get_unsigned_pair(fp);
178  app_data->flag1 = get_unsigned_pair(fp);
179  app_data->transform = get_unsigned_byte(fp);
180 
181  add_APPn_marker(j_info, JM_APP14, JS_APPn_ADOBE, app_data);
182 
183  return 7;
184 }
185 
186 static unsigned int
187 read_exif_bytes(unsigned char **p, int n, int b)
188 {
189  unsigned int rval = 0;
190  unsigned char *pp = *p;
191  if (b) {
192  switch (n) {
193  case 4:
194  rval += *pp++; rval <<= 8;
195  rval += *pp++; rval <<= 8;
196  case 2:
197  rval += *pp++; rval <<= 8;
198  rval += *pp;
199  break;
200  }
201  }
202  else {
203  pp += n;
204  switch (n) {
205  case 4:
206  rval += *--pp; rval <<= 8;
207  rval += *--pp; rval <<= 8;
208  case 2:
209  rval += *--pp; rval <<= 8;
210  rval += *--pp;
211  break;
212  }
213  }
214  *p += n;
215  return rval;
216 }
217 
218 static unsigned short
219 read_APP1_Exif (struct JPEG_info *j_info, FILE *fp, unsigned short length)
220 {
221  /* this doesn't save the data, just reads the tags we need */
222  /* based on info from http://www.exif.org/Exif2-2.PDF */
223  unsigned char *buffer = NEW(length, unsigned char);
224  unsigned char *p, *rp;
225  unsigned char *tiff_header;
226  char bigendian;
227  int i;
228  int num_fields, tag, type;
229  int value = 0, num = 0, den = 0; /* silence uninitialized warnings */
230  double xres = 72.0;
231  double yres = 72.0;
232  double res_unit = 1.0;
233  fread(buffer, length, 1, fp);
234  p = buffer;
235  while ((p < buffer + length) && (*p == 0))
236  ++p;
237  tiff_header = p;
238  if ((*p == 'M') && (*(p+1) == 'M'))
239  bigendian = 1;
240  else if ((*p == 'I') && (*(p+1) == 'I'))
241  bigendian = 0;
242  else
243  goto err;
244  p += 2;
245  i = read_exif_bytes(&p, 2, bigendian);
246  if (i != 42)
247  goto err;
248  i = read_exif_bytes(&p, 4, bigendian);
249  p = tiff_header + i;
250  num_fields = read_exif_bytes(&p, 2, bigendian);
251  while (num_fields-- > 0) {
252  tag = read_exif_bytes(&p, 2, bigendian);
253  type = read_exif_bytes(&p, 2, bigendian);
254  (void)read_exif_bytes(&p, 4, bigendian);
255  switch (type) {
256  case 1: /* byte */
257  value = *p++;
258  p += 3;
259  break;
260  case 3: /* short */
261  value = read_exif_bytes(&p, 2, bigendian);
262  p += 2;
263  break;
264  case 4: /* long */
265  case 9: /* slong */
266  value = read_exif_bytes(&p, 4, bigendian);
267  break;
268  case 5: /* rational */
269  case 10: /* srational */
270  value = read_exif_bytes(&p, 4, bigendian);
271  rp = tiff_header + value;
272  num = read_exif_bytes(&rp, 4, bigendian);
273  den = read_exif_bytes(&rp, 4, bigendian);
274  break;
275  case 7: /* undefined */
276  value = *p++;
277  p += 3;
278  break;
279  case 2: /* ascii */
280  default:
281  p += 4;
282  break;
283  }
284  switch (tag) {
285  case 282: /* x res */
286  if (den != 0)
287  xres = num / den;
288  break;
289  case 283: /* y res */
290  if (den != 0)
291  yres = num / den;
292  break;
293  case 296: /* res unit */
294  switch (value) {
295  case 2:
296  res_unit = 1.0;
297  break;
298  case 3:
299  res_unit = 2.54;
300  break;
301  }
302  }
303  }
304 /*
305  Do not overwrite if j_info->xdpi and j_info->ydpi are
306  already determined as JFIF
307 */
308  if (j_info->xdpi < 0.1 && j_info->ydpi < 0.1) {
309  j_info->xdpi = xres * res_unit;
310  j_info->ydpi = yres * res_unit;
311  }
312 
313 err:
314  RELEASE(buffer);
315  return length;
316 }
317 
318 static unsigned short
319 read_APP0_JFIF (struct JPEG_info *j_info, FILE *fp)
320 {
321  struct JPEG_APPn_JFIF *app_data;
322  unsigned short thumb_data_len;
323 
324  app_data = NEW(1, struct JPEG_APPn_JFIF);
325  app_data->version = get_unsigned_pair(fp);
326  app_data->units = get_unsigned_byte(fp);
327  app_data->Xdensity = get_unsigned_pair(fp);
328  app_data->Ydensity = get_unsigned_pair(fp);
329  app_data->Xthumbnail = get_unsigned_byte(fp);
330  app_data->Ythumbnail = get_unsigned_byte(fp);
331  thumb_data_len = 3 * app_data->Xthumbnail * app_data->Ythumbnail;
332  if (thumb_data_len > 0) {
333  app_data->thumbnail = NEW(thumb_data_len, unsigned char);
334  fread(app_data->thumbnail, 1, thumb_data_len, fp);
335  } else {
336  app_data->thumbnail = NULL;
337  }
338 
339  add_APPn_marker(j_info, JM_APP0, JS_APPn_JFIF, app_data);
340 
341  switch (app_data->units) {
342  case 1:
343  j_info->xdpi = app_data->Xdensity;
344  j_info->ydpi = app_data->Ydensity;
345  break;
346  case 2: /* density is in pixels per cm */
347  j_info->xdpi = app_data->Xdensity * 2.54;
348  j_info->ydpi = app_data->Ydensity * 2.54;
349  break;
350  default: /* FIXME: not sure what to do with this.... */
351  j_info->xdpi = 72.0;
352  j_info->ydpi = 72.0;
353  break;
354  }
355 
356  return (9 + thumb_data_len);
357 }
358 
359 static unsigned short
360 read_APP0_JFXX (FILE *fp, unsigned short length)
361 {
363  /* Extension Code:
364  *
365  * 0x10: Thumbnail coded using JPEG
366  * 0x11: Thumbnail stored using 1 byte/pixel
367  * 0x13: Thumbnail stored using 3 bytes/pixel
368  */
369  seek_relative(fp, length-1); /* Thunbnail image */
370 
371  /* Ignore */
372 
373  return length;
374 }
375 
376 static unsigned short
377 read_APP2_ICC (struct JPEG_info *j_info, FILE *fp, unsigned short length)
378 {
379  struct JPEG_APPn_ICC *app_data;
380 
381  app_data = NEW(1, struct JPEG_APPn_ICC);
382  app_data->seq_id = get_unsigned_byte(fp); /* Starting at 1 */
383  app_data->num_chunks = get_unsigned_byte(fp);
384  app_data->length = length - 2;
385  app_data->chunk = NEW(app_data->length, unsigned char);
386  fread(app_data->chunk, 1, app_data->length, fp);
387 
388  add_APPn_marker(j_info, JM_APP2, JS_APPn_ICC, app_data);
389 
390  return length;
391 }
392 
393 int
394 JPEG_scan_file (struct JPEG_info *j_info, FILE *fp)
395 {
396  JPEG_marker marker;
397  unsigned short length;
398  int found_SOFn, count;
399  char app_sig[128];
400 
401  JPEG_info_init(j_info);
402 
403  rewind(fp);
404  count = 0;
405  found_SOFn = 0;
406  while (!found_SOFn &&
407  (marker = JPEG_get_marker(fp)) != (JPEG_marker) -1) {
408  if (marker == JM_SOI ||
409  (marker >= JM_RST0 && marker <= JM_RST7)) {
410  count++;
411  continue;
412  }
413  length = get_unsigned_pair(fp) - 2;
414  switch (marker) {
415  case JM_SOF0: case JM_SOF1: case JM_SOF2: case JM_SOF3:
416  case JM_SOF5: case JM_SOF6: case JM_SOF7: case JM_SOF9:
417  case JM_SOF10: case JM_SOF11: case JM_SOF13: case JM_SOF14:
418  case JM_SOF15:
420  j_info->height = get_unsigned_pair(fp);
421  j_info->width = get_unsigned_pair(fp);
423  found_SOFn = 1;
424  break;
425  case JM_APP0:
426  if (length > 5) {
427  if (fread(app_sig, sizeof(char), 5, fp) != 5)
428  return -1;
429  length -= 5;
430  if (!memcmp(app_sig, "JFIF\000", 5)) {
431  j_info->flags |= HAVE_APPn_JFIF;
432  length -= read_APP0_JFIF(j_info, fp);
433  } else if (!memcmp(app_sig, "JFXX", 5)) {
435  }
436  }
438  break;
439  case JM_APP1:
440  if (length > 5) {
441  if (fread(app_sig, sizeof(char), 5, fp) != 5)
442  return -1;
443  length -= 5;
444  if (!memcmp(app_sig, "Exif\000", 5)) {
445  j_info->flags |= HAVE_APPn_Exif;
446  length -= read_APP1_Exif(j_info, fp, length);
447  }
448  }
450  break;
451  case JM_APP2:
452  if (length >= 14) {
453  if (fread(app_sig, sizeof(char), 12, fp) != 12)
454  return -1;
455  length -= 12;
456  if (!memcmp(app_sig, "ICC_PROFILE\000", 12)) {
457  j_info->flags |= HAVE_APPn_ICC;
458  length -= read_APP2_ICC(j_info, fp, length);
459  if (count < MAX_COUNT) {
460  j_info->skipbits[count / 8] |= (1 << (7 - (count % 8)));
461  }
462  }
463  }
465  break;
466  case JM_APP14:
467  if (length > 5) {
468  if (fread(app_sig, sizeof(char), 5, fp) != 5)
469  return -1;
470  length -= 5;
471  if (!memcmp(app_sig, "Adobe", 5)) {
472  j_info->flags |= HAVE_APPn_ADOBE;
473  length -= read_APP14_Adobe(j_info, fp);
474  } else {
475  if (count < MAX_COUNT) {
476  j_info->skipbits[count/8] |= (1 << (7 - (count % 8)));
477  }
478  }
479  }
481  break;
482  default:
484  if (marker >= JM_APP0 &&
485  marker <= JM_APP15) {
486  if (count < MAX_COUNT) {
487  j_info->skipbits[count / 8] |= (1 << (7 - (count % 8)));
488  }
489  }
490  break;
491  }
492  count++;
493  }
494 
495 /*
496  * If j_info->xdpi, and j_info->ydpi are not yet determined,
497  * they are assumed to be 72.0 to avoid division by zero.
498  */
499  if (j_info->xdpi < 0.1 && j_info->ydpi < 0.1) {
500  j_info->xdpi = j_info->ydpi = 72.0;
501  }
502 
503  return (found_SOFn ? 0 : -1);
504 }
rp
Definition: action.c:992
#define type(a)
Definition: aptex-macros.h:171
#define count(a)
Definition: aptex-macros.h:781
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
#define fread
Definition: xxstdio.h:25
#define fgetc
Definition: xxstdio.h:26
static void
Definition: fpif.c:118
FieldLoc_T num_fields
mpz_t pp
Definition: gen-psqr.c:108
#define c(n)
Definition: gpos-common.c:150
#define memcmp(s1, s2, n)
Definition: gsftopk.c:66
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
int den
Definition: dvi.c:19
int num
Definition: disdvi.c:621
@ JS_APPn_ADOBE
Definition: jpegimage.c:125
@ JS_APPn_ICC
Definition: jpegimage.c:126
@ JS_APPn_JFIF
Definition: jpegimage.c:124
int check_for_jpeg(FILE *fp)
Definition: jpegimage.c:214
JPEG_marker
Definition: jpegimage.c:79
@ JM_SOF15
Definition: jpegimage.c:94
@ JM_APP14
Definition: jpegimage.c:117
@ JM_RST7
Definition: jpegimage.c:103
@ JM_SOF6
Definition: jpegimage.c:86
@ JM_SOF10
Definition: jpegimage.c:89
@ JM_SOF9
Definition: jpegimage.c:88
@ JM_SOF7
Definition: jpegimage.c:87
@ JM_SOF0
Definition: jpegimage.c:80
@ JM_APP15
Definition: jpegimage.c:118
@ JM_SOF11
Definition: jpegimage.c:90
@ JM_SOF1
Definition: jpegimage.c:81
@ JM_SOF2
Definition: jpegimage.c:82
@ JM_APP0
Definition: jpegimage.c:114
@ JM_APP1
Definition: jpegimage.c:115
@ JM_SOF14
Definition: jpegimage.c:93
@ JM_SOF3
Definition: jpegimage.c:83
@ JM_SOI
Definition: jpegimage.c:105
@ JM_SOF13
Definition: jpegimage.c:92
@ JM_APP2
Definition: jpegimage.c:116
@ JM_RST0
Definition: jpegimage.c:96
@ JM_SOF5
Definition: jpegimage.c:84
#define MAX_COUNT
Definition: jpegimage.c:177
void seek_relative(FILE *file, int32_t pos)
Definition: mfileio.c:85
unsigned char get_unsigned_byte(FILE *file)
Definition: numbers.c:32
unsigned short get_unsigned_pair(FILE *file)
Definition: numbers.c:55
#define length(c)
Definition: ctangleboot.c:65
@ err
Definition: mtxline.h:24
union value value
Definition: obx.h:44
static int xres
Definition: pbmto4425.c:21
static int yres
Definition: pbmto4425.c:22
#define fp
bstring c int memset(void *s, int c, int length)
static unsigned short read_APP14_Adobe(struct JPEG_info *j_info, FILE *fp)
Definition: jpegimage.c:171
static unsigned short read_APP0_JFIF(struct JPEG_info *j_info, FILE *fp)
Definition: jpegimage.c:319
static void JPEG_info_init(struct JPEG_info *j_info)
Definition: jpegimage.c:110
static unsigned short read_APP2_ICC(struct JPEG_info *j_info, FILE *fp, unsigned short length)
Definition: jpegimage.c:377
#define NEW(n, t)
Definition: jpegimage.c:92
#define HAVE_APPn_ICC
Definition: jpegimage.c:88
#define RENEW(p, n, t)
Definition: jpegimage.c:93
static unsigned int read_exif_bytes(unsigned char **p, int n, int b)
Definition: jpegimage.c:187
#define HAVE_APPn_ADOBE
Definition: jpegimage.c:87
static JPEG_marker JPEG_get_marker(FILE *fp)
Definition: jpegimage.c:129
#define HAVE_APPn_Exif
Definition: jpegimage.c:89
static unsigned short read_APP1_Exif(struct JPEG_info *j_info, FILE *fp, unsigned short length)
Definition: jpegimage.c:219
int JPEG_scan_file(struct JPEG_info *j_info, FILE *fp)
Definition: jpegimage.c:394
#define RELEASE(p)
Definition: jpegimage.c:91
#define HAVE_APPn_JFIF
Definition: jpegimage.c:86
static int add_APPn_marker(struct JPEG_info *j_info, JPEG_marker marker, int app_sig, void *app_data)
Definition: jpegimage.c:150
static unsigned short read_APP0_JFXX(FILE *fp, unsigned short length)
Definition: jpegimage.c:360
uint16_t version
Definition: jpegimage.c:156
uint16_t flag0
Definition: jpegimage.c:157
uint8_t transform
Definition: jpegimage.c:159
uint16_t flag1
Definition: jpegimage.c:158
size_t length
Definition: jpegimage.c:151
unsigned char * chunk
Definition: jpegimage.c:148
uint8_t num_chunks
Definition: jpegimage.c:147
uint8_t seq_id
Definition: jpegimage.c:146
uint16_t Xdensity
Definition: jpegimage.c:137
uint8_t Xthumbnail
Definition: jpegimage.c:139
uint8_t Ythumbnail
Definition: jpegimage.c:140
uint16_t Ydensity
Definition: jpegimage.c:138
unsigned char * thumbnail
Definition: jpegimage.c:141
uint16_t version
Definition: jpegimage.c:132
uint8_t units
Definition: jpegimage.c:133
JPEG_marker marker
Definition: jpegimage.c:172
void * app_data
Definition: jpegimage.c:174
JPEG_APPn_sig app_sig
Definition: jpegimage.c:173
int max_appn
Definition: jpegimage.c:191
double ydpi
Definition: jpegimage.c:187
uint8_t num_components
Definition: jpegimage.c:184
int num_appn
Definition: jpegimage.c:191
uint8_t bits_per_component
Definition: jpegimage.c:183
struct JPEG_ext * appn
Definition: jpegimage.c:192
uint16_t width
Definition: jpegimage.c:181
uint16_t height
Definition: jpegimage.c:180
char skipbits[1024/8+1]
Definition: jpegimage.c:195
double xdpi
Definition: jpegimage.c:186
int flags
Definition: jpegimage.c:190
Definition: utils.c:300
Definition: xmlparse.c:179
#define FILE
Definition: t1stdio.h:34
tag int tag
Definition: tex4ht.c:2554
Definition: obx.h:51
#define buffer
Definition: xmlparse.c:611