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)  

psio.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  - This software is distributed in the hope that it will be
4  - useful, but with NO WARRANTY OF ANY KIND.
5  - No author or distributor accepts responsibility to anyone for the
6  - consequences of using this software, or for whether it serves any
7  - particular purpose or works at all, unless he or she says so in
8  - writing. Everyone is granted permission to copy, modify and
9  - redistribute this source code, for commercial or non-commercial
10  - purposes, with the following restrictions: (1) the origin of this
11  - source code must not be misrepresented; (2) modified versions must
12  - be plainly marked as such; and (3) this notice may not be removed
13  - or altered from any source or modified source distribution.
14  *====================================================================*/
15 
16 /*
17  * psio.c
18  *
19  * This is a PostScript "device driver" for wrapping images
20  * in PostScript. The images can be rendered by a PostScript
21  * interpreter, such as gs or the embedded interpreter in a
22  * PostScript printer.
23  *
24  * Convert any image file to PS for embedding
25  * l_int32 convertToPSEmbed()
26  *
27  * For uncompressed images
28  *
29  * l_int32 pixWritePSEmbed()
30  *
31  * l_int32 pixWriteStreamPS()
32  * char *pixWriteStringPS()
33  *
34  * void getScaledParametersPS()
35  * l_int32 convertByteToHexAscii()
36  *
37  * For jpeg compressed images
38  *
39  * l_int32 convertJpegToPSEmbed()
40  *
41  * l_int32 convertJpegToPS()
42  * l_int32 convertJpegToPSString()
43  * l_int32 extractJpegDataFromFile()
44  * l_int32 extractJpegDataFromArray()
45  *
46  * static l_int32 locateJpegImageParameters()
47  * static l_int32 getNextJpegMarker()
48  * static l_int32 getTwoByteParameter()
49  *
50  * For tiff g4 compressed images
51  *
52  * l_int32 convertTiffG4ToPSEmbed()
53  *
54  * l_int32 convertTiffG4ToPS()
55  * l_int32 convertTiffG4ToPSString()
56  * l_int32 extractTiffG4DataFromFile()
57  *
58  * For multipage tiff images
59  *
60  * l_int32 convertTiffMultipageToPS()
61  *
62  * Converting resolution
63  * l_int32 getResLetterPage()
64  * l_int32 getResA4Page()
65  *
66  * Utility for encoding and decoding data with ascii85
67  *
68  * char *encodeAscii85()
69  * l_int32 *convertChunkToAscii85()
70  * l_uint8 *decodeAscii85()
71  *
72  * These PostScript converters are used in three different ways:
73  *
74  * (1) For embedding a PS file in a program like TeX. We must have
75  * a bounding box. convertToPSEmbed() handles this for
76  * both level 1 and level 2 output, and prog/converttops
77  * wraps this in an executable. converttops is a generalization
78  * of Thomas Merz's jpeg2ps wrapper, in that it works for
79  * all types (formats, depth, colormap) of input images and
80  * gives PS output in either compressed or uncompressed format,
81  * depending on an input flag.
82  *
83  * (2) For composing a set of pages with any number of images
84  * painted on them, in DCT or G4 compressed format depending
85  * on if the image is grayscale/color or binary. Because we
86  * append each PS string and specify the scaling and placement
87  * explicitly, one must NOT have a bounding box attached to
88  * each separate image.
89  *
90  * (3) For printing a page image or a set of page images, at a
91  * resolution that optimally fills the page. Here we use
92  * a bounding box and scale the image appropriately.
93  */
94 
95 #include <stdio.h>
96 #include <stdlib.h>
97 #include <string.h>
98 
99 #include "allheaders.h"
100 
101 static const char *TEMP_G4TIFF_FILE = "/usr/tmp/junk_temp_g4tiff.tif";
102 static const char *TEMP_JPEG_FILE = "/usr/tmp/junk_temp_jpeg.jpg";
103 
104 static const l_int32 BUF_SIZE = 512;
105 static const l_int32 DEFAULT_PRINTER_RES = 300; /* default printing ppi */
106 static const l_int32 MIN_RES = 5;
107 static const l_int32 MAX_RES = 3000;
108 static const l_int32 MAX_85_LINE_COUNT = 64;
109 
110  /* for computing resolution that fills page to desired amount */
111 static const l_int32 LETTER_WIDTH = 612; /* points */
112 static const l_int32 LETTER_HEIGHT = 792; /* points */
113 static const l_int32 A4_WIDTH = 595; /* points */
114 static const l_int32 A4_HEIGHT = 842; /* points */
115 static const l_float32 DEFAULT_FILL_FRACTION = 0.95;
116 
117 static const l_uint32 power85[5] = {1,
118  85,
119  85 * 85,
120  85 * 85 * 85,
121  85 * 85 * 85 * 85};
122 
126 
127 
128 #ifndef NO_CONSOLE_IO
129 #define DEBUG_JPEG 0
130 #define DEBUG_G4 0
131 #endif /* ~NO_CONSOLE_IO */
132 
133  /* This should be false for documents that are composited from
134  * sequences of painted images, where more than one image can
135  * be placed in an arbitrary location on any page.
136  * However, for images that are composited, we use special *Embed()
137  * functions for writing PostScript with bounding boxes, so they
138  * can be embedded in TeX files, e.g. */
139 #define PRINT_BOUNDING_BOX 0
140 
141 
142 
143 /*-------------------------------------------------------------*
144  * Convert any image file to PS for embedding *
145  *-------------------------------------------------------------*/
146 /*
147  * convertToPSEmbed()
148  *
149  * Input: filein (input file)
150  * fileout (output ps file)
151  * level (1 - uncompressed, 2 - compressed)
152  * Return: 0 if OK, 1 on error
153  *
154  * Notes:
155  * (1) This is a wrapper function that generates a PS file with
156  * a bounding box, from any input image file.
157  * (2) Colormaps are removed.
158  * (3) If the image is not 1 bpp and is not jpeg compressed,
159  * and it is to be written as PS with DCT compression
160  * (level = 2), it will first be written to file as jpeg with
161  * quality = 75. This will cause some degradation in the image.
162  * (4) The bounding box is required when a program such as TeX
163  * (through epsf) places and rescales the image.
164  * (5) The bounding box is sized for fitting the image to an
165  * 8.5 x 11.0 inch page.
166  */
167 l_int32
168 convertToPSEmbed(const char *filein,
169  const char *fileout,
170  l_int32 level)
171 {
172 l_int32 d, format;
173 FILE *fp;
174 PIX *pix, *pixs;
175 
176  PROCNAME("convertToPSEmbed");
177 
178  if (!filein)
179  return ERROR_INT("filein not defined", procName, 1);
180  if (!fileout)
181  return ERROR_INT("fileout not defined", procName, 1);
182 
183  if (level == 1) {
184  pixWritePSEmbed(filein, fileout);
185  return 0;
186  }
187 
188  /* We must write out level 2 PS */
189  if ((fp = fopen(filein, "rb")) == NULL)
190  return ERROR_INT("filein not found", procName, 1);
192  fclose(fp);
193  if (format == IFF_JFIF_JPEG) { /* write out directly */
194  convertJpegToPSEmbed(filein, fileout);
195  return 0;
196  }
197 
198  /* We need to convert to jpeg or tiff g4.
199  * If it's already in tiff g4 format, we take the hit of
200  * reading it in and writing it back out the same way. */
201  if ((pixs = pixRead(filein)) == NULL)
202  return ERROR_INT("image not read from file", procName, 1);
203  d = pixGetDepth(pixs);
204  if (d == 16)
205  pix = pixConvert16To8(pixs, 1);
206  else
208  d = pixGetDepth(pix);
209  if (d == 1) {
212  }
213  else {
216  }
217 
218  pixDestroy(&pix);
219  pixDestroy(&pixs);
220  return 0;
221 }
222 
223 
224 
225 /*-------------------------------------------------------------*
226  * For uncompressed images *
227  *-------------------------------------------------------------*/
228 /*!
229  * pixWritePSEmbed()
230  *
231  * Input: filein (input file)
232  * fileout (output ps file)
233  * Return: 0 if OK, 1 on error
234  *
235  * Notes:
236  * (1) This is a simple wrapper function that generates an
237  * uncompressed PS file, with a bounding box.
238  * (2) The bounding box is required when a program such as TeX
239  * (through epsf) places and rescales the image.
240  * (3) The bounding box is sized for fitting the image to an
241  * 8.5 x 11.0 inch page.
242  */
243 l_int32
244 pixWritePSEmbed(const char *filein,
245  const char *fileout)
246 {
247 l_int32 w, h;
249 FILE *fp;
250 PIX *pix;
251 
252  PROCNAME("pixWritePSEmbed");
253 
254  if (!filein)
255  return ERROR_INT("filein not defined", procName, 1);
256  if (!fileout)
257  return ERROR_INT("fileout not defined", procName, 1);
258 
259  if ((pix = pixRead(filein)) == NULL)
260  return ERROR_INT("image not read from file", procName, 1);
261  w = pixGetWidth(pix);
262  h = pixGetHeight(pix);
263  if (w * 11.0 > h * 8.5)
264  scale = 8.5 * 300. / (l_float32)w;
265  else
266  scale = 11.0 * 300. / (l_float32)h;
267 
268  if ((fp = fopen(fileout, "wb")) == NULL)
269  return ERROR_INT("file not opened for write", procName, 1);
271  fclose(fp);
272 
273  pixDestroy(&pix);
274  return 0;
275 }
276 
277 
278 /*!
279  * pixWriteStreamPS()
280  *
281  * Input: stream
282  * pix
283  * box (<optional>)
284  * res (can use 0 for default of 300 ppi)
285  * scale (to prevent scaling, use either 1.0 or 0.0)
286  * Return: 0 if OK; 1 on error
287  *
288  * Action: writes image in PS format, optionally scaled,
289  * adjusted for the printer resolution, and with
290  * a bounding box. For details on use of parameters,
291  * see pixWriteStringPS().
292  */
293 l_int32
295  PIX *pix,
296  BOX *box,
297  l_int32 res,
299 {
300 char *pstring;
302 PIX *pixc;
303 
304  PROCNAME("pixWriteStreamPS");
305 
306  if (!fp)
307  return (l_int32)ERROR_INT("stream not open", procName, 1);
308  if (!pix)
309  return (l_int32)ERROR_INT("pix not defined", procName, 1);
310 
311  if ((pixc = pixConvertForPSWrap(pix)) == NULL)
312  return (l_int32)ERROR_INT("pixc not made", procName, 1);
313 
314  pstring = pixWriteStringPS(pixc, box, res, scale);
315  length = strlen(pstring);
316  fwrite(pstring, 1, length, fp);
317  FREE((void *)pstring);
318  pixDestroy(&pixc);
319 
320  return 0;
321 }
322 
323 
324 /*!
325  * pixWriteStringPS()
326  *
327  * Input: pix: 1 bpp, colormapped, 8 bpp grayscale, 32 bpp (RGB)
328  * box: (a) If box == null, image is placed, optionally scaled,
329  * in a standard b.b. at the center of the page.
330  * This is to be used when another program like
331  * TeX (through epsf) places the image.
332  * (b) If box != null, image is placed without a
333  * b.b. at the specified page location and with
334  * (optional) scaling. This is to be used when
335  * you want to specify exactly where (and optionally
336  * how big) you want the image to be.
337  * Note that all coordinates are in PS convention,
338  * with (0,0) at LL corner of the page:
339  * (x,y) location of LL corner of image, in mils.
340  * (w,h) scaled size, in mils. Use 0 to
341  * scale with "scale" and "res" input.
342  * res: resolution, in printer ppi. Use 0 for default (300 ppi).
343  * scale: scale factor. If no scaling is desired, use
344  * either 1.0 or 0.0. Scaling just resets the resolution
345  * parameter; the actual scaling is done in the
346  * interpreter at rendering time. This is important:
347  * it allows you to scale the image up without
348  * increasing the file size.
349  *
350  * Return: ps string if OK, or null on error
351  *
352  * Usage notes:
353  * OK, this seems a bit complicated, because there are various
354  * ways to scale and not to scale.
355  * If you don't want any scaling at all:
356  * if you are using a box:
357  * set w = 0, h = 0, and use scale = 1.0; it will print
358  * each pixel unscaled at printer resolution
359  * if you are not using a box:
360  * set scale = 1.0; it will print at printer resolution
361  * If you want the image to be a certain size in inches:
362  * you must use a box and set the box (w,h) in mils
363  * If you want the image to be scaled by a scale factor != 1.0:
364  * if you are using a box:
365  * set w = 0, h = 0, and use the desired scale factor;
366  * the higher the printer resolution, the smaller the
367  * image will actually appear.
368  * if you are not using a box:
369  * set the desired scale factor; the higher the printer
370  * resolution, the smaller the image will actually appear.
371  *
372  * Distance units:
373  * The interface distances are in milli-inches.
374  * In addition, we use 3 different units internally:
375  * - pixels (units of 1/res inch)
376  * - printer pts (units of 1/72 inch)
377  * - inches
378  *
379  * Here is a quiz on units from a reviewer:
380  * How many UK milli-cups in a US kilo-teaspoon?
381  * (Hint: a US cup = 0.75 UK cups + 2 desertspoons.)
382  */
383 char *
385  BOX *box,
386  l_int32 res,
388 {
389 char nib1, nib2;
390 char bigbuf[BUF_SIZE];
391 char *hexdata, *pstring;
392 l_uint8 byteval;
393 l_int32 i, j, k, d, wpix, hpix;
394 l_float32 wpt, hpt, xpt, ypt;
395 l_int32 wpl, psbpl, hexbytes, boxflag, sampledepth;
396 l_uint32 *line, *data;
397 PIX *pix;
398 SARRAY *sa;
399 
400  PROCNAME("pixWriteStringPS");
401 
402  if (!pixs)
403  return (char *)ERROR_PTR("pix not defined", procName, NULL);
404 
405  d = pixGetDepth(pixs);
406  if (d == 16)
407  pix = pixConvert16To8(pixs, 1);
408  else
410  d = pixGetDepth(pix);
411 
412  /* get the factors by which PS scales and translates, in pts */
413  wpix = pixGetWidth(pix);
414  hpix = pixGetHeight(pix);
415  if (!box)
416  boxflag = 0; /* no scaling; b.b. at center */
417  else
418  boxflag = 1; /* no b.b., specify placement and optional scaling */
419  getScaledParametersPS(box, wpix, hpix, res, scale, &xpt, &ypt, &wpt, &hpt);
420 
421  if (d == 1)
422  sampledepth = 1;
423  else /* d == 8 || d == 32 */
424  sampledepth = 8;
425 
426  /* convert image data to hex string */
427  wpl = pixGetWpl(pix);
428  if (d == 1 || d == 8)
429  psbpl = (wpix * d + 7) / 8; /* packed to byte boundary */
430  else /* d == 32 */
431  psbpl = 3 * wpix; /* packed to byte boundary */
432  data = pixGetData(pix);
433  hexbytes = 2 * psbpl * hpix; /* size of ps hex array */
434  if ((hexdata = (char *)CALLOC(hexbytes + 1, sizeof(char))) == NULL)
435  return (char *)ERROR_PTR("hexdata not made", procName, NULL);
436  if (d == 1 || d == 8) {
437  for (i = 0, k = 0; i < hpix; i++) {
438  line = data + i * wpl;
439  for (j = 0; j < psbpl; j++) {
440  byteval = GET_DATA_BYTE(line, j);
441  convertByteToHexAscii(byteval, &nib1, &nib2);
442  hexdata[k++] = nib1;
443  hexdata[k++] = nib2;
444  }
445  }
446  }
447  else { /* d == 32; hexdata bytes packed RGBRGB..., 2 per sample */
448  for (i = 0, k = 0; i < hpix; i++) {
449  line = data + i * wpl;
450  for (j = 0; j < wpix; j++) {
451  byteval = GET_DATA_BYTE(line + j, 0); /* red */
452  convertByteToHexAscii(byteval, &nib1, &nib2);
453  hexdata[k++] = nib1;
454  hexdata[k++] = nib2;
455  byteval = GET_DATA_BYTE(line + j, 1); /* green */
456  convertByteToHexAscii(byteval, &nib1, &nib2);
457  hexdata[k++] = nib1;
458  hexdata[k++] = nib2;
459  byteval = GET_DATA_BYTE(line + j, 2); /* blue */
460  convertByteToHexAscii(byteval, &nib1, &nib2);
461  hexdata[k++] = nib1;
462  hexdata[k++] = nib2;
463  }
464  }
465  }
466  hexdata[k] = '\0';
467 
468  if ((sa = sarrayCreate(0)) == NULL)
469  return (char *)ERROR_PTR("sa not made", procName, NULL);
470 
471  sarrayAddString(sa, "%!Adobe-PS", 1);
472  if (boxflag == 0) {
473  sprintf(bigbuf,
474  "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
475  xpt, ypt, xpt + wpt, ypt + hpt);
476  sarrayAddString(sa, bigbuf, 1);
477  }
478  else /* boxflag == 1 */
479  sarrayAddString(sa, "gsave", 1);
480 
481  if (d == 1)
482  sarrayAddString(sa, "{1 exch sub} settransfer %invert binary", 1);
483 
484  sprintf(bigbuf, "/bpl %d string def %%bpl as a string", psbpl);
485  sarrayAddString(sa, bigbuf, 1);
486  sprintf(bigbuf,
487  "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
488  sarrayAddString(sa, bigbuf, 1);
489  sprintf(bigbuf,
490  "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
491  sarrayAddString(sa, bigbuf, 1);
492  sprintf(bigbuf,
493  "%d %d %d %%image dimensions in pixels",
494  wpix, hpix, sampledepth);
495  sarrayAddString(sa, bigbuf, 1);
496  sprintf(bigbuf,
497  "[%d %d %d %d %d %d] %%mapping matrix: [wpix 0 0 -hpix 0 hpix]",
498  wpix, 0, 0, -hpix, 0, hpix);
499  sarrayAddString(sa, bigbuf, 1);
500 
501  if (boxflag == 0) {
502  if (d == 1 || d == 8)
503  sarrayAddString(sa, "{currentfile bpl readhexstring pop} image", 1);
504  else /* d == 32 */
505  sarrayAddString(sa,
506  "{currentfile bpl readhexstring pop} false 3 colorimage", 1);
507  }
508  else { /* boxflag == 1 */
509  if (d == 1 || d == 8)
510  sarrayAddString(sa,
511  "{currentfile bpl readhexstring pop} bind image",1);
512  else /* d == 32 */
513  sarrayAddString(sa,
514  "{currentfile bpl readhexstring pop} bind false 3 colorimage",1);
515  }
516 
517  sarrayAddString(sa, hexdata, 0);
518 
519  if (boxflag == 0)
520  sarrayAddString(sa, "\nshowpage", 1);
521  else /* boxflag == 1 */
522  sarrayAddString(sa, "\ngrestore", 1);
523 
524  if ((pstring = sarrayToString(sa, 1)) == NULL)
525  return (char *)ERROR_PTR("pstring not made", procName, NULL);
526 
527  sarrayDestroy(&sa);
528  pixDestroy(&pix);
529  return pstring;
530 }
531 
532 
533 /*!
534  * getScaledParametersPS()
535  *
536  * Input: box (<optional> location of image in mils; with
537  * (x,y) being the LL corner)
538  * wpix (pix width in pixels)
539  * hpix (pix height in pixels)
540  * res (of printer; use 0 for default)
541  * scale (use 1.0 or 0.0 for no scaling)
542  * &xpt (location of llx in pts)
543  * &ypt (location of lly in pts)
544  * &wpt (image width in pts)
545  * &hpt (image height in pts)
546  *
547  * Return: void (no arg checking)
548  *
549  * Notes:
550  * (1) the image is always scaled, depending on res and scale
551  * (2) if no box, the image is centered on the page
552  * (3) if there is a box, the image is placed within it
553  */
554 void
556  l_int32 wpix,
557  l_int32 hpix,
558  l_int32 res,
560  l_float32 *pxpt,
561  l_float32 *pypt,
562  l_float32 *pwpt,
563  l_float32 *phpt)
564 {
565 l_float32 winch, hinch, xinch, yinch, fres;
566 
567  PROCNAME("getScaledParametersPS");
568 
569  if (res == 0)
571  fres = (l_float32)res;
572 
573  /* allow the PS interpreter to scale the resolution */
574  if (scale == 0.0)
575  scale = 1.0;
576  if (scale != 1.0) {
577  fres = (l_float32)res / scale;
578  res = (l_int32)fres;
579  }
580 
581  /* limit valid resolution interval */
583  L_WARNING_INT("res %d out of bounds; using default res; no scaling",
584  procName, res);
586  fres = (l_float32)res;
587  }
588 
589  if (!box) { /* center on page */
590  winch = (l_float32)wpix / fres;
591  hinch = (l_float32)hpix / fres;
592  xinch = (8.5 - winch) / 2.;
593  yinch = (11.0 - hinch) / 2.;
594  }
595  else {
596  if (box->w == 0)
597  winch = (l_float32)wpix / fres;
598  else
599  winch = (l_float32)box->w / 1000.;
600  if (box->h == 0)
601  hinch = (l_float32)hpix / fres;
602  else
603  hinch = (l_float32)box->h / 1000.;
604  xinch = (l_float32)box->x / 1000.;
605  yinch = (l_float32)box->y / 1000.;
606  }
607 
608  if (xinch < 0)
609  L_WARNING("left edge < 0.0 inch", procName);
610  if (xinch + winch > 8.5)
611  L_WARNING("right edge > 8.5 inch", procName);
612  if (yinch < 0.0)
613  L_WARNING("bottom edge < 0.0 inch", procName);
614  if (yinch + hinch > 11.0)
615  L_WARNING("top edge > 11.0 inch", procName);
616 
617  *pwpt = 72. * winch;
618  *phpt = 72. * hinch;
619  *pxpt = 72. * xinch;
620  *pypt = 72. * yinch;
621  return;
622 }
623 
624 
625 /*!
626  * convertByteToHexAscii()
627  *
628  * Input: byteval (input byte)
629  * &nib1, &nib2 (<return> two hex ascii characters)
630  * Return: void
631  */
632 void
634  char *pnib1,
635  char *pnib2)
636 {
637 l_uint8 nib;
638 
639  nib = byteval >> 4;
640  if (nib < 10)
641  *pnib1 = '0' + nib;
642  else
643  *pnib1 = 'a' + (nib - 10);
644  nib = byteval & 0xf;
645  if (nib < 10)
646  *pnib2 = '0' + nib;
647  else
648  *pnib2 = 'a' + (nib - 10);
649 
650  return;
651 }
652 
653 
654 /*-------------------------------------------------------------*
655  * For jpeg compressed images *
656  *-------------------------------------------------------------*/
657 /*!
658  * convertJpegToPSEmbed()
659  *
660  * Input: filein (input jpeg file)
661  * fileout (output ps file)
662  * Return: 0 if OK, 1 on error
663  *
664  * Notes:
665  * (1) This function takes a jpeg file as input and generates a DCT
666  * compressed, ascii85 encoded PS file, with a bounding box.
667  * (2) The bounding box is required when a program such as TeX
668  * (through epsf) places and rescales the image.
669  * (3) The bounding box is sized for fitting the image to an
670  * 8.5 x 11.0 inch page.
671  */
672 l_int32
673 convertJpegToPSEmbed(const char *filein,
674  const char *fileout)
675 {
676 char *pstring, *outstr;
677 char *data85; /* ascii85 encoded file */
678 char bigbuf[512];
679 l_uint8 *bindata; /* binary encoded jpeg data (entire file) */
680 l_int32 bps, w, h, spp;
681 l_int32 nbinbytes, psbytes, nbytes85, totbytes;
682 l_float32 xpt, ypt, wpt, hpt;
683 SARRAY *sa;
684 
685  PROCNAME("convertJpegToPSEmbed");
686 
687  if (!filein)
688  return ERROR_INT("filein not defined", procName, 1);
689  if (!fileout)
690  return ERROR_INT("fileout not defined", procName, 1);
691 
692  /* the returned jpeg data in memory is the entire jpeg file,
693  * which starts with ffd8 and ends with ffd9 */
694  if (extractJpegDataFromFile(filein, &bindata, &nbinbytes,
695  &w, &h, &bps, &spp))
696  return ERROR_INT("bindata not extracted from file", procName, 1);
697 
698  /* convert entire jpeg file of encoded DCT data to ascii85 */
699  data85 = encodeAscii85(bindata, nbinbytes, &nbytes85);
700  FREE((void *)bindata);
701  if (!data85)
702  return ERROR_INT("data85 not made", procName, 1);
703 
704  /* scale for 20 pt boundary and otherwise full filling
705  * in one direction on 8.5 x 11 inch device */
706  xpt = 20.0;
707  ypt = 20.0;
708  if (w * 11.0 > h * 8.5) {
709  wpt = 572.0; /* 612 - 2 * 20 */
710  hpt = wpt * (l_float32)h / (l_float32)w;
711  }
712  else {
713  hpt = 752.0; /* 792 - 2 * 20 */
714  wpt = hpt * (l_float32)w / (l_float32)h;
715  }
716 
717  /* -------- generate PostScript output -------- */
718  if ((sa = sarrayCreate(50)) == NULL)
719  return ERROR_INT("sa not made", procName, 1);
720 
721  sarrayAddString(sa, "%!PS-Adobe-3.0", 1);
722  sarrayAddString(sa, "%%Creator: leptonica", 1);
723  sprintf(bigbuf, "%%%%Title: %s", filein);
724  sarrayAddString(sa, bigbuf, 1);
725  sprintf(bigbuf,
726  "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
727  xpt, ypt, xpt + wpt, ypt + hpt);
728  sarrayAddString(sa, bigbuf, 1);
729  sarrayAddString(sa, "%%DocumentData: Clean7Bit", 1);
730  sarrayAddString(sa, "%%LanguageLevel: 2", 1);
731  sarrayAddString(sa, "%%EndComments", 1);
732  sarrayAddString(sa, "%%Page: 1 1", 1);
733 
734  sarrayAddString(sa, "save", 1);
735  sarrayAddString(sa, "/RawData currentfile /ASCII85Decode filter def", 1);
736  sarrayAddString(sa, "/Data RawData << >> /DCTDecode filter def", 1);
737 
738  sprintf(bigbuf,
739  "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
740  sarrayAddString(sa, bigbuf, 1);
741 
742  sprintf(bigbuf,
743  "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
744  sarrayAddString(sa, bigbuf, 1);
745 
746  if (spp == 1)
747  sarrayAddString(sa, "/DeviceGray setcolorspace", 1);
748  else if (spp == 3)
749  sarrayAddString(sa, "/DeviceRGB setcolorspace", 1);
750  else /*spp == 4 */
751  sarrayAddString(sa, "/DeviceCMYK setcolorspace", 1);
752 
753  sarrayAddString(sa, "{ << /ImageType 1", 1);
754  sprintf(bigbuf, " /Width %d", w);
755  sarrayAddString(sa, bigbuf, 1);
756  sprintf(bigbuf, " /Height %d", h);
757  sarrayAddString(sa, bigbuf, 1);
758  sprintf(bigbuf, " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
759  sarrayAddString(sa, bigbuf, 1);
760  sarrayAddString(sa, " /DataSource Data", 1);
761  sprintf(bigbuf, " /BitsPerComponent %d", bps);
762  sarrayAddString(sa, bigbuf, 1);
763 
764  if (spp == 1)
765  sarrayAddString(sa, " /Decode [0 1]", 1);
766  else if (spp == 3)
767  sarrayAddString(sa, " /Decode [0 1 0 1 0 1]", 1);
768  else /* spp == 4 */
769  sarrayAddString(sa, " /Decode [0 1 0 1 0 1 0 1]", 1);
770 
771  sarrayAddString(sa, " >> image", 1);
772  sarrayAddString(sa, " Data closefile", 1);
773  sarrayAddString(sa, " RawData flushfile", 1);
774  sarrayAddString(sa, " showpage", 1);
775  sarrayAddString(sa, " restore", 1);
776  sarrayAddString(sa, "} exec", 1);
777 
778  if ((pstring = sarrayToString(sa, 1)) == NULL)
779  return ERROR_INT("pstring not made", procName, 1);
780  sarrayDestroy(&sa);
781  psbytes = strlen(pstring);
782 
783  /* add the ascii85 data */
784  totbytes = psbytes + nbytes85;
785  if ((outstr = (char *)CALLOC(totbytes + 4, sizeof(char))) == NULL)
786  return ERROR_INT("outstr not made", procName, 1);
787  memcpy(outstr, pstring, psbytes);
788  memcpy(outstr + psbytes, data85, nbytes85);
789  FREE((void *)pstring);
790  FREE((void *)data85);
791 
792  if (arrayWrite(fileout, "w", outstr, totbytes))
793  return ERROR_INT("ps string not written to file", procName, 1);
794  FREE((void *)outstr);
795  return 0;
796 }
797 
798 
799 /*!
800  * convertJpegToPS()
801  *
802  * Input: filein (input jpeg file)
803  * fileout (output ps file)
804  * operation ("w" for write; "a" for append)
805  * x, y (location of LL corner of image, in pixels, relative
806  * to the PostScript origin (0,0) at the LL corner
807  * of the page)
808  * res (resolution of the input image, in ppi; use 0 for default)
809  * scale (scaling by printer; use 0.0 or 1.0 for no scaling)
810  * pageno (page number; must start with 1; you can use 0
811  * if there is only one page.)
812  * endpage (boolean: TRUE if the last image to be
813  * added to the page; FALSE otherwise)
814  * Return: 0 if OK, 1 on error
815  *
816  * Usage: This is simpler to use than pixWriteStringPS(), and
817  * it outputs in level 2 PS as compressed DCT (overlaid
818  * with ascii85 encoding).
819  *
820  * An output file can contain multiple pages, each with
821  * multiple images. The arguments to convertJpegToPS()
822  * allow you to control placement of jpeg images on multiple
823  * pages within a PostScript file.
824  *
825  * For the first image written to a file, use "w", which
826  * opens for write and clears the file. For all subsequent
827  * images written to that file, use "a".
828  *
829  * The (x, y) parameters give the LL corner of the image
830  * relative to the LL corner of the page. They are in
831  * units of pixels if scale = 1.0. If you use (e.g.)
832  * scale = 2.0, the image is placed at (2x, 2y) on the page,
833  * and the image dimensions are also doubled.
834  *
835  * If your display is 75 ppi and your image was created
836  * at a resolution of 300 ppi, you can get the image
837  * to print at the same size as it appears on your display
838  * by either setting scale = 4.0 or by setting res = 75.
839  * Both tell the printer to make a 4x enlarged image.
840  *
841  * If your image is generated at 150 ppi and you use scale = 1,
842  * it will be rendered such that 150 pixels correspond
843  * to 72 pts (1 inch on the printer). This function does
844  * the conversion from pixels (with or without scaling) to
845  * pts, which are the units that the printer uses.
846  *
847  * The printer will choose its own resolution to use
848  * in rendering the image, which will not affect the size
849  * of the rendered image. That is because the output
850  * PostScript file describes the geometry in terms of pts,
851  * which are defined to be 1/72 inch. The printer will
852  * only see the size of the image in pts, through the
853  * scale and translate parameters and the affine
854  * transform (the ImageMatrix) of the image.
855  *
856  * To render multiple images on the same page, set
857  * endpage = FALSE for each image until you get to the
858  * last, for which you set endpage = TRUE. This causes the
859  * "showpage" command to be invoked. Showpage outputs
860  * the entire page and clears the raster buffer for the
861  * next page to be added. Without a "showpage",
862  * subsequent images from the next page will overlay those
863  * previously put down.
864  *
865  * For multiple pages, increment the page number, starting
866  * with page 1. This allows PostScript (and PDF) to build
867  * a page directory, which viewers use for navigation.
868  */
869 l_int32
870 convertJpegToPS(const char *filein,
871  const char *fileout,
872  const char *operation,
873  l_int32 x,
874  l_int32 y,
875  l_int32 res,
877  l_int32 pageno,
879 {
880 char *outstr;
882 
883  PROCNAME("convertJpegToPS");
884 
885  if (!filein)
886  return ERROR_INT("filein not defined", procName, 1);
887  if (!fileout)
888  return ERROR_INT("fileout not defined", procName, 1);
889  if (strcmp(operation, "w") && strcmp(operation, "a"))
890  return ERROR_INT("operation must be \"w\" or \"a\"", procName, 1);
891 
892  if (convertJpegToPSString(filein, &outstr, &nbytes, x, y, res, scale,
893  pageno, endpage))
894  return ERROR_INT("ps string not made", procName, 1);
895 
896  if (arrayWrite(fileout, operation, outstr, nbytes))
897  return ERROR_INT("ps string not written to file", procName, 1);
898 
899  FREE((void *)outstr);
900  return 0;
901 }
902 
903 
904 /*!
905  * convertJpegToPSString()
906  *
907  * Generates PS string in jpeg format from jpeg file
908  *
909  * Input: filein (input jpeg file)
910  * &poutstr (<return> PS string)
911  * &nbytes (<return> number of bytes in PS string)
912  * x, y (location of LL corner of image, in pixels, relative
913  * to the PostScript origin (0,0) at the LL corner
914  * of the page)
915  * res (resolution of the input image, in ppi; use 0 for default)
916  * scale (scaling by printer; use 0.0 or 1.0 for no scaling)
917  * pageno (page number; must start with 1; you can use 0
918  * if there is only one page.)
919  * endpage (boolean: TRUE if the last image to be
920  * added to the page; FALSE otherwise)
921  * Return: 0 if OK, 1 on error
922  *
923  * Note: The returned PS character array is binary string, not a
924  * null-terminated ascii C string. It has null bytes embedded in it!
925  *
926  * Usage: See convertJpegToPS()
927  */
928 l_int32
929 convertJpegToPSString(const char *filein,
930  char **poutstr,
931  l_int32 *pnbytes,
932  l_int32 x,
933  l_int32 y,
934  l_int32 res,
936  l_int32 pageno,
938 {
939 char *pstring, *outstr;
940 char *data85; /* ascii85 encoded file */
941 char bigbuf[BUF_SIZE];
942 l_uint8 *bindata; /* binary encoded jpeg data (entire file) */
943 l_int32 bps, w, h, spp;
944 l_int32 nbinbytes, psbytes, nbytes85, totbytes;
945 l_float32 xpt, ypt, wpt, hpt;
946 SARRAY *sa;
947 
948  PROCNAME("convertJpegToPSString");
949 
950  if (!filein)
951  return ERROR_INT("filein not defined", procName, 1);
952  if (!poutstr)
953  return ERROR_INT("&outstr not defined", procName, 1);
954  if (!pnbytes)
955  return ERROR_INT("&nbytes not defined", procName, 1);
956  *poutstr = NULL;
957 
958  /* the returned jpeg data in memory is the entire jpeg file,
959  * which starts with ffd8 and ends with ffd9 */
960  if (extractJpegDataFromFile(filein, &bindata, &nbinbytes,
961  &w, &h, &bps, &spp))
962  return ERROR_INT("bindata not extracted from file", procName, 1);
963 
964  /* convert entire jpeg file of encoded DCT data to ascii85 */
965  data85 = encodeAscii85(bindata, nbinbytes, &nbytes85);
966  FREE((void *)bindata);
967  if (!data85)
968  return ERROR_INT("data85 not made", procName, 1);
969 
970 #if DEBUG_JPEG
971  fprintf(stderr, "w = %d, h = %d, bps = %d, spp = %d\n", w, h, bps, spp);
972  fprintf(stderr, "nbinbytes = %d, nbytes85 = %d, ratio = %5.3f\n",
973  nbinbytes, nbytes85, (l_float32)nbytes85 / (l_float32)nbinbytes);
974 #endif /* DEBUG_JPEG */
975 
976  /* get scaled location in pts */
977  if (scale == 0.0)
978  scale = 1.0;
979  if (res == 0)
981  xpt = scale * x * 72. / res;
982  ypt = scale * y * 72. / res;
983  wpt = scale * w * 72. / res;
984  hpt = scale * h * 72. / res;
985 
986  if (pageno == 0)
987  pageno = 1;
988 
989 #if DEBUG_JPEG
990  fprintf(stderr, "xpt = %7.2f, ypt = %7.2f, wpt = %7.2f, hpt = %7.2f\n",
991  xpt, ypt, wpt, hpt);
992 #endif /* DEBUG_JPEG */
993 
994  /* -------- generate PostScript output -------- */
995  if ((sa = sarrayCreate(50)) == NULL)
996  return ERROR_INT("sa not made", procName, 1);
997 
998  sarrayAddString(sa, "%!PS-Adobe-3.0", 1);
999  sarrayAddString(sa, "%%Creator: leptonica", 1);
1000  sprintf(bigbuf, "%%%%Title: %s", filein);
1001  sarrayAddString(sa, bigbuf, 1);
1002 #if PRINT_BOUNDING_BOX
1003  sprintf(bigbuf,
1004  "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
1005  xpt, ypt, xpt + wpt, ypt + hpt);
1006  sarrayAddString(sa, bigbuf, 1);
1007 #endif /* PRINT_BOUNDING_BOX */
1008 
1009  sarrayAddString(sa, "%%DocumentData: Clean7Bit", 1);
1010  sarrayAddString(sa, "%%LanguageLevel: 2", 1);
1011  sarrayAddString(sa, "%%EndComments", 1);
1012  sprintf(bigbuf, "%%%%Page: %d %d", pageno, pageno);
1013  sarrayAddString(sa, bigbuf, 1);
1014 
1015  sarrayAddString(sa, "save", 1);
1016  sarrayAddString(sa, "/RawData currentfile /ASCII85Decode filter def", 1);
1017  sarrayAddString(sa, "/Data RawData << >> /DCTDecode filter def", 1);
1018 
1019  sprintf(bigbuf,
1020  "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
1021  sarrayAddString(sa, bigbuf, 1);
1022 
1023  sprintf(bigbuf,
1024  "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
1025  sarrayAddString(sa, bigbuf, 1);
1026 
1027  if (spp == 1)
1028  sarrayAddString(sa, "/DeviceGray setcolorspace", 1);
1029  else if (spp == 3)
1030  sarrayAddString(sa, "/DeviceRGB setcolorspace", 1);
1031  else /*spp == 4 */
1032  sarrayAddString(sa, "/DeviceCMYK setcolorspace", 1);
1033 
1034  sarrayAddString(sa, "{ << /ImageType 1", 1);
1035  sprintf(bigbuf, " /Width %d", w);
1036  sarrayAddString(sa, bigbuf, 1);
1037  sprintf(bigbuf, " /Height %d", h);
1038  sarrayAddString(sa, bigbuf, 1);
1039  sprintf(bigbuf, " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
1040  sarrayAddString(sa, bigbuf, 1);
1041  sarrayAddString(sa, " /DataSource Data", 1);
1042  sprintf(bigbuf, " /BitsPerComponent %d", bps);
1043  sarrayAddString(sa, bigbuf, 1);
1044 
1045  if (spp == 1)
1046  sarrayAddString(sa, " /Decode [0 1]", 1);
1047  else if (spp == 3)
1048  sarrayAddString(sa, " /Decode [0 1 0 1 0 1]", 1);
1049  else /* spp == 4 */
1050  sarrayAddString(sa, " /Decode [0 1 0 1 0 1 0 1]", 1);
1051 
1052  sarrayAddString(sa, " >> image", 1);
1053  sarrayAddString(sa, " Data closefile", 1);
1054  sarrayAddString(sa, " RawData flushfile", 1);
1055  if (endpage == TRUE)
1056  sarrayAddString(sa, " showpage", 1);
1057  sarrayAddString(sa, " restore", 1);
1058  sarrayAddString(sa, "} exec", 1);
1059 
1060  if ((pstring = sarrayToString(sa, 1)) == NULL)
1061  return ERROR_INT("pstring not made", procName, 1);
1062  psbytes = strlen(pstring);
1063 
1064  /* add the ascii85 data */
1065  totbytes = psbytes + nbytes85;
1066  *pnbytes = totbytes;
1067  if ((outstr = (char *)CALLOC(totbytes + 4, sizeof(char))) == NULL)
1068  return ERROR_INT("outstr not made", procName, 1);
1069  *poutstr = outstr;
1070  memcpy(outstr, pstring, psbytes);
1071  memcpy(outstr + psbytes, data85, nbytes85);
1072 
1073  sarrayDestroy(&sa);
1074  FREE((void *)data85);
1075  FREE((void *)pstring);
1076  return 0;
1077 }
1078 
1079 
1080 /*!
1081  * extractJpegDataFromFile()
1082  *
1083  * Input: filein
1084  * &data (binary data consisting of the entire jpeg file)
1085  * &nbytes (size of binary data)
1086  * &w (<return> image width)
1087  * &h (<return> image height)
1088  * &bps (<return> bits/sample; should be 8)
1089  * &spp (<return> samples/pixel; should be 1 or 3)
1090  * Return: 0 if OK, 1 on error
1091  *
1092  * Note: on error, free the data.
1093  */
1094 l_int32
1095 extractJpegDataFromFile(const char *filein,
1096  l_uint8 **pdata,
1097  l_int32 *pnbytes,
1098  l_int32 *pw,
1099  l_int32 *ph,
1100  l_int32 *pbps,
1101  l_int32 *pspp)
1102 {
1103 l_uint8 *data;
1105 FILE *fpin;
1106 
1107  PROCNAME("extractJpegDataFromFile");
1108 
1109  if (!filein)
1110  return ERROR_INT("filein not defined", procName, 1);
1111  if (!pdata)
1112  return ERROR_INT("&data not defined", procName, 1);
1113  if (!pnbytes)
1114  return ERROR_INT("&nbytes not defined", procName, 1);
1115  if (!pw || !ph || !pbps || !pspp)
1116  return ERROR_INT("&w, &h, &bps, &spp not all defined", procName, 1);
1117  *pdata = NULL;
1118  *pnbytes = *pw = *ph = *pbps = *pspp = 0;
1119 
1120  if ((fpin = fopen(filein, "rb")) == NULL)
1121  return ERROR_INT("filein not defined", procName, 1);
1122  format = findFileFormat(fpin);
1123  fclose(fpin);
1124  if (format != IFF_JFIF_JPEG)
1125  return ERROR_INT("filein not jfif jpeg", procName, 1);
1126 
1127  if ((data = arrayRead(filein, &nbytes)) == NULL)
1128  return ERROR_INT("inarray not made", procName, 1);
1129  *pnbytes = nbytes;
1130  *pdata = data;
1131 
1132  if (extractJpegDataFromArray(data, nbytes, pw, ph, pbps, pspp)) {
1133  FREE((void *)data);
1134  *pdata = NULL;
1135  *pnbytes = 0;
1136  }
1137 
1138  return 0;
1139 }
1140 
1141 
1142 /*!
1143  * extractJpegDataFromArray()
1144  *
1145  * Input: data (binary data consisting of the entire jpeg file)
1146  * nbytes (size of binary data)
1147  * &w (<return> image width)
1148  * &h (<return> image height)
1149  * &bps (<return> bits/sample; should be 8)
1150  * &spp (<return> samples/pixel; should be 1 or 3)
1151  * Return: 0 if OK, 1 on error
1152  */
1153 l_int32
1155  l_int32 nbytes,
1156  l_int32 *pw,
1157  l_int32 *ph,
1158  l_int32 *pbps,
1159  l_int32 *pspp)
1160 {
1161 l_uint8 *data8;
1162 l_int32 imeta, msize, bps, w, h, spp;
1163 
1164  PROCNAME("extractJpegDataFromArray");
1165 
1166  if (!data)
1167  return ERROR_INT("data not defined", procName, 1);
1168  if (!pw || !ph || !pbps || !pspp)
1169  return ERROR_INT("&w, &h, &bps, &spp not all defined", procName, 1);
1170  *pw = *ph = *pbps = *pspp = 0;
1171  data8 = (l_uint8 *)data;
1172 
1173  /* Find where the image metadata begins in header:
1174  * 0xc0 is start of metadata for baseline DCT;
1175  * 0xc1 is start of metadata for extended sequential DCT;
1176  * ... */
1177  imeta = 0;
1178  if (locateJpegImageParameters(data8, nbytes, &imeta))
1179  return ERROR_INT("metadata not found", procName, 1);
1180 
1181  /* save the metadata */
1182  msize = getTwoByteParameter(data8, imeta); /* metadata size */
1183  bps = data8[imeta + 2];
1184  h = getTwoByteParameter(data8, imeta + 3);
1185  w = getTwoByteParameter(data8, imeta + 5);
1186  spp = data8[imeta + 7];
1187  *pbps = bps;
1188  *ph = h;
1189  *pw = w;
1190  *pspp = spp;
1191 #if DEBUG_JPEG
1192  fprintf(stderr, "w = %d, h = %d, bps = %d, spp = %d\n", w, h, bps, spp);
1193  fprintf(stderr, "imeta = %d, msize = %d\n", imeta, msize);
1194 #endif /* DEBUG_JPEG */
1195 
1196  /* is the data obviously bad? */
1197  if (h <= 0 || w <= 0 || bps != 8 || (spp != 1 && spp !=3 && spp != 4)) {
1198  fprintf(stderr, "h = %d, w = %d, bps = %d, spp = %d\n", h, w, bps, spp);
1199  return ERROR_INT("image parameters not valid", procName, 1);
1200  }
1201 
1202  return 0;
1203 }
1204 
1205 
1206 /*
1207  * locateJpegImageParameters()
1208  *
1209  * Input: inarray (binary jpeg)
1210  * size (of the data array)
1211  * &index (<return> location of image metadata)
1212  * Return: 0 if OK, 1 on error. Caller must check this!
1213  *
1214  * The parameters listed here appear to be tho only jpeg flags
1215  * we need to worry about. It would have been nice to have
1216  * avoided the switch with all these parameters, but
1217  * unfortunately the parser for the jpeg header is set
1218  * to accept any old flag that's not on the approved list!
1219  * So we have to look for a flag that's not on the list
1220  * (and is not 0), and then interpret the size of the
1221  * data chunk and skip it. Sometimes such a chunk contains
1222  * a thumbnail version of the image, so if we don't skip it,
1223  * we will find a pair of bytes such as 0xffc0, followed
1224  * by small w and h dimensions.
1225  */
1226 static l_int32
1228  l_int32 size,
1229  l_int32 *pindex)
1230 {
1231 l_uint8 val;
1232 l_int32 index, skiplength;
1233 
1234  PROCNAME("locateJpegImageParameters");
1235 
1236  if (!inarray)
1237  return ERROR_INT("inarray not defined", procName, 1);
1238  if (!pindex)
1239  return ERROR_INT("&index not defined", procName, 1);
1240 
1241  index = *pindex;
1242  while (1) {
1244  break;
1245  if ((val = inarray[index]) == 0) /* ignore if "escaped" */
1246  continue;
1247 /* fprintf(stderr, " marker %x at %o, %d\n", val, index, index); */
1248  switch(val)
1249  {
1250  case 0xc0: /* M_SOF0 */
1251  case 0xc1: /* M_SOF1 */
1252  case 0xc2: /* M_SOF2 */
1253  case 0xc3: /* M_SOF3 */
1254  case 0xc5: /* M_SOF5 */
1255  case 0xc6: /* M_SOF6 */
1256  case 0xc7: /* M_SOF7 */
1257  case 0xc9: /* M_SOF9 */
1258  case 0xca: /* M_SOF10 */
1259  case 0xcd: /* M_SOF13 */
1260  case 0xce: /* M_SOF14 */
1261  case 0xcf: /* M_SOF15 */
1262  *pindex = index + 1; /* found it */
1263  return 0;
1264 
1265  case 0x01: /* M_TEM */
1266  case 0xd0: /* M_RST0 */
1267  case 0xd1: /* M_RST1 */
1268  case 0xd2: /* M_RST2 */
1269  case 0xd3: /* M_RST3 */
1270  case 0xd4: /* M_RST4 */
1271  case 0xd5: /* M_RST5 */
1272  case 0xd6: /* M_RST6 */
1273  case 0xd7: /* M_RST7 */
1274  case 0xd8: /* M_SOI */
1275  case 0xd9: /* M_EOI */
1276  case 0xe0: /* M_APP0 */
1277  case 0xee: /* M_APP14 */
1278  break;
1279 
1280  default:
1281  skiplength = getTwoByteParameter(inarray, index + 1);
1282  index += skiplength;
1283  break;
1284  }
1285  }
1286 
1287  return 1; /* not found */
1288 }
1289 
1290 
1291 /*
1292  * getNextJpegMarker()
1293  *
1294  * Input: array (jpeg data)
1295  * size (from current point to the end)
1296  * &index (<return> the last position searched. If it
1297  * is not at the end of the array, we return
1298  * the first byte that is not 0xff, after
1299  * having encountered at least one 0xff.)
1300  * Return: 0 if a marker is found, 1 if the end of the array is reached
1301  *
1302  * In jpeg, 0xff is used to mark the end of a data segment.
1303  * There may be more than one 0xff in succession. But not every
1304  * 0xff marks the end of a segment. It is possible, though
1305  * rare, that 0xff can occur within some data. In that case,
1306  * the marker is "escaped", by following it with 0x00.
1307  *
1308  * getNextJpegMarker parses a jpeg data stream. It
1309  * doesn't <really> get the next marker, because it doesn't
1310  * check if the 0xff is escaped. But the caller checks for
1311  * this escape condition, and ignores the marker if escaped.
1312  */
1313 static l_int32
1315  l_int32 size,
1316  l_int32 *pindex)
1317 {
1318 l_uint8 val;
1319 l_int32 index;
1320 
1321  PROCNAME("getNextJpegMarker");
1322 
1323  if (!array)
1324  return ERROR_INT("array not defined", procName, 1);
1325  if (!pindex)
1326  return ERROR_INT("&index not defined", procName, 1);
1327 
1328  index = *pindex;
1329 
1330  while (index < size) { /* skip to 0xff */
1331  val = array[index++];
1332  if (val == 0xff)
1333  break;
1334  }
1335 
1336  while (index < size) { /* skip repeated 0xff */
1337  val = array[index++];
1338  if (val != 0xff)
1339  break;
1340  }
1341 
1342  *pindex = index - 1;
1343  if (index >= size)
1344  return 1;
1345  else
1346  return 0;
1347 }
1348 
1349 
1350 static l_int32
1352  l_int32 index)
1353 {
1354  return (l_int32)((array[index]) << 8) + (l_int32)(array[index + 1]);
1355 }
1356 
1357 
1358 
1359 /*-------------------------------------------------------------*
1360  * For tiff g4 compressed images *
1361  *-------------------------------------------------------------*/
1362 /*!
1363  * convertTiffG4ToPSEmbed()
1364  *
1365  * Input: filein (input jpeg file)
1366  * fileout (output ps file)
1367  * Return: 0 if OK, 1 on error
1368  *
1369  * Notes:
1370  * (1) This function takes a g4 compressed tif file as input and
1371  * generates a g4 compressed, ascii85 encoded PS file, with
1372  * a bounding box.
1373  * (2) The bounding box is required when a program such as TeX
1374  * (through epsf) places and rescales the image.
1375  * (3) The bounding box is sized for fitting the image to an
1376  * 8.5 x 11.0 inch page.
1377  * (4) We paint this through a mask, over whatever is below.
1378  */
1379 l_int32
1380 convertTiffG4ToPSEmbed(const char *filein,
1381  const char *fileout)
1382 {
1383 char *pstring, *pstring2, *outstr;
1384 char *data85; /* ascii85 encoded ccitt g4 data */
1385 char bigbuf[512];
1386 l_uint8 *bindata; /* binary encoded ccitt g4 data */
1387 l_int32 minisblack; /* TRUE or FALSE */
1388 l_int32 w, h;
1389 l_int32 nbinbytes, nbytes85, psbytes, psbytes2, totbytes;
1390 l_float32 xpt, ypt, wpt, hpt;
1391 SARRAY *sa, *sa2;
1392 
1393  PROCNAME("convertTiffG4ToPSEmbed");
1394 
1395  if (!filein)
1396  return ERROR_INT("filein not defined", procName, 1);
1397  if (!fileout)
1398  return ERROR_INT("fileout not defined", procName, 1);
1399 
1400  /* the returned ccitt g4 data in memory is the block of
1401  * bytes in the tiff file, starting after 8 bytes and
1402  * ending before the directory. */
1403  if (extractTiffG4DataFromFile(filein, &bindata, &nbinbytes,
1404  &w, &h, &minisblack))
1405  return ERROR_INT("bindata not extracted from file", procName, 1);
1406 
1407  /* Convert the ccittg4 encoded data to ascii85 */
1408  data85 = encodeAscii85(bindata, nbinbytes, &nbytes85);
1409  FREE((void *)bindata);
1410  if (!data85)
1411  return ERROR_INT("data85 not made", procName, 1);
1412 
1413  /* scale for 20 pt boundary and otherwise full filling
1414  * in one direction on 8.5 x 11 inch device */
1415  xpt = 20.0;
1416  ypt = 20.0;
1417  if (w * 11.0 > h * 8.5) {
1418  wpt = 572.0; /* 612 - 2 * 20 */
1419  hpt = wpt * (l_float32)h / (l_float32)w;
1420  }
1421  else {
1422  hpt = 752.0; /* 792 - 2 * 20 */
1423  wpt = hpt * (l_float32)w / (l_float32)h;
1424  }
1425 
1426  /* -------- generate PostScript output -------- */
1427  if ((sa = sarrayCreate(50)) == NULL)
1428  return ERROR_INT("sa not made", procName, 1);
1429 
1430  sarrayAddString(sa, "%!PS-Adobe-3.0", 1);
1431  sarrayAddString(sa, "%%Creator: leptonica", 1);
1432  sprintf(bigbuf, "%%%%Title: %s", filein);
1433  sarrayAddString(sa, bigbuf, 1);
1434  sarrayAddString(sa, "%%DocumentData: Clean7Bit", 1);
1435  sprintf(bigbuf,
1436  "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
1437  xpt, ypt, xpt + wpt, ypt + hpt);
1438  sarrayAddString(sa, bigbuf, 1);
1439 
1440  sarrayAddString(sa, "%%LanguageLevel: 2", 1);
1441  sarrayAddString(sa, "%%EndComments", 1);
1442  sarrayAddString(sa, "%%Page: 1 1", 1);
1443 
1444  sarrayAddString(sa, "save", 1);
1445  sarrayAddString(sa, "100 dict begin", 1);
1446 
1447  sprintf(bigbuf,
1448  "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
1449  sarrayAddString(sa, bigbuf, 1);
1450 
1451  sprintf(bigbuf,
1452  "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
1453  sarrayAddString(sa, bigbuf, 1);
1454 
1455  sarrayAddString(sa, "/DeviceGray setcolorspace", 1);
1456 
1457  sarrayAddString(sa, "{", 1);
1458  sarrayAddString(sa, " /RawData currentfile /ASCII85Decode filter def", 1);
1459  sarrayAddString(sa, " << ", 1);
1460  sarrayAddString(sa, " /ImageType 1", 1);
1461  sprintf(bigbuf, " /Width %d", w);
1462  sarrayAddString(sa, bigbuf, 1);
1463  sprintf(bigbuf, " /Height %d", h);
1464  sarrayAddString(sa, bigbuf, 1);
1465  sprintf(bigbuf, " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
1466  sarrayAddString(sa, bigbuf, 1);
1467  sarrayAddString(sa, " /BitsPerComponent 1", 1);
1468  sarrayAddString(sa, " /Interpolate true", 1);
1469  if (minisblack)
1470  sarrayAddString(sa, " /Decode [1 0]", 1);
1471  else /* miniswhite; typical for 1 bpp */
1472  sarrayAddString(sa, " /Decode [0 1]", 1);
1473  sarrayAddString(sa, " /DataSource RawData", 1);
1474  sarrayAddString(sa, " <<", 1);
1475  sarrayAddString(sa, " /K -1", 1);
1476  sprintf(bigbuf, " /Columns %d", w);
1477  sarrayAddString(sa, bigbuf, 1);
1478  sprintf(bigbuf, " /Rows %d", h);
1479  sarrayAddString(sa, bigbuf, 1);
1480  sarrayAddString(sa, " >> /CCITTFaxDecode filter", 1);
1481  sarrayAddString(sa, " >> imagemask", 1);
1482  sarrayAddString(sa, " RawData flushfile", 1);
1483  sarrayAddString(sa, " showpage", 1);
1484  sarrayAddString(sa, "}", 1);
1485 
1486  sarrayAddString(sa, "%%BeginData:", 1);
1487  sarrayAddString(sa, "exec", 1);
1488 
1489  if ((pstring = sarrayToString(sa, 1)) == NULL)
1490  return ERROR_INT("pstring not made", procName, 1);
1491  psbytes = strlen(pstring);
1492  sarrayDestroy(&sa);
1493 
1494  /* concat the trailing data */
1495  sa2 = sarrayCreate(10);
1496  sarrayAddString(sa2, "%%EndData", 1);
1497  sarrayAddString(sa2, "end", 1);
1498  sarrayAddString(sa2, "restore", 1);
1499  if ((pstring2 = sarrayToString(sa2, 1)) == NULL)
1500  return ERROR_INT("pstring2 not made", procName, 1);
1501  psbytes2 = strlen(pstring2);
1502  sarrayDestroy(&sa2);
1503 
1504  /* add the ascii85 data */
1505  totbytes = psbytes + psbytes2 + nbytes85;
1506  if ((outstr = (char *)CALLOC(totbytes + 4, sizeof(char))) == NULL)
1507  return ERROR_INT("outstr not made", procName, 1);
1508  memcpy(outstr, pstring, psbytes);
1509  memcpy(outstr + psbytes, data85, nbytes85);
1510  memcpy(outstr + psbytes + nbytes85, pstring2, psbytes2);
1511  FREE((void *)data85);
1512  FREE((void *)pstring);
1513  FREE((void *)pstring2);
1514 
1515  if (arrayWrite(fileout, "w", outstr, totbytes))
1516  return ERROR_INT("ps string not written to file", procName, 1);
1517  FREE((void *)outstr);
1518  return 0;
1519 }
1520 
1521 
1522 /*!
1523  * convertTiffG4ToPS()
1524  *
1525  * Input: filein (input tiff g4 file)
1526  * fileout (output ps file)
1527  * operation ("w" for write; "a" for append)
1528  * x, y (location of LL corner of image, in pixels, relative
1529  * to the PostScript origin (0,0) at the LL corner
1530  * of the page)
1531  * res (resolution of the input image, in ppi; typ. values
1532  * are 300 and 600; use 0 for automatic determination
1533  * based on image size)
1534  * scale (scaling by printer; use 0.0 or 1.0 for no scaling)
1535  * pageno (page number; must start with 1; you can use 0
1536  * if there is only one page.)
1537  * mask (boolean: use TRUE if just painting through fg;
1538  * FALSE if painting both fg and bg.
1539  * endpage (boolean: use TRUE if the last image to be
1540  * added to the page; FALSE otherwise)
1541  * Return: 0 if OK, 1 on error
1542  *
1543  * Usage: See the usage comments in convertJpegToPS(), some of
1544  * which are repeated here.
1545  *
1546  * This is a wrapper for tiff g4. The PostScript that
1547  * is generated is expanded by about 5/4 (due to the
1548  * ascii85 encoding. If you convert to pdf (ps2pdf), the
1549  * ascii85 decoder is automatically invoked, so that the
1550  * pdf wrapped g4 file is essentially the same size as
1551  * the original g4 file. It's useful to have the PS
1552  * file ascii85 encoded, because many printers will not
1553  * print binary PS files.
1554  *
1555  * For the first image written to a file, use "w", which
1556  * opens for write and clears the file. For all subsequent
1557  * images written to that file, use "a".
1558  *
1559  * To render multiple images on the same page, set
1560  * endpage = FALSE for each image until you get to the
1561  * last, for which you set endpage = TRUE. This causes the
1562  * "showpage" command to be invoked. Showpage outputs
1563  * the entire page and clears the raster buffer for the
1564  * next page to be added. Without a "showpage",
1565  * subsequent images from the next page will overlay those
1566  * previously put down.
1567  *
1568  * For multiple images to the same page, where you are writing
1569  * both jpeg and tiff-g4, you have two options:
1570  *
1571  * (1) write the g4 first, as either image (mask == false)
1572  * or imagemask (mask == true), and then write the
1573  * jpeg over it.
1574  *
1575  * (2) write the jpeg first and as the last item, write
1576  * the g4 as an imagemask (mask == true), to paint
1577  * through the foreground only.
1578  *
1579  * We have this flexibility with the tiff-g4 because it is 1 bpp.
1580  *
1581  * For multiple pages, increment the page number, starting
1582  * with page 1. This allows PostScript (and PDF) to build
1583  * a page directory, which viewers use for navigation.
1584  */
1585 l_int32
1586 convertTiffG4ToPS(const char *filein,
1587  const char *fileout,
1588  const char *operation,
1589  l_int32 x,
1590  l_int32 y,
1591  l_int32 res,
1592  l_float32 scale,
1593  l_int32 pageno,
1594  l_int32 mask,
1595  l_int32 endpage)
1596 {
1597 char *outstr;
1598 l_int32 nbytes;
1599 
1600  PROCNAME("convertTiffG4ToPS");
1601 
1602  if (!filein)
1603  return ERROR_INT("filein not defined", procName, 1);
1604  if (!fileout)
1605  return ERROR_INT("fileout not defined", procName, 1);
1606  if (strcmp(operation, "w") && strcmp(operation, "a"))
1607  return ERROR_INT("operation must be \"w\" or \"a\"", procName, 1);
1608 
1609  if (convertTiffG4ToPSString(filein, &outstr, &nbytes, x, y, res, scale,
1610  pageno, mask, endpage))
1611  return ERROR_INT("ps string not made", procName, 1);
1612 
1613  if (arrayWrite(fileout, operation, outstr, nbytes))
1614  return ERROR_INT("ps string not written to file", procName, 1);
1615 
1616  FREE((void *)outstr);
1617  return 0;
1618 }
1619 
1620 
1621 /*!
1622  * convertTiffG4ToPSString()
1623  *
1624  * Generates PS string in G4 compressed tiff format from G4 tiff file
1625  *
1626  * Input: filein (input tiff g4 file)
1627  * &poutstr (<return> PS string)
1628  * &nbytes (<return> number of bytes in PS string)
1629  * x, y (location of LL corner of image, in pixels, relative
1630  * to the PostScript origin (0,0) at the LL corner
1631  * of the page)
1632  * res (resolution of the input image, in ppi; typ. values
1633  * are 300 and 600; use 0 for automatic determination
1634  * based on image size)
1635  * scale (scaling by printer; use 0.0 or 1.0 for no scaling)
1636  * pageno (page number; must start with 1; you can use 0
1637  * if there is only one page.)
1638  * mask (boolean: use TRUE if just painting through fg;
1639  * FALSE if painting both fg and bg.
1640  * endpage (boolean: use TRUE if the last image to be
1641  * added to the page; FALSE otherwise)
1642  * Return: 0 if OK, 1 on error
1643  *
1644  * Note: The returned PS character array is binary string, not a
1645  * null-terminated C string. It has null bytes embedded in it!
1646  *
1647  * Usage: See convertTiffG4ToPS()
1648  */
1649 l_int32
1650 convertTiffG4ToPSString(const char *filein,
1651  char **poutstr,
1652  l_int32 *pnbytes,
1653  l_int32 x,
1654  l_int32 y,
1655  l_int32 res,
1656  l_float32 scale,
1657  l_int32 pageno,
1658  l_int32 mask,
1659  l_int32 endpage)
1660 {
1661 char *pstring, *pstring2, *outstr;
1662 char *data85; /* ascii85 encoded ccitt g4 data */
1663 char bigbuf[BUF_SIZE];
1664 l_uint8 *bindata; /* binary encoded ccitt g4 data */
1665 l_int32 minisblack; /* TRUE or FALSE */
1666 l_int32 w, h;
1667 l_int32 nbinbytes, nbytes85, psbytes, psbytes2, totbytes;
1668 l_float32 xpt, ypt, wpt, hpt;
1669 SARRAY *sa, *sa2;
1670 
1671  PROCNAME("convertTiffG4ToPSString");
1672 
1673  if (!filein)
1674  return ERROR_INT("filein not defined", procName, 1);
1675  if (!poutstr)
1676  return ERROR_INT("&outstr not defined", procName, 1);
1677  if (!pnbytes)
1678  return ERROR_INT("&nbytes not defined", procName, 1);
1679  *poutstr = NULL;
1680 
1681  /* the returned ccitt g4 data in memory is the block of
1682  * bytes in the tiff file, starting after 8 bytes and
1683  * ending before the directory. */
1684  if (extractTiffG4DataFromFile(filein, &bindata, &nbinbytes,
1685  &w, &h, &minisblack))
1686  return ERROR_INT("bindata not extracted from file", procName, 1);
1687 
1688 #if DEBUG_G4
1689 /* arrayWrite("junkarray", "w", bindata, nbinbytes); */
1690  fprintf(stderr, "nbinbytes = %d, w = %d, h = %d, minisblack = %d\n",
1691  nbinbytes, w, h, minisblack);
1692 #endif /* DEBUG_G4 */
1693 
1694  /* Convert the ccittg4 encoded data to ascii85 */
1695  data85 = encodeAscii85(bindata, nbinbytes, &nbytes85);
1696  FREE((void *)bindata);
1697  if (!data85)
1698  return ERROR_INT("data85 not made", procName, 1);
1699 
1700  /* get scaled location in pts */
1701  if (scale == 0.0)
1702  scale = 1.0;
1703  if (res == 0) {
1704  if (h <= 3300)
1705  res = 300;
1706  else
1707  res = 600;
1708  }
1709  xpt = scale * x * 72. / res;
1710  ypt = scale * y * 72. / res;
1711  wpt = scale * w * 72. / res;
1712  hpt = scale * h * 72. / res;
1713 
1714 #if DEBUG_G4
1715  fprintf(stderr, "xpt = %7.2f, ypt = %7.2f, wpt = %7.2f, hpt = %7.2f\n",
1716  xpt, ypt, wpt, hpt);
1717 #endif /* DEBUG_G4 */
1718 
1719  /* -------- generate PostScript output -------- */
1720  if ((sa = sarrayCreate(50)) == NULL)
1721  return ERROR_INT("sa not made", procName, 1);
1722 
1723  sarrayAddString(sa, "%!PS-Adobe-3.0", 1);
1724  sarrayAddString(sa, "%%Creator: leptonica", 1);
1725  sprintf(bigbuf, "%%%%Title: %s", filein);
1726  sarrayAddString(sa, bigbuf, 1);
1727  sarrayAddString(sa, "%%DocumentData: Clean7Bit", 1);
1728 #if PRINT_BOUNDING_BOX
1729  sprintf(bigbuf,
1730  "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
1731  xpt, ypt, xpt + wpt, ypt + hpt);
1732  sarrayAddString(sa, bigbuf, 1);
1733 #endif /* PRINT_BOUNDING_BOX */
1734 
1735  sarrayAddString(sa, "%%LanguageLevel: 2", 1);
1736  sarrayAddString(sa, "%%EndComments", 1);
1737  sprintf(bigbuf, "%%%%Page: %d %d", pageno, pageno);
1738  sarrayAddString(sa, bigbuf, 1);
1739 
1740  sarrayAddString(sa, "save", 1);
1741  sarrayAddString(sa, "100 dict begin", 1);
1742 
1743  sprintf(bigbuf,
1744  "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
1745  sarrayAddString(sa, bigbuf, 1);
1746 
1747  sprintf(bigbuf,
1748  "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
1749  sarrayAddString(sa, bigbuf, 1);
1750 
1751  sarrayAddString(sa, "/DeviceGray setcolorspace", 1);
1752 
1753  sarrayAddString(sa, "{", 1);
1754  sarrayAddString(sa, " /RawData currentfile /ASCII85Decode filter def", 1);
1755  sarrayAddString(sa, " << ", 1);
1756  sarrayAddString(sa, " /ImageType 1", 1);
1757  sprintf(bigbuf, " /Width %d", w);
1758  sarrayAddString(sa, bigbuf, 1);
1759  sprintf(bigbuf, " /Height %d", h);
1760  sarrayAddString(sa, bigbuf, 1);
1761  sprintf(bigbuf, " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
1762  sarrayAddString(sa, bigbuf, 1);
1763  sarrayAddString(sa, " /BitsPerComponent 1", 1);
1764  sarrayAddString(sa, " /Interpolate true", 1);
1765  if (minisblack)
1766  sarrayAddString(sa, " /Decode [1 0]", 1);
1767  else /* miniswhite; typical for 1 bpp */
1768  sarrayAddString(sa, " /Decode [0 1]", 1);
1769  sarrayAddString(sa, " /DataSource RawData", 1);
1770  sarrayAddString(sa, " <<", 1);
1771  sarrayAddString(sa, " /K -1", 1);
1772  sprintf(bigbuf, " /Columns %d", w);
1773  sarrayAddString(sa, bigbuf, 1);
1774  sprintf(bigbuf, " /Rows %d", h);
1775  sarrayAddString(sa, bigbuf, 1);
1776  sarrayAddString(sa, " >> /CCITTFaxDecode filter", 1);
1777  if (mask == TRUE) /* just paint through the fg */
1778  sarrayAddString(sa, " >> imagemask", 1);
1779  else /* paint full image */
1780  sarrayAddString(sa, " >> image", 1);
1781  sarrayAddString(sa, " RawData flushfile", 1);
1782  if (endpage == TRUE)
1783  sarrayAddString(sa, " showpage", 1);
1784  sarrayAddString(sa, "}", 1);
1785 
1786  sarrayAddString(sa, "%%BeginData:", 1);
1787  sarrayAddString(sa, "exec", 1);
1788 
1789  if ((pstring = sarrayToString(sa, 1)) == NULL)
1790  return ERROR_INT("pstring not made", procName, 1);
1791  psbytes = strlen(pstring);
1792 
1793  /* concat the trailing data */
1794  sa2 = sarrayCreate(10);
1795  sarrayAddString(sa2, "%%EndData", 1);
1796  sarrayAddString(sa2, "end", 1);
1797  sarrayAddString(sa2, "restore", 1);
1798  if ((pstring2 = sarrayToString(sa2, 1)) == NULL)
1799  return ERROR_INT("pstring2 not made", procName, 1);
1800  psbytes2 = strlen(pstring2);
1801 
1802  /* add the ascii85 data */
1803  totbytes = psbytes + psbytes2 + nbytes85;
1804  *pnbytes = totbytes;
1805  if ((outstr = (char *)CALLOC(totbytes + 4, sizeof(char))) == NULL)
1806  return ERROR_INT("outstr not made", procName, 1);
1807  *poutstr = outstr;
1808  memcpy(outstr, pstring, psbytes);
1809  memcpy(outstr + psbytes, data85, nbytes85);
1810  memcpy(outstr + psbytes + nbytes85, pstring2, psbytes2);
1811 
1812  sarrayDestroy(&sa);
1813  sarrayDestroy(&sa2);
1814  FREE((void *)data85);
1815  FREE((void *)pstring);
1816  FREE((void *)pstring2);
1817  return 0;
1818 }
1819 
1820 
1821 /*!
1822  * extractTiffG4DataFromFile()
1823  *
1824  * Input: filein
1825  * &data (binary data of ccitt g4 encoded stream)
1826  * &nbytes (size of binary data)
1827  * &w (image width)
1828  * &h (image height)
1829  * &minisblack (boolean, but must use l_uint16)
1830  * Return: 0 if OK, 1 on error
1831  */
1832 l_int32
1833 extractTiffG4DataFromFile(const char *filein,
1834  l_uint8 **pdata,
1835  l_int32 *pnbytes,
1836  l_int32 *pw,
1837  l_int32 *ph,
1838  l_int32 *pminisblack)
1839 {
1840 l_uint8 *inarray, *data;
1841 l_uint16 minisblack, comptype; /* accessors require l_uint16 */
1842 l_int32 format, fbytes, nbytes;
1843 l_uint32 w, h, rowsperstrip; /* accessors require l_uint32 */
1844 l_uint32 diroff;
1845 FILE *fpin;
1846 TIFF *tif;
1847 
1848  PROCNAME("extractTiffG4DataFromFile");
1849 
1850  if (!pdata)
1851  return ERROR_INT("&data not defined", procName, 1);
1852  if (!pnbytes || !pw || !ph || !pminisblack)
1853  return ERROR_INT("&nbytes, &w, &h, &minisblack not all defined",
1854  procName, 1);
1855  *pdata = NULL;
1856  *pnbytes = *pw = *ph = *pminisblack = 0;
1857 
1858  if ((fpin = fopen(filein, "rb")) == NULL)
1859  return ERROR_INT("filein not defined", procName, 1);
1860  format = findFileFormat(fpin);
1861  fclose(fpin);
1862  if (format != IFF_TIFF)
1863  return ERROR_INT("filein not tiff", procName, 1);
1864 
1865  if ((inarray = arrayRead(filein, &fbytes)) == NULL)
1866  return ERROR_INT("inarray not made", procName, 1);
1867 
1868  /* get metadata about the image */
1869  if ((tif = TIFFOpen(filein, "rb")) == NULL)
1870  return ERROR_INT("tif not open for read", procName, 1);
1871  TIFFGetField(tif, TIFFTAG_COMPRESSION, &comptype);
1872  if (comptype != COMPRESSION_CCITTFAX4) {
1873  FREE((void *)inarray);
1874  TIFFClose(tif);
1875  return ERROR_INT("filein is not g4 compressed", procName, 1);
1876  }
1877 
1880  TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1881  if (h != rowsperstrip)
1882  L_WARNING("more than 1 strip", procName);
1883  TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &minisblack); /* for 1 bpp */
1884 /* TIFFPrintDirectory(tif, stderr, 0); */
1885  TIFFClose(tif);
1886  *pw = (l_int32)w;
1887  *ph = (l_int32)h;
1888  *pminisblack = (l_int32)minisblack;
1889 
1890  /* The header has 8 bytes: the first 2 are the magic number,
1891  * the next 2 are the version, and the last 4 are the
1892  * offset to the first directory. That's what we want here.
1893  * We have to test the byte order before decoding 4 bytes! */
1894  if (inarray[0] == 0x4d) { /* big-endian */
1895  diroff = (inarray[4] << 24) | (inarray[5] << 16) |
1896  (inarray[6] << 8) | inarray[7];
1897  }
1898  else { /* inarray[0] == 0x49 : little-endian */
1899  diroff = (inarray[7] << 24) | (inarray[6] << 16) |
1900  (inarray[5] << 8) | inarray[4];
1901  }
1902 /* fprintf(stderr, " diroff = %d, %x\n", diroff, diroff); */
1903 
1904  /* Extract the ccittg4 encoded data from the tiff file.
1905  * We skip the 8 byte header and take nbytes of data,
1906  * up to the beginning of the directory (at diroff) */
1907  nbytes = diroff - 8;
1908  *pnbytes = nbytes;
1909  if ((data = (l_uint8 *)CALLOC(nbytes, sizeof(l_uint8))) == NULL) {
1910  FREE((void *)inarray);
1911  return ERROR_INT("data not allocated", procName, 1);
1912  }
1913  *pdata = data;
1914  memcpy(data, inarray + 8, nbytes);
1915  FREE((void *)inarray);
1916 
1917  return 0;
1918 }
1919 
1920 
1921 /*-------------------------------------------------------------*
1922  * For tiff multipage files *
1923  *-------------------------------------------------------------*/
1924 /*!
1925  * convertTiffMultipageToPS()
1926  *
1927  * Input: filein (input tiff multipage file)
1928  * fileout (output ps file)
1929  * tempfile (<optional> for temporary g4 tiffs;
1930  * use NULL for default)
1931  * factor (for filling 8.5 x 11 inch page;
1932  * use 0.0 for DEFAULT_FILL_FRACTION)
1933  * Return: 0 if OK, 1 on error
1934  *
1935  * This converts a multipage tiff file of binary page images
1936  * into a ccitt g4 compressed PS file. If the images are
1937  * generated from a standard resolution fax, the vertical
1938  * resolution is doubled to give a normal-looking aspect ratio.
1939  */
1940 l_int32
1941 convertTiffMultipageToPS(const char *filein,
1942  const char *fileout,
1943  const char *tempfile,
1944  l_float32 fillfract)
1945 {
1946 const char tempdefault[] = "/usr/tmp/junk_temp_g4.tif";
1947 const char *tempname;
1948 l_int32 i, npages, w, h;
1950 PIX *pix, *pixs;
1951 FILE *fp;
1952 
1953  PROCNAME("convertTiffMultipageToPS");
1954 
1955  if (!filein)
1956  return ERROR_INT("filein not defined", procName, 1);
1957  if (!fileout)
1958  return ERROR_INT("fileout not defined", procName, 1);
1959 
1960  if ((fp = fopen(filein, "rb")) == NULL)
1961  return ERROR_INT("file not found", procName, 1);
1962  if (findFileFormat(fp) != IFF_TIFF)
1963  return ERROR_INT("file not tiff format", procName, 1);
1964  tiffGetCount(fp, &npages);
1965  fclose(fp);
1966 
1967  if (tempfile)
1968  tempname = tempfile;
1969  else
1970  tempname = tempdefault;
1971 
1972  if (fillfract == 0.0)
1973  fillfract = DEFAULT_FILL_FRACTION;
1974 
1975  for (i = 0; i < npages; i++) {
1976  if ((pix = pixReadTiff(filein, i)) == NULL)
1977  return ERROR_INT("pix not made", procName, 1);
1978 
1979  w = pixGetWidth(pix);
1980  h = pixGetHeight(pix);
1981  if (w == 1728 && h < w) /* it's a std res fax */
1982  pixs = pixScale(pix, 1.0, 2.0);
1983  else
1984  pixs = pixClone(pix);
1985 
1986  pixWrite(tempname, pixs, IFF_TIFF_G4);
1987  scale = L_MIN(fillfract * 2550 / w, fillfract * 3300 / h);
1988  if (i == 0)
1989  convertTiffG4ToPS(tempname, fileout, "w", 0, 0, 300, scale,
1990  i + 1, FALSE, TRUE);
1991  else
1992  convertTiffG4ToPS(tempname, fileout, "a", 0, 0, 300, scale,
1993  i + 1, FALSE, TRUE);
1994  pixDestroy(&pix);
1995  pixDestroy(&pixs);
1996  }
1997 
1998  return 0;
1999 }
2000 
2001 
2002 /*-------------------------------------------------------------*
2003  * Converting resolution *
2004  *-------------------------------------------------------------*/
2005 /*!
2006  * getResLetterPage()
2007  *
2008  * Input: w (image width, pixels)
2009  * h (image height, pixels)
2010  * fillfract (fraction in linear dimension of full page, not
2011  * to be exceeded; use 0 for default)
2012  * Return: 0 if OK, 1 on error
2013  */
2014 l_int32
2016  l_int32 h,
2017  l_float32 fillfract)
2018 {
2019 l_int32 resw, resh, res;
2020 
2021  if (fillfract == 0.0)
2022  fillfract = DEFAULT_FILL_FRACTION;
2023  resw = (l_int32)((w * 72.) / (LETTER_WIDTH * fillfract));
2024  resh = (l_int32)((h * 72.) / (LETTER_HEIGHT * fillfract));
2025  res = L_MAX(resw, resh);
2026  return res;
2027 }
2028 
2029 
2030 /*!
2031  * getResA4Page()
2032  *
2033  * Input: w (image width, pixels)
2034  * h (image height, pixels)
2035  * fillfract (fraction in linear dimension of full page, not
2036  * to be exceeded; use 0 for default)
2037  * Return: 0 if OK, 1 on error
2038  */
2039 l_int32
2041  l_int32 h,
2042  l_float32 fillfract)
2043 {
2044 l_int32 resw, resh, res;
2045 
2046  if (fillfract == 0.0)
2047  fillfract = DEFAULT_FILL_FRACTION;
2048  resw = (l_int32)((w * 72.) / (A4_WIDTH * fillfract));
2049  resh = (l_int32)((h * 72.) / (A4_HEIGHT * fillfract));
2050  res = L_MAX(resw, resh);
2051  return res;
2052 }
2053 
2054 
2055 
2056 /*-------------------------------------------------------------*
2057  * Utility for encoding and decoding data with ascii85 *
2058  *-------------------------------------------------------------*/
2059 /*!
2060  * encodeAscii85()
2061  *
2062  * Input: inarray (input data)
2063  * insize (number of bytes in input array)
2064  * &outsize (<return> number of bytes in output char array)
2065  * Return: chara (with 64 characters + \n in each line)
2066  *
2067  * Note: Ghostscript has a stack break if the last line of
2068  * data only has a '>', so we avoid the problem by
2069  * always putting '~>' on the last line.
2070  */
2071 char *
2073  l_int32 insize,
2074  l_int32 *poutsize)
2075 {
2076 char *chara;
2077 char *outbuf;
2078 l_int32 maxsize, i, index, outindex, linecount, nbout, eof;
2079 
2080  PROCNAME("encodeAscii85");
2081 
2082  if (!inarray)
2083  return (char *)ERROR_PTR("inarray not defined", procName, NULL);
2084 
2085  /* accumulate results in chara */
2086  maxsize = (l_int32)(80. + (insize * 5. / 4.) * (1. + 2. / MAX_85_LINE_COUNT));
2087  if ((chara = (char *)CALLOC(maxsize, sizeof(char))) == NULL)
2088  return (char *)ERROR_PTR("chara not made", procName, NULL);
2089 
2090  if ((outbuf = (char *)CALLOC(8, sizeof(char))) == NULL)
2091  return (char *)ERROR_PTR("outbuf not made", procName, NULL);
2092 
2093  linecount = 0;
2094  index = 0;
2095  outindex = 0;
2096  while (1) {
2097  eof = convertChunkToAscii85(inarray, insize, &index, outbuf, &nbout);
2098  for (i = 0; i < nbout; i++) {
2099  chara[outindex++] = outbuf[i];
2100  linecount++;
2101  if (linecount >= MAX_85_LINE_COUNT) {
2102  chara[outindex++] = '\n';
2103  linecount = 0;
2104  }
2105  }
2106  if (eof == TRUE) {
2107  if (linecount != 0)
2108  chara[outindex++] = '\n';
2109  chara[outindex++] = '~';
2110  chara[outindex++] = '>';
2111  chara[outindex++] = '\n';
2112  break;
2113  }
2114  }
2115 
2116  FREE((void *)outbuf);
2117  *poutsize = outindex;
2118 
2119 #if 0
2120  for (i = 0; i < outindex; i++)
2121  fprintf(stderr, " %c", chara[i]);
2122  fprintf(stderr, "\n");
2123 #endif
2124 
2125  return chara;
2126 }
2127 
2128 
2129 /*!
2130  * convertChunkToAscii85()
2131  *
2132  * Input: inarray (input data)
2133  * insize (number of bytes in input array)
2134  * &index (use and <return> -- ptr)
2135  * outbuf (holds 8 ascii chars; we use no more than 7)
2136  * &nbsout (<return> number of bytes written to outbuf)
2137  * Return: boolean for eof (0 if more data, 1 if end of file)
2138  *
2139  * Note: Attempts to read 4 bytes and write 5.
2140  * Writes 1 byte if the value is 0.
2141  * Writes 2 extra bytes if EOF.
2142  */
2143 l_int32
2145  l_int32 insize,
2146  l_int32 *pindex,
2147  char *outbuf,
2148  l_int32 *pnbout)
2149 {
2150 l_uint8 inbyte;
2151 l_uint32 inword, val;
2152 l_int32 eof, index, nread, nbout, i;
2153 
2154  eof = FALSE;
2155  index = *pindex;
2156  nread = L_MIN(4, (insize - index));
2157  if (insize == index + nread)
2158  eof = TRUE;
2159  *pindex += nread; /* save new index */
2160 
2161  /* read input data and save in l_uint32 */
2162  inword = 0;
2163  for (i = 0; i < nread; i++) {
2164  inbyte = inarray[index + i];
2165  inword += inbyte << (8 * (3 - i));
2166  }
2167 
2168 #if 0
2169  fprintf(stderr, "index = %d, nread = %d\n", index, nread);
2170  fprintf(stderr, "inword = %x\n", inword);
2171  fprintf(stderr, "eof = %d\n", eof);
2172 #endif
2173 
2174  /* special case: output 1 byte only */
2175  if (inword == 0) {
2176  outbuf[0] = 'z';
2177  nbout = 1;
2178  }
2179  else { /* output nread + 1 bytes */
2180  for (i = 4; i >= 4 - nread; i--) {
2181  val = inword / power85[i];
2182  outbuf[4 - i] = (l_uint8)(val + '!');
2183  inword -= val * power85[i];
2184  }
2185  nbout = nread + 1;
2186  }
2187  *pnbout = nbout;
2188 
2189  return eof;
2190 }
2191 
2192 
2193 /*!
2194  * decodeAscii85()
2195  *
2196  * Input: inarray (ascii85 input data)
2197  * insize (number of bytes in input array)
2198  * &outsize (<return> number of bytes in output l_uint8 array)
2199  * Return: outarray (binary)
2200  *
2201  * Note: we assume the data is properly encoded, so we do not check
2202  * for invalid characters or the final '>' character. We permit
2203  * whitespace to be added to the encoding in an arbitrary way.
2204  */
2205 l_uint8 *
2206 decodeAscii85(char *ina,
2207  l_int32 insize,
2208  l_int32 *poutsize)
2209 {
2210 char inc;
2211 char *pin;
2212 l_uint8 val;
2213 l_uint8 *outa;
2214 l_int32 maxsize, ocount, bytecount, index;
2215 l_uint32 oword;
2216 
2217  PROCNAME("decodeAscii85");
2218 
2219  if (!ina)
2220  return (l_uint8 *)ERROR_PTR("ina not defined", procName, NULL);
2221 
2222  /* accumulate results in outa */
2223  maxsize = (l_int32)(80. + (insize * 4. / 5.)); /* plenty big */
2224  if ((outa = (l_uint8 *)CALLOC(maxsize, sizeof(l_uint8))) == NULL)
2225  return (l_uint8 *)ERROR_PTR("outa not made", procName, NULL);
2226 
2227  pin = ina;
2228  ocount = 0; /* byte index into outa */
2229  oword = 0;
2230  for (index = 0, bytecount = 0; index < insize; index++, pin++) {
2231  inc = *pin;
2232 
2233  if (inc == ' ' || inc == '\t' || inc == '\n' ||
2234  inc == '\f' || inc == '\r' || inc == '\v') /* ignore white space */
2235  continue;
2236 
2237  val = inc - '!';
2238  if (val < 85) {
2239  oword = oword * 85 + val;
2240  if (bytecount < 4)
2241  bytecount++;
2242  else { /* we have all 5 input chars for the oword */
2243  outa[ocount] = (oword >> 24) & 0xff;
2244  outa[ocount + 1] = (oword >> 16) & 0xff;
2245  outa[ocount + 2] = (oword >> 8) & 0xff;
2246  outa[ocount + 3] = oword & 0xff;
2247  ocount += 4;
2248  bytecount = 0;
2249  oword = 0;
2250  }
2251  }
2252  else if (inc == 'z' && bytecount == 0) {
2253  outa[ocount] = 0;
2254  outa[ocount + 1] = 0;
2255  outa[ocount + 2] = 0;
2256  outa[ocount + 3] = 0;
2257  ocount += 4;
2258  }
2259  else if (inc == '~') { /* end of data */
2260  fprintf(stderr, " %d extra bytes output\n", bytecount - 1);
2261  switch (bytecount) {
2262  case 0: /* normal eof */
2263  case 1: /* error */
2264  break;
2265  case 2: /* 1 extra byte */
2266  oword = oword * (85 * 85 * 85) + 0xffffff;
2267  outa[ocount] = (oword >> 24) & 0xff;
2268  break;
2269  case 3: /* 2 extra bytes */
2270  oword = oword * (85 * 85) + 0xffff;
2271  outa[ocount] = (oword >> 24) & 0xff;
2272  outa[ocount + 1] = (oword >> 16) & 0xff;
2273  break;
2274  case 4: /* 3 extra bytes */
2275  oword = oword * 85 + 0xff;
2276  outa[ocount] = (oword >> 24) & 0xff;
2277  outa[ocount + 1] = (oword >> 16) & 0xff;
2278  outa[ocount + 2] = (oword >> 8) & 0xff;
2279  break;
2280  }
2281  if (bytecount > 1)
2282  ocount += (bytecount - 1);
2283  break;
2284  }
2285  }
2286  *poutsize = ocount;
2287 
2288  return outa;
2289 }
2290 
int linecount
Definition: afm2pfm.c:107
int level
Definition: afm2pl.c:1694
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:98
static int npages
Definition: backend_pdf.c:75
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
int w
Definition: dviconv.c:26
int h
Definition: dviconv.c:9
#define fopen
Definition: xxstdio.h:21
int strcmp()
Definition: coll.cpp:143
static void endpage(void)
Definition: dvidvi.c:1180
struct rect data
Definition: dvipdfm.c:64
#define PROCNAME(name)
Definition: environ.h:131
#define ERROR_PTR(a, b, c)
Definition: environ.h:132
unsigned short l_uint16
Definition: environ.h:31
unsigned int l_uint32
Definition: environ.h:33
unsigned char l_uint8
Definition: environ.h:29
#define L_WARNING(a, b)
Definition: environ.h:136
#define ERROR_INT(a, b, c)
Definition: environ.h:133
int l_int32
Definition: environ.h:32
#define L_WARNING_INT(a, b, c)
Definition: environ.h:137
float l_float32
Definition: environ.h:34
#define d(n)
Definition: gpos-common.c:151
#define memcpy(d, s, n)
Definition: gsftopk.c:64
const unsigned char FREE
Definition: image.cpp:34
@ IFF_TIFF_G4
Definition: imageio.h:35
@ IFF_TIFF
Definition: imageio.h:32
@ IFF_JFIF_JPEG
Definition: imageio.h:30
unsigned nbytes
Definition: in_pcx.cpp:355
pix
Definition: in_pcx.cpp:383
uchar outbuf[(1000000+1000000)]
Definition: unzcrash.c:41
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
kerning y
Definition: ttdriver.c:212
#define fclose
Definition: debug.h:100
#define fprintf
Definition: mendex.h:64
#define length(c)
Definition: ctangleboot.c:65
Code related to b fwrite(a, sizeof(char), b, stdout) @d C_printf(c
boolean eof(FILE *file)
Definition: eofeoln.c:11
char tempfile[100]
Definition: splitup.c:51
#define CALLOC(t, n)
Definition: hash.c:21
#define sprintf
Definition: snprintf.c:44
l_uint32 * pixGetData(PIX *pix)
Definition: pix1.c:793
l_uint8 * arrayRead(const char *fname, l_int32 *pnbytes)
Definition: utils.c:776
void pixDestroy(PIX **ppix)
Definition: pix1.c:225
SARRAY * sarrayCreate(l_int32 n)
Definition: sarray.c:117
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
Definition: scale.c:131
l_int32 arrayWrite(const char *filename, const char *operation, void *data, l_int32 nbytes)
Definition: utils.c:873
l_int32 findFileFormat(FILE *fp)
Definition: readfile.c:186
l_int32 pixGetWpl(PIX *pix)
Definition: pix1.c:477
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
Definition: pixconv.c:198
l_int32 pixGetDepth(PIX *pix)
Definition: pix1.c:449
l_int32 tiffGetCount(FILE *fp, l_int32 *pn)
Definition: tiffio.c:775
void sarrayDestroy(SARRAY **psa)
Definition: sarray.c:270
PIX * pixConvertForPSWrap(PIX *pixs)
Definition: pixconv.c:1866
PIX * pixRead(const char *filename)
Definition: readfile.c:64
l_int32 pixWrite(const char *filename, PIX *pix, l_int32 format)
Definition: writefile.c:113
l_int32 sarrayAddString(SARRAY *sa, char *string, l_int32 copyflag)
Definition: sarray.c:333
PIX * pixConvert16To8(PIX *pixs, l_int32 whichbyte)
Definition: pixconv.c:802
PIX * pixReadTiff(const char *filename, l_int32 n)
Definition: tiffio.c:78
PIX * pixClone(PIX *pixs)
Definition: pix1.c:197
l_int32 pixGetHeight(PIX *pix)
Definition: pix1.c:419
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
Definition: sarray.c:528
l_int32 pixGetWidth(PIX *pix)
Definition: pix1.c:389
TIFF * TIFFOpen(const char *name, const char *mode)
Definition: tif_acorn.c:438
void TIFFClose(TIFF *tif)
Definition: tif_close.c:33
int TIFFGetField(TIFF *tif, ttag_t tag,...)
Definition: tif_dir.c:869
#define TIFFTAG_PHOTOMETRIC
Definition: tiff.h:176
#define TIFFTAG_IMAGEWIDTH
Definition: tiff.h:146
#define TIFFTAG_ROWSPERSTRIP
Definition: tiff.h:211
#define TIFFTAG_IMAGELENGTH
Definition: tiff.h:147
#define TIFFTAG_COMPRESSION
Definition: tiff.h:149
#define COMPRESSION_CCITTFAX4
Definition: tiff.h:153
#define L_MIN
Definition: manifests.h:69
#define L_MAX
Definition: manifests.h:80
char pageno[99]
Definition: mkind.c:62
@ oword
Definition: mtxline.h:23
float x
Definition: cordic.py:15
int k
Definition: otp-parser.c:70
static int format
Definition: pbmclean.c:15
#define res(length)
Definition: picttoppm.c:287
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:113
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
#define fp
#define index(s, c)
Definition: plain2.h:351
integer nib[360]
Definition: pmxab.c:90
double scale
Definition: pnmhistmap.c:38
static int size
Definition: ppmlabel.c:24
char line[1024]
Definition: process_score.c:29
#define mask(n)
Definition: lbitlib.c:93
#define inarray(t, key)
Definition: lj_tab.h:63
Definition: pix.h:292
Definition: pix.h:51
Definition: array.h:70
Definition: jquant2.c:258
Definition: mendex.h:20
Definition: bdf.c:133
Definition: sh2.c:920
Definition: tiffiop.h:70
Definition: strexpr.c:21
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
*job_name strlen((char *) job_name) - 4)
val
Definition: tex4ht.c:3227
static unsigned short bps
Definition: tifftopnm.c:58
static unsigned short spp
Definition: tifftopnm.c:58
static const char * TEMP_JPEG_FILE
Definition: psio.c:102
char * pixWriteStringPS(PIX *pixs, BOX *box, l_int32 res, l_float32 scale)
Definition: psio.c:384
char * encodeAscii85(l_uint8 *inarray, l_int32 insize, l_int32 *poutsize)
Definition: psio.c:2072
static const char * TEMP_G4TIFF_FILE
Definition: psio.c:101
void getScaledParametersPS(BOX *box, l_int32 wpix, l_int32 hpix, l_int32 res, l_float32 scale, l_float32 *pxpt, l_float32 *pypt, l_float32 *pwpt, l_float32 *phpt)
Definition: psio.c:555
l_int32 convertTiffG4ToPS(const char *filein, const char *fileout, const char *operation, l_int32 x, l_int32 y, l_int32 res, l_float32 scale, l_int32 pageno, l_int32 mask, l_int32 endpage)
Definition: psio.c:1586
l_int32 extractJpegDataFromFile(const char *filein, l_uint8 **pdata, l_int32 *pnbytes, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp)
Definition: psio.c:1095
static l_int32 getNextJpegMarker(l_uint8 *, l_int32, l_int32 *)
Definition: psio.c:1314
static l_int32 getTwoByteParameter(l_uint8 *, l_int32)
Definition: psio.c:1351
static const l_int32 MAX_RES
Definition: psio.c:107
void convertByteToHexAscii(l_uint8 byteval, char *pnib1, char *pnib2)
Definition: psio.c:633
l_int32 convertTiffMultipageToPS(const char *filein, const char *fileout, const char *tempfile, l_float32 fillfract)
Definition: psio.c:1941
l_int32 convertTiffG4ToPSString(const char *filein, char **poutstr, l_int32 *pnbytes, l_int32 x, l_int32 y, l_int32 res, l_float32 scale, l_int32 pageno, l_int32 mask, l_int32 endpage)
Definition: psio.c:1650
l_int32 convertToPSEmbed(const char *filein, const char *fileout, l_int32 level)
Definition: psio.c:168
static const l_int32 LETTER_WIDTH
Definition: psio.c:111
l_uint8 * decodeAscii85(char *ina, l_int32 insize, l_int32 *poutsize)
Definition: psio.c:2206
static const l_int32 MIN_RES
Definition: psio.c:106
l_int32 getResA4Page(l_int32 w, l_int32 h, l_float32 fillfract)
Definition: psio.c:2040
l_int32 convertTiffG4ToPSEmbed(const char *filein, const char *fileout)
Definition: psio.c:1380
static const l_int32 BUF_SIZE
Definition: psio.c:104
l_int32 convertJpegToPS(const char *filein, const char *fileout, const char *operation, l_int32 x, l_int32 y, l_int32 res, l_float32 scale, l_int32 pageno, l_int32 endpage)
Definition: psio.c:870
static const l_uint32 power85[5]
Definition: psio.c:117
l_int32 convertJpegToPSEmbed(const char *filein, const char *fileout)
Definition: psio.c:673
static const l_int32 MAX_85_LINE_COUNT
Definition: psio.c:108
l_int32 extractTiffG4DataFromFile(const char *filein, l_uint8 **pdata, l_int32 *pnbytes, l_int32 *pw, l_int32 *ph, l_int32 *pminisblack)
Definition: psio.c:1833
l_int32 pixWriteStreamPS(FILE *fp, PIX *pix, BOX *box, l_int32 res, l_float32 scale)
Definition: psio.c:294
static l_int32 locateJpegImageParameters(l_uint8 *, l_int32, l_int32 *)
Definition: psio.c:1227
static const l_int32 A4_WIDTH
Definition: psio.c:113
static const l_int32 LETTER_HEIGHT
Definition: psio.c:112
l_int32 convertJpegToPSString(const char *filein, char **poutstr, l_int32 *pnbytes, l_int32 x, l_int32 y, l_int32 res, l_float32 scale, l_int32 pageno, l_int32 endpage)
Definition: psio.c:929
static const l_float32 DEFAULT_FILL_FRACTION
Definition: psio.c:115
l_int32 getResLetterPage(l_int32 w, l_int32 h, l_float32 fillfract)
Definition: psio.c:2015
l_int32 convertChunkToAscii85(l_uint8 *inarray, l_int32 insize, l_int32 *pindex, char *outbuf, l_int32 *pnbout)
Definition: psio.c:2144
l_int32 pixWritePSEmbed(const char *filein, const char *fileout)
Definition: psio.c:244
l_int32 extractJpegDataFromArray(const void *data, l_int32 nbytes, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp)
Definition: psio.c:1154
static const l_int32 A4_HEIGHT
Definition: psio.c:114
static const l_int32 DEFAULT_PRINTER_RES
Definition: psio.c:105
@ msize
Definition: preamble.c:50