Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
psio2.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
96#ifdef HAVE_CONFIG_H
97#include <config_auto.h>
98#endif /* HAVE_CONFIG_H */
99
100#include <string.h>
101#include "allheaders.h"
102
103/* --------------------------------------------*/
104#if USE_PSIO /* defined in environ.h */
105 /* --------------------------------------------*/
106
107 /* Set default for writing bounding box hint */
108static l_int32 var_PS_WRITE_BOUNDING_BOX = 1;
109
110#define Bufsize 512
111static const l_int32 DefaultInputRes = 300; /* typical scan res, ppi */
112static const l_int32 MinRes = 5;
113static const l_int32 MaxRes = 3000;
114
115 /* For computing resolution that fills page to desired amount */
116static const l_int32 LetterWidth = 612; /* points */
117static const l_int32 LetterHeight = 792; /* points */
118static const l_int32 A4Width = 595; /* points */
119static const l_int32 A4Height = 842; /* points */
120static const l_float32 DefaultFillFraction = 0.95f;
121
122#ifndef NO_CONSOLE_IO
123#define DEBUG_JPEG 0
124#define DEBUG_G4 0
125#define DEBUG_FLATE 0
126#endif /* ~NO_CONSOLE_IO */
127
128/* Note that the bounding box hint at the top of the generated PostScript
129 * file is required for the "*Embed" functions. These generate a
130 * PostScript file for an individual image that can be translated and
131 * scaled by an application that embeds the image in its output
132 * (e.g., in the PS output from a TeX file).
133 * However, bounding box hints should not be embedded in any
134 * PostScript image that will be composited with other images,
135 * where more than one image may be placed in an arbitrary location
136 * on a page. */
137
138 /* Static helper functions */
139static void getScaledParametersPS(BOX *box, l_int32 wpix, l_int32 hpix,
140 l_int32 res, l_float32 scale,
141 l_float32 *pxpt, l_float32 *pypt,
142 l_float32 *pwpt, l_float32 *phpt);
143static void convertByteToHexAscii(l_uint8 byteval, char *pnib1, char *pnib2);
144static l_ok convertJpegToPSString(const char *filein, char **poutstr,
145 l_int32 *pnbytes, l_int32 x, l_int32 y,
146 l_int32 res, l_float32 scale,
147 l_int32 pageno, l_int32 endpage);
148static char *generateJpegPS(const char *filein, L_COMP_DATA *cid,
149 l_float32 xpt, l_float32 ypt, l_float32 wpt,
150 l_float32 hpt, l_int32 pageno, l_int32 endpage);
151static l_ok convertG4ToPSString(const char *filein, char **poutstr,
152 l_int32 *pnbytes, l_int32 x, l_int32 y,
153 l_int32 res, l_float32 scale, l_int32 pageno,
154 l_int32 maskflag, l_int32 endpage);
155static char *generateG4PS(const char *filein, L_COMP_DATA *cid, l_float32 xpt,
156 l_float32 ypt, l_float32 wpt, l_float32 hpt,
157 l_int32 maskflag, l_int32 pageno, l_int32 endpage);
158static l_ok convertFlateToPSString(const char *filein, char **poutstr,
159 l_int32 *pnbytes, l_int32 x, l_int32 y,
160 l_int32 res, l_float32 scale,
161 l_int32 pageno, l_int32 endpage);
162static char *generateFlatePS(const char *filein, L_COMP_DATA *cid,
163 l_float32 xpt, l_float32 ypt, l_float32 wpt,
164 l_float32 hpt, l_int32 pageno, l_int32 endpage);
165
166
167/*-------------------------------------------------------------*
168 * For uncompressed images *
169 *-------------------------------------------------------------*/
187l_ok
188pixWritePSEmbed(const char *filein,
189 const char *fileout)
190{
191l_int32 w, h, ret;
192l_float32 scale;
193FILE *fp;
194PIX *pix;
195
196 if (!filein)
197 return ERROR_INT("filein not defined", __func__, 1);
198 if (!fileout)
199 return ERROR_INT("fileout not defined", __func__, 1);
200
201 if ((pix = pixRead(filein)) == NULL)
202 return ERROR_INT("image not read from file", __func__, 1);
203 w = pixGetWidth(pix);
204 h = pixGetHeight(pix);
205 if (w * 11.0 > h * 8.5)
206 scale = 8.5f * 300.f / (l_float32)w;
207 else
208 scale = 11.0f * 300.f / (l_float32)h;
209
210 if ((fp = fopenWriteStream(fileout, "wb")) == NULL)
211 return ERROR_INT_1("file not opened for write", fileout, __func__, 1);
212 ret = pixWriteStreamPS(fp, pix, NULL, 0, scale);
213 fclose(fp);
214
215 pixDestroy(&pix);
216 return ret;
217}
218
219
238l_ok
240 PIX *pix,
241 BOX *box,
242 l_int32 res,
243 l_float32 scale)
244{
245char *outstr;
246l_int32 length;
247PIX *pixc;
248
249 if (!fp)
250 return (l_int32)ERROR_INT("stream not open", __func__, 1);
251 if (!pix)
252 return (l_int32)ERROR_INT("pix not defined", __func__, 1);
253
254 if ((pixc = pixConvertForPSWrap(pix)) == NULL)
255 return (l_int32)ERROR_INT("pixc not made", __func__, 1);
256
257 if ((outstr = pixWriteStringPS(pixc, box, res, scale)) == NULL) {
258 pixDestroy(&pixc);
259 return (l_int32)ERROR_INT("outstr not made", __func__, 1);
260 }
261 length = strlen(outstr);
262 fwrite(outstr, 1, length, fp);
263 LEPT_FREE(outstr);
264 pixDestroy(&pixc);
265 return 0;
266}
267
268
336char *
338 BOX *box,
339 l_int32 res,
340 l_float32 scale)
341{
342char nib1, nib2;
343char *hexdata, *outstr;
344l_uint8 byteval;
345l_int32 i, j, k, w, h, d;
346l_float32 wpt, hpt, xpt, ypt;
347l_int32 wpl, psbpl, hexbytes, boxflag, bps;
348l_uint32 *line, *data;
349PIX *pix;
350
351 if (!pixs)
352 return (char *)ERROR_PTR("pixs not defined", __func__, NULL);
353
354 if ((pix = pixConvertForPSWrap(pixs)) == NULL)
355 return (char *)ERROR_PTR("pix not made", __func__, NULL);
356 pixGetDimensions(pix, &w, &h, &d);
357
358 /* Get the factors by which PS scales and translates, in pts */
359 if (!box)
360 boxflag = 0; /* no scaling; b.b. at center */
361 else
362 boxflag = 1; /* no b.b., specify placement and optional scaling */
363 getScaledParametersPS(box, w, h, res, scale, &xpt, &ypt, &wpt, &hpt);
364
365 if (d == 1)
366 bps = 1; /* bits/sample */
367 else /* d == 8 || d == 32 */
368 bps = 8;
369
370 /* Convert image data to hex string. psbpl is the number of
371 * bytes in each raster line when it is packed to the byte
372 * boundary (not the 32 bit word boundary, as with the pix).
373 * When converted to hex, the hex string has 2 bytes for
374 * every byte of raster data. */
375 wpl = pixGetWpl(pix);
376 if (d == 1 || d == 8)
377 psbpl = (w * d + 7) / 8;
378 else /* d == 32 */
379 psbpl = 3 * w;
380 data = pixGetData(pix);
381 hexbytes = 2 * psbpl * h; /* size of ps hex array */
382 if ((hexdata = (char *)LEPT_CALLOC(hexbytes + 1, sizeof(char))) == NULL)
383 return (char *)ERROR_PTR("hexdata not made", __func__, NULL);
384 if (d == 1 || d == 8) {
385 for (i = 0, k = 0; i < h; i++) {
386 line = data + i * wpl;
387 for (j = 0; j < psbpl; j++) {
388 byteval = GET_DATA_BYTE(line, j);
389 convertByteToHexAscii(byteval, &nib1, &nib2);
390 hexdata[k++] = nib1;
391 hexdata[k++] = nib2;
392 }
393 }
394 } else { /* d == 32; hexdata bytes packed RGBRGB..., 2 per sample */
395 for (i = 0, k = 0; i < h; i++) {
396 line = data + i * wpl;
397 for (j = 0; j < w; j++) {
398 byteval = GET_DATA_BYTE(line + j, 0); /* red */
399 convertByteToHexAscii(byteval, &nib1, &nib2);
400 hexdata[k++] = nib1;
401 hexdata[k++] = nib2;
402 byteval = GET_DATA_BYTE(line + j, 1); /* green */
403 convertByteToHexAscii(byteval, &nib1, &nib2);
404 hexdata[k++] = nib1;
405 hexdata[k++] = nib2;
406 byteval = GET_DATA_BYTE(line + j, 2); /* blue */
407 convertByteToHexAscii(byteval, &nib1, &nib2);
408 hexdata[k++] = nib1;
409 hexdata[k++] = nib2;
410 }
411 }
412 }
413 hexdata[k] = '\0';
414
415 outstr = generateUncompressedPS(hexdata, w, h, d, psbpl, bps,
416 xpt, ypt, wpt, hpt, boxflag);
417 pixDestroy(&pix);
418 if (!outstr)
419 return (char *)ERROR_PTR("outstr not made", __func__, NULL);
420 return outstr;
421}
422
423
444char *
446 l_int32 w,
447 l_int32 h,
448 l_int32 d,
449 l_int32 psbpl,
450 l_int32 bps,
451 l_float32 xpt,
452 l_float32 ypt,
453 l_float32 wpt,
454 l_float32 hpt,
455 l_int32 boxflag)
456{
457char *outstr;
458char bigbuf[Bufsize];
459SARRAY *sa;
460
461 if (!hexdata)
462 return (char *)ERROR_PTR("hexdata not defined", __func__, NULL);
463
464 sa = sarrayCreate(0);
465 sarrayAddString(sa, "%!Adobe-PS", L_COPY);
466 if (boxflag == 0) {
467 snprintf(bigbuf, sizeof(bigbuf),
468 "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
469 xpt, ypt, xpt + wpt, ypt + hpt);
470 sarrayAddString(sa, bigbuf, L_COPY);
471 } else { /* boxflag == 1 */
472 sarrayAddString(sa, "gsave", L_COPY);
473 }
474
475 if (d == 1)
476 sarrayAddString(sa,
477 "{1 exch sub} settransfer %invert binary", L_COPY);
478
479 snprintf(bigbuf, sizeof(bigbuf),
480 "/bpl %d string def %%bpl as a string", psbpl);
481 sarrayAddString(sa, bigbuf, L_COPY);
482 snprintf(bigbuf, sizeof(bigbuf),
483 "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
484 sarrayAddString(sa, bigbuf, L_COPY);
485 snprintf(bigbuf, sizeof(bigbuf),
486 "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
487 sarrayAddString(sa, bigbuf, L_COPY);
488 snprintf(bigbuf, sizeof(bigbuf),
489 "%d %d %d %%image dimensions in pixels", w, h, bps);
490 sarrayAddString(sa, bigbuf, L_COPY);
491 snprintf(bigbuf, sizeof(bigbuf),
492 "[%d %d %d %d %d %d] %%mapping matrix: [w 0 0 -h 0 h]",
493 w, 0, 0, -h, 0, h);
494 sarrayAddString(sa, bigbuf, L_COPY);
495
496 if (boxflag == 0) {
497 if (d == 1 || d == 8)
498 sarrayAddString(sa,
499 "{currentfile bpl readhexstring pop} image", L_COPY);
500 else /* d == 32 */
501 sarrayAddString(sa,
502 "{currentfile bpl readhexstring pop} false 3 colorimage",
503 L_COPY);
504 } else { /* boxflag == 1 */
505 if (d == 1 || d == 8)
506 sarrayAddString(sa,
507 "{currentfile bpl readhexstring pop} bind image", L_COPY);
508 else /* d == 32 */
509 sarrayAddString(sa,
510 "{currentfile bpl readhexstring pop} bind false 3 colorimage",
511 L_COPY);
512 }
513
514 sarrayAddString(sa, hexdata, L_INSERT);
515
516 if (boxflag == 0)
517 sarrayAddString(sa, "\nshowpage", L_COPY);
518 else /* boxflag == 1 */
519 sarrayAddString(sa, "\ngrestore", L_COPY);
520
521 outstr = sarrayToString(sa, 1);
522 sarrayDestroy(&sa);
523 if (!outstr) L_ERROR("outstr not made\n", __func__);
524 return outstr;
525}
526
527
549static void
551 l_int32 wpix,
552 l_int32 hpix,
553 l_int32 res,
554 l_float32 scale,
555 l_float32 *pxpt,
556 l_float32 *pypt,
557 l_float32 *pwpt,
558 l_float32 *phpt)
559{
560l_int32 bx, by, bw, bh;
561l_float32 winch, hinch, xinch, yinch, fres;
562
563 if (res == 0)
564 res = DefaultInputRes;
565 fres = (l_float32)res;
566
567 /* Allow the PS interpreter to scale the resolution */
568 if (scale == 0.0)
569 scale = 1.0;
570 if (scale != 1.0) {
571 fres = (l_float32)res / scale;
572 res = (l_int32)fres;
573 }
574
575 /* Limit valid resolution interval */
576 if (res < MinRes || res > MaxRes) {
577 L_WARNING("res %d out of bounds; using default res; no scaling\n",
578 __func__, res);
579 res = DefaultInputRes;
580 fres = (l_float32)res;
581 }
582
583 if (!box) { /* center on page */
584 winch = (l_float32)wpix / fres;
585 hinch = (l_float32)hpix / fres;
586 xinch = (8.5f - winch) / 2.f;
587 yinch = (11.0f - hinch) / 2.f;
588 } else {
589 boxGetGeometry(box, &bx, &by, &bw, &bh);
590 if (bw == 0)
591 winch = (l_float32)wpix / fres;
592 else
593 winch = (l_float32)bw / 1000.f;
594 if (bh == 0)
595 hinch = (l_float32)hpix / fres;
596 else
597 hinch = (l_float32)bh / 1000.f;
598 xinch = (l_float32)bx / 1000.f;
599 yinch = (l_float32)by / 1000.f;
600 }
601
602 if (xinch < 0)
603 L_WARNING("left edge < 0.0 inch\n", __func__);
604 if (xinch + winch > 8.5)
605 L_WARNING("right edge > 8.5 inch\n", __func__);
606 if (yinch < 0.0)
607 L_WARNING("bottom edge < 0.0 inch\n", __func__);
608 if (yinch + hinch > 11.0)
609 L_WARNING("top edge > 11.0 inch\n", __func__);
610
611 *pwpt = 72.f * winch;
612 *phpt = 72.f * hinch;
613 *pxpt = 72.f * xinch;
614 *pypt = 72.f * yinch;
615 return;
616}
617
618
626static void
627convertByteToHexAscii(l_uint8 byteval,
628 char *pnib1,
629 char *pnib2)
630{
631l_uint8 nib;
632
633 nib = byteval >> 4;
634 if (nib < 10)
635 *pnib1 = '0' + nib;
636 else
637 *pnib1 = 'a' + (nib - 10);
638 nib = byteval & 0xf;
639 if (nib < 10)
640 *pnib2 = '0' + nib;
641 else
642 *pnib2 = 'a' + (nib - 10);
643 return;
644}
645
646
647/*-------------------------------------------------------------*
648 * For jpeg compressed images *
649 *-------------------------------------------------------------*/
667l_ok
668convertJpegToPSEmbed(const char *filein,
669 const char *fileout)
670{
671char *outstr;
672l_int32 w, h, nbytes, ret;
673l_float32 xpt, ypt, wpt, hpt;
674L_COMP_DATA *cid;
675
676 if (!filein)
677 return ERROR_INT("filein not defined", __func__, 1);
678 if (!fileout)
679 return ERROR_INT("fileout not defined", __func__, 1);
680
681 /* Generate the ascii encoded jpeg data */
682 if ((cid = l_generateJpegData(filein, 1)) == NULL)
683 return ERROR_INT("jpeg data not made", __func__, 1);
684 w = cid->w;
685 h = cid->h;
686
687 /* Scale for 20 pt boundary and otherwise full filling
688 * in one direction on 8.5 x 11 inch device */
689 xpt = 20.0;
690 ypt = 20.0;
691 if (w * 11.0 > h * 8.5) {
692 wpt = 572.0; /* 612 - 2 * 20 */
693 hpt = wpt * (l_float32)h / (l_float32)w;
694 } else {
695 hpt = 752.0; /* 792 - 2 * 20 */
696 wpt = hpt * (l_float32)w / (l_float32)h;
697 }
698
699 /* Generate the PS.
700 * The bounding box information should be inserted (default). */
701 outstr = generateJpegPS(NULL, cid, xpt, ypt, wpt, hpt, 1, 1);
702 l_CIDataDestroy(&cid);
703 if (!outstr)
704 return ERROR_INT("outstr not made", __func__, 1);
705 nbytes = strlen(outstr);
706
707 ret = l_binaryWrite(fileout, "w", outstr, nbytes);
708 LEPT_FREE(outstr);
709 if (ret) L_ERROR("ps string not written to file\n", __func__);
710 return ret;
711}
712
713
781l_ok
782convertJpegToPS(const char *filein,
783 const char *fileout,
784 const char *operation,
785 l_int32 x,
786 l_int32 y,
787 l_int32 res,
788 l_float32 scale,
789 l_int32 pageno,
790 l_int32 endpage)
791{
792char *outstr;
793l_int32 nbytes;
794
795 if (!filein)
796 return ERROR_INT("filein not defined", __func__, 1);
797 if (!fileout)
798 return ERROR_INT("fileout not defined", __func__, 1);
799 if (strcmp(operation, "w") && strcmp(operation, "a"))
800 return ERROR_INT("operation must be \"w\" or \"a\"", __func__, 1);
801
802 if (convertJpegToPSString(filein, &outstr, &nbytes, x, y, res, scale,
803 pageno, endpage))
804 return ERROR_INT("ps string not made", __func__, 1);
805
806 if (l_binaryWrite(fileout, operation, outstr, nbytes)) {
807 LEPT_FREE(outstr);
808 return ERROR_INT("ps string not written to file", __func__, 1);
809 }
810
811 LEPT_FREE(outstr);
812 return 0;
813}
814
815
841static l_ok
842convertJpegToPSString(const char *filein,
843 char **poutstr,
844 l_int32 *pnbytes,
845 l_int32 x,
846 l_int32 y,
847 l_int32 res,
848 l_float32 scale,
849 l_int32 pageno,
850 l_int32 endpage)
851{
852char *outstr;
853l_float32 xpt, ypt, wpt, hpt;
854L_COMP_DATA *cid;
855
856 if (!poutstr)
857 return ERROR_INT("&outstr not defined", __func__, 1);
858 if (!pnbytes)
859 return ERROR_INT("&nbytes not defined", __func__, 1);
860 *poutstr = NULL;
861 *pnbytes = 0;
862 if (!filein)
863 return ERROR_INT("filein not defined", __func__, 1);
864
865 /* Generate the ascii encoded jpeg data */
866 if ((cid = l_generateJpegData(filein, 1)) == NULL)
867 return ERROR_INT("jpeg data not made", __func__, 1);
868
869 /* Get scaled location in pts. Guess the input scan resolution
870 * based on the input parameter %res, the resolution data in
871 * the pix, and the size of the image. */
872 if (scale == 0.0)
873 scale = 1.0;
874 if (res <= 0) {
875 if (cid->res > 0)
876 res = cid->res;
877 else
878 res = DefaultInputRes;
879 }
880
881 /* Get scaled location in pts */
882 if (scale == 0.0)
883 scale = 1.0;
884 xpt = scale * x * 72.f / res;
885 ypt = scale * y * 72.f / res;
886 wpt = scale * cid->w * 72.f / res;
887 hpt = scale * cid->h * 72.f / res;
888
889 if (pageno == 0)
890 pageno = 1;
891
892#if DEBUG_JPEG
893 lept_stderr("w = %d, h = %d, bps = %d, spp = %d\n",
894 cid->w, cid->h, cid->bps, cid->spp);
895 lept_stderr("comp bytes = %ld, nbytes85 = %ld, ratio = %5.3f\n",
896 (unsigned long)cid->nbytescomp, (unsigned long)cid->nbytes85,
897 (l_float32)cid->nbytes85 / (l_float32)cid->nbytescomp);
898 lept_stderr("xpt = %7.2f, ypt = %7.2f, wpt = %7.2f, hpt = %7.2f\n",
899 xpt, ypt, wpt, hpt);
900#endif /* DEBUG_JPEG */
901
902 /* Generate the PS */
903 outstr = generateJpegPS(NULL, cid, xpt, ypt, wpt, hpt, pageno, endpage);
904 l_CIDataDestroy(&cid);
905 if (!outstr)
906 return ERROR_INT("outstr not made", __func__, 1);
907 *poutstr = outstr;
908 *pnbytes = strlen(outstr);
909 return 0;
910}
911
912
933static char *
934generateJpegPS(const char *filein,
935 L_COMP_DATA *cid,
936 l_float32 xpt,
937 l_float32 ypt,
938 l_float32 wpt,
939 l_float32 hpt,
940 l_int32 pageno,
941 l_int32 endpage)
942{
943l_int32 w, h, bps, spp;
944char *outstr;
945char bigbuf[Bufsize];
946SARRAY *sa;
947
948 if (!cid)
949 return (char *)ERROR_PTR("jpeg data not defined", __func__, NULL);
950 w = cid->w;
951 h = cid->h;
952 bps = cid->bps;
953 spp = cid->spp;
954
955 sa = sarrayCreate(50);
956 sarrayAddString(sa, "%!PS-Adobe-3.0", L_COPY);
957 sarrayAddString(sa, "%%Creator: leptonica", L_COPY);
958 if (filein)
959 snprintf(bigbuf, sizeof(bigbuf), "%%%%Title: %s", filein);
960 else
961 snprintf(bigbuf, sizeof(bigbuf), "%%%%Title: Jpeg compressed PS");
962 sarrayAddString(sa, bigbuf, L_COPY);
963 sarrayAddString(sa, "%%DocumentData: Clean7Bit", L_COPY);
964
965 if (var_PS_WRITE_BOUNDING_BOX == 1) {
966 snprintf(bigbuf, sizeof(bigbuf),
967 "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
968 xpt, ypt, xpt + wpt, ypt + hpt);
969 sarrayAddString(sa, bigbuf, L_COPY);
970 }
971
972 sarrayAddString(sa, "%%LanguageLevel: 2", L_COPY);
973 sarrayAddString(sa, "%%EndComments", L_COPY);
974 snprintf(bigbuf, sizeof(bigbuf), "%%%%Page: %d %d", pageno, pageno);
975 sarrayAddString(sa, bigbuf, L_COPY);
976
977 sarrayAddString(sa, "save", L_COPY);
978 sarrayAddString(sa,
979 "/RawData currentfile /ASCII85Decode filter def", L_COPY);
980 sarrayAddString(sa, "/Data RawData << >> /DCTDecode filter def", L_COPY);
981
982 snprintf(bigbuf, sizeof(bigbuf),
983 "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
984 sarrayAddString(sa, bigbuf, L_COPY);
985
986 snprintf(bigbuf, sizeof(bigbuf),
987 "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
988 sarrayAddString(sa, bigbuf, L_COPY);
989
990 if (spp == 1)
991 sarrayAddString(sa, "/DeviceGray setcolorspace", L_COPY);
992 else if (spp == 3)
993 sarrayAddString(sa, "/DeviceRGB setcolorspace", L_COPY);
994 else /*spp == 4 */
995 sarrayAddString(sa, "/DeviceCMYK setcolorspace", L_COPY);
996
997 sarrayAddString(sa, "{ << /ImageType 1", L_COPY);
998 snprintf(bigbuf, sizeof(bigbuf), " /Width %d", w);
999 sarrayAddString(sa, bigbuf, L_COPY);
1000 snprintf(bigbuf, sizeof(bigbuf), " /Height %d", h);
1001 sarrayAddString(sa, bigbuf, L_COPY);
1002 snprintf(bigbuf, sizeof(bigbuf),
1003 " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
1004 sarrayAddString(sa, bigbuf, L_COPY);
1005 sarrayAddString(sa, " /DataSource Data", L_COPY);
1006 snprintf(bigbuf, sizeof(bigbuf), " /BitsPerComponent %d", bps);
1007 sarrayAddString(sa, bigbuf, L_COPY);
1008
1009 if (spp == 1)
1010 sarrayAddString(sa, " /Decode [0 1]", L_COPY);
1011 else if (spp == 3)
1012 sarrayAddString(sa, " /Decode [0 1 0 1 0 1]", L_COPY);
1013 else /* spp == 4 */
1014 sarrayAddString(sa, " /Decode [0 1 0 1 0 1 0 1]", L_COPY);
1015
1016 sarrayAddString(sa, " >> image", L_COPY);
1017 sarrayAddString(sa, " Data closefile", L_COPY);
1018 sarrayAddString(sa, " RawData flushfile", L_COPY);
1019 if (endpage == TRUE)
1020 sarrayAddString(sa, " showpage", L_COPY);
1021 sarrayAddString(sa, " restore", L_COPY);
1022 sarrayAddString(sa, "} exec", L_COPY);
1023
1024 /* Insert the ascii85 jpeg data; this is now owned by sa */
1025 sarrayAddString(sa, cid->data85, L_INSERT);
1026 cid->data85 = NULL; /* it has been transferred and destroyed */
1027
1028 /* Generate and return the output string */
1029 outstr = sarrayToString(sa, 1);
1030 sarrayDestroy(&sa);
1031 return outstr;
1032}
1033
1034
1035/*-------------------------------------------------------------*
1036 * For ccitt g4 compressed images *
1037 *-------------------------------------------------------------*/
1057l_ok
1058convertG4ToPSEmbed(const char *filein,
1059 const char *fileout)
1060{
1061char *outstr;
1062l_int32 w, h, nbytes, ret;
1063l_float32 xpt, ypt, wpt, hpt;
1064L_COMP_DATA *cid;
1065
1066 if (!filein)
1067 return ERROR_INT("filein not defined", __func__, 1);
1068 if (!fileout)
1069 return ERROR_INT("fileout not defined", __func__, 1);
1070
1071 if ((cid = l_generateG4Data(filein, 1)) == NULL)
1072 return ERROR_INT("g4 data not made", __func__, 1);
1073 w = cid->w;
1074 h = cid->h;
1075
1076 /* Scale for 20 pt boundary and otherwise full filling
1077 * in one direction on 8.5 x 11 inch device */
1078 xpt = 20.0;
1079 ypt = 20.0;
1080 if (w * 11.0 > h * 8.5) {
1081 wpt = 572.0; /* 612 - 2 * 20 */
1082 hpt = wpt * (l_float32)h / (l_float32)w;
1083 } else {
1084 hpt = 752.0; /* 792 - 2 * 20 */
1085 wpt = hpt * (l_float32)w / (l_float32)h;
1086 }
1087
1088 /* Generate the PS, painting through the image mask.
1089 * The bounding box information should be inserted (default). */
1090 outstr = generateG4PS(NULL, cid, xpt, ypt, wpt, hpt, 1, 1, 1);
1091 l_CIDataDestroy(&cid);
1092 if (!outstr)
1093 return ERROR_INT("outstr not made", __func__, 1);
1094 nbytes = strlen(outstr);
1095
1096 ret = l_binaryWrite(fileout, "w", outstr, nbytes);
1097 LEPT_FREE(outstr);
1098 if (ret) L_ERROR("ps string not written to file\n", __func__);
1099 return ret;
1100}
1101
1102
1161l_ok
1162convertG4ToPS(const char *filein,
1163 const char *fileout,
1164 const char *operation,
1165 l_int32 x,
1166 l_int32 y,
1167 l_int32 res,
1168 l_float32 scale,
1169 l_int32 pageno,
1170 l_int32 maskflag,
1171 l_int32 endpage)
1172{
1173char *outstr;
1174l_int32 nbytes, ret;
1175
1176 if (!filein)
1177 return ERROR_INT("filein not defined", __func__, 1);
1178 if (!fileout)
1179 return ERROR_INT("fileout not defined", __func__, 1);
1180 if (strcmp(operation, "w") && strcmp(operation, "a"))
1181 return ERROR_INT("operation must be \"w\" or \"a\"", __func__, 1);
1182
1183 if (convertG4ToPSString(filein, &outstr, &nbytes, x, y, res, scale,
1184 pageno, maskflag, endpage))
1185 return ERROR_INT("ps string not made", __func__, 1);
1186
1187 ret = l_binaryWrite(fileout, operation, outstr, nbytes);
1188 LEPT_FREE(outstr);
1189 if (ret)
1190 return ERROR_INT("ps string not written to file", __func__, 1);
1191 return 0;
1192}
1193
1194
1222static l_ok
1223convertG4ToPSString(const char *filein,
1224 char **poutstr,
1225 l_int32 *pnbytes,
1226 l_int32 x,
1227 l_int32 y,
1228 l_int32 res,
1229 l_float32 scale,
1230 l_int32 pageno,
1231 l_int32 maskflag,
1232 l_int32 endpage)
1233{
1234char *outstr;
1235l_float32 xpt, ypt, wpt, hpt;
1236L_COMP_DATA *cid;
1237
1238 if (!poutstr)
1239 return ERROR_INT("&outstr not defined", __func__, 1);
1240 if (!pnbytes)
1241 return ERROR_INT("&nbytes not defined", __func__, 1);
1242 *poutstr = NULL;
1243 *pnbytes = 0;
1244 if (!filein)
1245 return ERROR_INT("filein not defined", __func__, 1);
1246
1247 if ((cid = l_generateG4Data(filein, 1)) == NULL)
1248 return ERROR_INT("g4 data not made", __func__, 1);
1249
1250 /* Get scaled location in pts. Guess the input scan resolution
1251 * based on the input parameter %res, the resolution data in
1252 * the pix, and the size of the image. */
1253 if (scale == 0.0)
1254 scale = 1.0;
1255 if (res <= 0) {
1256 if (cid->res > 0) {
1257 res = cid->res;
1258 } else {
1259 if (cid->h <= 3509) /* A4 height at 300 ppi */
1260 res = 300;
1261 else
1262 res = 600;
1263 }
1264 }
1265 xpt = scale * x * 72.f / res;
1266 ypt = scale * y * 72.f / res;
1267 wpt = scale * cid->w * 72.f / res;
1268 hpt = scale * cid->h * 72.f / res;
1269
1270 if (pageno == 0)
1271 pageno = 1;
1272
1273#if DEBUG_G4
1274 lept_stderr("w = %d, h = %d, minisblack = %d\n",
1275 cid->w, cid->h, cid->minisblack);
1276 lept_stderr("comp bytes = %ld, nbytes85 = %ld\n",
1277 (unsigned long)cid->nbytescomp, (unsigned long)cid->nbytes85);
1278 lept_stderr("xpt = %7.2f, ypt = %7.2f, wpt = %7.2f, hpt = %7.2f\n",
1279 xpt, ypt, wpt, hpt);
1280#endif /* DEBUG_G4 */
1281
1282 /* Generate the PS */
1283 outstr = generateG4PS(NULL, cid, xpt, ypt, wpt, hpt,
1284 maskflag, pageno, endpage);
1285 l_CIDataDestroy(&cid);
1286 if (!outstr)
1287 return ERROR_INT("outstr not made", __func__, 1);
1288 *poutstr = outstr;
1289 *pnbytes = strlen(outstr);
1290 return 0;
1291}
1292
1293
1316static char *
1317generateG4PS(const char *filein,
1318 L_COMP_DATA *cid,
1319 l_float32 xpt,
1320 l_float32 ypt,
1321 l_float32 wpt,
1322 l_float32 hpt,
1323 l_int32 maskflag,
1324 l_int32 pageno,
1325 l_int32 endpage)
1326{
1327l_int32 w, h;
1328char *outstr;
1329char bigbuf[Bufsize];
1330SARRAY *sa;
1331
1332 if (!cid)
1333 return (char *)ERROR_PTR("g4 data not defined", __func__, NULL);
1334 w = cid->w;
1335 h = cid->h;
1336
1337 sa = sarrayCreate(50);
1338 sarrayAddString(sa, "%!PS-Adobe-3.0", L_COPY);
1339 sarrayAddString(sa, "%%Creator: leptonica", L_COPY);
1340 if (filein)
1341 snprintf(bigbuf, sizeof(bigbuf), "%%%%Title: %s", filein);
1342 else
1343 snprintf(bigbuf, sizeof(bigbuf), "%%%%Title: G4 compressed PS");
1344 sarrayAddString(sa, bigbuf, L_COPY);
1345 sarrayAddString(sa, "%%DocumentData: Clean7Bit", L_COPY);
1346
1347 if (var_PS_WRITE_BOUNDING_BOX == 1) {
1348 snprintf(bigbuf, sizeof(bigbuf),
1349 "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
1350 xpt, ypt, xpt + wpt, ypt + hpt);
1351 sarrayAddString(sa, bigbuf, L_COPY);
1352 }
1353
1354 sarrayAddString(sa, "%%LanguageLevel: 2", L_COPY);
1355 sarrayAddString(sa, "%%EndComments", L_COPY);
1356 snprintf(bigbuf, sizeof(bigbuf), "%%%%Page: %d %d", pageno, pageno);
1357 sarrayAddString(sa, bigbuf, L_COPY);
1358
1359 sarrayAddString(sa, "save", L_COPY);
1360 sarrayAddString(sa, "100 dict begin", L_COPY);
1361
1362 snprintf(bigbuf, sizeof(bigbuf),
1363 "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
1364 sarrayAddString(sa, bigbuf, L_COPY);
1365
1366 snprintf(bigbuf, sizeof(bigbuf),
1367 "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
1368 sarrayAddString(sa, bigbuf, L_COPY);
1369
1370 sarrayAddString(sa, "/DeviceGray setcolorspace", L_COPY);
1371
1372 sarrayAddString(sa, "{", L_COPY);
1373 sarrayAddString(sa,
1374 " /RawData currentfile /ASCII85Decode filter def", L_COPY);
1375 sarrayAddString(sa, " << ", L_COPY);
1376 sarrayAddString(sa, " /ImageType 1", L_COPY);
1377 snprintf(bigbuf, sizeof(bigbuf), " /Width %d", w);
1378 sarrayAddString(sa, bigbuf, L_COPY);
1379 snprintf(bigbuf, sizeof(bigbuf), " /Height %d", h);
1380 sarrayAddString(sa, bigbuf, L_COPY);
1381 snprintf(bigbuf, sizeof(bigbuf),
1382 " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
1383 sarrayAddString(sa, bigbuf, L_COPY);
1384 sarrayAddString(sa, " /BitsPerComponent 1", L_COPY);
1385 sarrayAddString(sa, " /Interpolate true", L_COPY);
1386 if (cid->minisblack)
1387 sarrayAddString(sa, " /Decode [1 0]", L_COPY);
1388 else /* miniswhite; typical for 1 bpp */
1389 sarrayAddString(sa, " /Decode [0 1]", L_COPY);
1390 sarrayAddString(sa, " /DataSource RawData", L_COPY);
1391 sarrayAddString(sa, " <<", L_COPY);
1392 sarrayAddString(sa, " /K -1", L_COPY);
1393 snprintf(bigbuf, sizeof(bigbuf), " /Columns %d", w);
1394 sarrayAddString(sa, bigbuf, L_COPY);
1395 snprintf(bigbuf, sizeof(bigbuf), " /Rows %d", h);
1396 sarrayAddString(sa, bigbuf, L_COPY);
1397 sarrayAddString(sa, " >> /CCITTFaxDecode filter", L_COPY);
1398 if (maskflag == TRUE) /* just paint through the fg */
1399 sarrayAddString(sa, " >> imagemask", L_COPY);
1400 else /* Paint full image */
1401 sarrayAddString(sa, " >> image", L_COPY);
1402 sarrayAddString(sa, " RawData flushfile", L_COPY);
1403 if (endpage == TRUE)
1404 sarrayAddString(sa, " showpage", L_COPY);
1405 sarrayAddString(sa, "}", L_COPY);
1406
1407 sarrayAddString(sa, "%%BeginData:", L_COPY);
1408 sarrayAddString(sa, "exec", L_COPY);
1409
1410 /* Insert the ascii85 ccittg4 data; this is now owned by sa */
1411 sarrayAddString(sa, cid->data85, L_INSERT);
1412
1413 /* Concat the trailing data */
1414 sarrayAddString(sa, "%%EndData", L_COPY);
1415 sarrayAddString(sa, "end", L_COPY);
1416 sarrayAddString(sa, "restore", L_COPY);
1417
1418 outstr = sarrayToString(sa, 1);
1419 sarrayDestroy(&sa);
1420 cid->data85 = NULL; /* it has been transferred and destroyed */
1421 return outstr;
1422}
1423
1424
1425/*-------------------------------------------------------------*
1426 * For tiff multipage files *
1427 *-------------------------------------------------------------*/
1446l_ok
1447convertTiffMultipageToPS(const char *filein,
1448 const char *fileout,
1449 l_float32 fillfract)
1450{
1451char *tempfile;
1452l_int32 i, npages, w, h, istiff;
1453l_float32 scale;
1454PIX *pix, *pixs;
1455FILE *fp;
1456
1457 if (!filein)
1458 return ERROR_INT("filein not defined", __func__, 1);
1459 if (!fileout)
1460 return ERROR_INT("fileout not defined", __func__, 1);
1461
1462 if ((fp = fopenReadStream(filein)) == NULL)
1463 return ERROR_INT_1("file not found", filein, __func__, 1);
1464 istiff = fileFormatIsTiff(fp);
1465 if (!istiff) {
1466 fclose(fp);
1467 return ERROR_INT_1("file not tiff format", filein, __func__, 1);
1468 }
1469 tiffGetCount(fp, &npages);
1470 fclose(fp);
1471
1472 if (fillfract == 0.0)
1473 fillfract = DefaultFillFraction;
1474
1475 for (i = 0; i < npages; i++) {
1476 if ((pix = pixReadTiff(filein, i)) == NULL)
1477 return ERROR_INT_1("pix not made", filein, __func__, 1);
1478
1479 pixGetDimensions(pix, &w, &h, NULL);
1480 if (w == 1728 && h < w) /* it's a std res fax */
1481 pixs = pixScale(pix, 1.0, 2.0);
1482 else
1483 pixs = pixClone(pix);
1484
1485 tempfile = l_makeTempFilename();
1486 pixWrite(tempfile, pixs, IFF_TIFF_G4);
1487 scale = L_MIN(fillfract * 2550 / w, fillfract * 3300 / h);
1488 if (i == 0)
1489 convertG4ToPS(tempfile, fileout, "w", 0, 0, 300, scale,
1490 i + 1, FALSE, TRUE);
1491 else
1492 convertG4ToPS(tempfile, fileout, "a", 0, 0, 300, scale,
1493 i + 1, FALSE, TRUE);
1494 lept_rmfile(tempfile);
1495 LEPT_FREE(tempfile);
1496 pixDestroy(&pix);
1497 pixDestroy(&pixs);
1498 }
1499
1500 return 0;
1501}
1502
1503
1504/*---------------------------------------------------------------------*
1505 * For flate (gzip) compressed images (e.g., png) *
1506 *---------------------------------------------------------------------*/
1524l_ok
1525convertFlateToPSEmbed(const char *filein,
1526 const char *fileout)
1527{
1528char *outstr;
1529l_int32 w, h, nbytes, ret;
1530l_float32 xpt, ypt, wpt, hpt;
1531L_COMP_DATA *cid;
1532
1533 if (!filein)
1534 return ERROR_INT("filein not defined", __func__, 1);
1535 if (!fileout)
1536 return ERROR_INT("fileout not defined", __func__, 1);
1537
1538 if ((cid = l_generateFlateData(filein, 1)) == NULL)
1539 return ERROR_INT("flate data not made", __func__, 1);
1540 w = cid->w;
1541 h = cid->h;
1542
1543 /* Scale for 20 pt boundary and otherwise full filling
1544 * in one direction on 8.5 x 11 inch device */
1545 xpt = 20.0;
1546 ypt = 20.0;
1547 if (w * 11.0 > h * 8.5) {
1548 wpt = 572.0; /* 612 - 2 * 20 */
1549 hpt = wpt * (l_float32)h / (l_float32)w;
1550 } else {
1551 hpt = 752.0; /* 792 - 2 * 20 */
1552 wpt = hpt * (l_float32)w / (l_float32)h;
1553 }
1554
1555 /* Generate the PS.
1556 * The bounding box information should be inserted (default). */
1557 outstr = generateFlatePS(NULL, cid, xpt, ypt, wpt, hpt, 1, 1);
1558 l_CIDataDestroy(&cid);
1559 if (!outstr)
1560 return ERROR_INT("outstr not made", __func__, 1);
1561 nbytes = strlen(outstr);
1562
1563 ret = l_binaryWrite(fileout, "w", outstr, nbytes);
1564 LEPT_FREE(outstr);
1565 if (ret) L_ERROR("ps string not written to file\n", __func__);
1566 return ret;
1567}
1568
1569
1636l_ok
1637convertFlateToPS(const char *filein,
1638 const char *fileout,
1639 const char *operation,
1640 l_int32 x,
1641 l_int32 y,
1642 l_int32 res,
1643 l_float32 scale,
1644 l_int32 pageno,
1645 l_int32 endpage)
1646{
1647char *outstr;
1648l_int32 nbytes, ret;
1649
1650 if (!filein)
1651 return ERROR_INT("filein not defined", __func__, 1);
1652 if (!fileout)
1653 return ERROR_INT("fileout not defined", __func__, 1);
1654 if (strcmp(operation, "w") && strcmp(operation, "a"))
1655 return ERROR_INT("operation must be \"w\" or \"a\"", __func__, 1);
1656
1657 if (convertFlateToPSString(filein, &outstr, &nbytes, x, y, res, scale,
1658 pageno, endpage))
1659 return ERROR_INT("ps string not made", __func__, 1);
1660
1661 ret = l_binaryWrite(fileout, operation, outstr, nbytes);
1662 LEPT_FREE(outstr);
1663 if (ret) L_ERROR("ps string not written to file\n", __func__);
1664 return ret;
1665}
1666
1667
1701static l_ok
1702convertFlateToPSString(const char *filein,
1703 char **poutstr,
1704 l_int32 *pnbytes,
1705 l_int32 x,
1706 l_int32 y,
1707 l_int32 res,
1708 l_float32 scale,
1709 l_int32 pageno,
1710 l_int32 endpage)
1711{
1712char *outstr;
1713l_float32 xpt, ypt, wpt, hpt;
1714L_COMP_DATA *cid;
1715
1716 if (!poutstr)
1717 return ERROR_INT("&outstr not defined", __func__, 1);
1718 if (!pnbytes)
1719 return ERROR_INT("&nbytes not defined", __func__, 1);
1720 *pnbytes = 0;
1721 *poutstr = NULL;
1722 if (!filein)
1723 return ERROR_INT("filein not defined", __func__, 1);
1724
1725 if ((cid = l_generateFlateData(filein, 1)) == NULL)
1726 return ERROR_INT("flate data not made", __func__, 1);
1727
1728 /* Get scaled location in pts. Guess the input scan resolution
1729 * based on the input parameter %res, the resolution data in
1730 * the pix, and the size of the image. */
1731 if (scale == 0.0)
1732 scale = 1.0;
1733 if (res <= 0) {
1734 if (cid->res > 0)
1735 res = cid->res;
1736 else
1737 res = DefaultInputRes;
1738 }
1739 xpt = scale * x * 72.f / res;
1740 ypt = scale * y * 72.f / res;
1741 wpt = scale * cid->w * 72.f / res;
1742 hpt = scale * cid->h * 72.f / res;
1743
1744 if (pageno == 0)
1745 pageno = 1;
1746
1747#if DEBUG_FLATE
1748 lept_stderr("w = %d, h = %d, bps = %d, spp = %d\n",
1749 cid->w, cid->h, cid->bps, cid->spp);
1750 lept_stderr("uncomp bytes = %ld, comp bytes = %ld, nbytes85 = %ld\n",
1751 (unsigned long)cid->nbytes, (unsigned long)cid->nbytescomp,
1752 (unsigned long)cid->nbytes85);
1753 lept_stderr("xpt = %7.2f, ypt = %7.2f, wpt = %7.2f, hpt = %7.2f\n",
1754 xpt, ypt, wpt, hpt);
1755#endif /* DEBUG_FLATE */
1756
1757 /* Generate the PS */
1758 outstr = generateFlatePS(NULL, cid, xpt, ypt, wpt, hpt, pageno, endpage);
1759 l_CIDataDestroy(&cid);
1760 if (!outstr)
1761 return ERROR_INT("outstr not made", __func__, 1);
1762 *poutstr = outstr;
1763 *pnbytes = strlen(outstr);
1764 return 0;
1765}
1766
1767
1783static char *
1784generateFlatePS(const char *filein,
1785 L_COMP_DATA *cid,
1786 l_float32 xpt,
1787 l_float32 ypt,
1788 l_float32 wpt,
1789 l_float32 hpt,
1790 l_int32 pageno,
1791 l_int32 endpage)
1792{
1793l_int32 w, h, bps, spp;
1794char *outstr;
1795char bigbuf[Bufsize];
1796SARRAY *sa;
1797
1798 if (!cid)
1799 return (char *)ERROR_PTR("flate data not defined", __func__, NULL);
1800 w = cid->w;
1801 h = cid->h;
1802 bps = cid->bps;
1803 spp = cid->spp;
1804
1805 sa = sarrayCreate(50);
1806 sarrayAddString(sa, "%!PS-Adobe-3.0 EPSF-3.0", L_COPY);
1807 sarrayAddString(sa, "%%Creator: leptonica", L_COPY);
1808 if (filein)
1809 snprintf(bigbuf, sizeof(bigbuf), "%%%%Title: %s", filein);
1810 else
1811 snprintf(bigbuf, sizeof(bigbuf), "%%%%Title: Flate compressed PS");
1812 sarrayAddString(sa, bigbuf, L_COPY);
1813 sarrayAddString(sa, "%%DocumentData: Clean7Bit", L_COPY);
1814
1815 if (var_PS_WRITE_BOUNDING_BOX == 1) {
1816 snprintf(bigbuf, sizeof(bigbuf),
1817 "%%%%BoundingBox: %7.2f %7.2f %7.2f %7.2f",
1818 xpt, ypt, xpt + wpt, ypt + hpt);
1819 sarrayAddString(sa, bigbuf, L_COPY);
1820 }
1821
1822 sarrayAddString(sa, "%%LanguageLevel: 3", L_COPY);
1823 sarrayAddString(sa, "%%EndComments", L_COPY);
1824 snprintf(bigbuf, sizeof(bigbuf), "%%%%Page: %d %d", pageno, pageno);
1825 sarrayAddString(sa, bigbuf, L_COPY);
1826
1827 sarrayAddString(sa, "save", L_COPY);
1828 snprintf(bigbuf, sizeof(bigbuf),
1829 "%7.2f %7.2f translate %%set image origin in pts", xpt, ypt);
1830 sarrayAddString(sa, bigbuf, L_COPY);
1831
1832 snprintf(bigbuf, sizeof(bigbuf),
1833 "%7.2f %7.2f scale %%set image size in pts", wpt, hpt);
1834 sarrayAddString(sa, bigbuf, L_COPY);
1835
1836 /* If there is a colormap, add the data; it is now owned by sa */
1837 if (cid->cmapdata85) {
1838 snprintf(bigbuf, sizeof(bigbuf),
1839 "[ /Indexed /DeviceRGB %d %%set colormap type/size",
1840 cid->ncolors - 1);
1841 sarrayAddString(sa, bigbuf, L_COPY);
1842 sarrayAddString(sa, " <~", L_COPY);
1843 sarrayAddString(sa, cid->cmapdata85, L_INSERT);
1844 sarrayAddString(sa, " ] setcolorspace", L_COPY);
1845 } else if (spp == 1) {
1846 sarrayAddString(sa, "/DeviceGray setcolorspace", L_COPY);
1847 } else { /* spp == 3 */
1848 sarrayAddString(sa, "/DeviceRGB setcolorspace", L_COPY);
1849 }
1850
1851 sarrayAddString(sa,
1852 "/RawData currentfile /ASCII85Decode filter def", L_COPY);
1853 sarrayAddString(sa,
1854 "/Data RawData << >> /FlateDecode filter def", L_COPY);
1855
1856 sarrayAddString(sa, "{ << /ImageType 1", L_COPY);
1857 snprintf(bigbuf, sizeof(bigbuf), " /Width %d", w);
1858 sarrayAddString(sa, bigbuf, L_COPY);
1859 snprintf(bigbuf, sizeof(bigbuf), " /Height %d", h);
1860 sarrayAddString(sa, bigbuf, L_COPY);
1861 snprintf(bigbuf, sizeof(bigbuf), " /BitsPerComponent %d", bps);
1862 sarrayAddString(sa, bigbuf, L_COPY);
1863 snprintf(bigbuf, sizeof(bigbuf),
1864 " /ImageMatrix [ %d 0 0 %d 0 %d ]", w, -h, h);
1865 sarrayAddString(sa, bigbuf, L_COPY);
1866
1867 if (cid->cmapdata85) {
1868 sarrayAddString(sa, " /Decode [0 255]", L_COPY);
1869 } else if (spp == 1) {
1870 if (bps == 1) /* miniswhite photometry */
1871 sarrayAddString(sa, " /Decode [1 0]", L_COPY);
1872 else /* bps > 1 */
1873 sarrayAddString(sa, " /Decode [0 1]", L_COPY);
1874 } else { /* spp == 3 */
1875 sarrayAddString(sa, " /Decode [0 1 0 1 0 1]", L_COPY);
1876 }
1877
1878 sarrayAddString(sa, " /DataSource Data", L_COPY);
1879 sarrayAddString(sa, " >> image", L_COPY);
1880 sarrayAddString(sa, " Data closefile", L_COPY);
1881 sarrayAddString(sa, " RawData flushfile", L_COPY);
1882 if (endpage == TRUE)
1883 sarrayAddString(sa, " showpage", L_COPY);
1884 sarrayAddString(sa, " restore", L_COPY);
1885 sarrayAddString(sa, "} exec", L_COPY);
1886
1887 /* Insert the ascii85 gzipped data; this is now owned by sa */
1888 sarrayAddString(sa, cid->data85, L_INSERT);
1889
1890 /* Generate and return the output string */
1891 outstr = sarrayToString(sa, 1);
1892 sarrayDestroy(&sa);
1893 cid->cmapdata85 = NULL; /* it has been transferred to sa and destroyed */
1894 cid->data85 = NULL; /* it has been transferred to sa and destroyed */
1895 return outstr;
1896}
1897
1898
1899/*---------------------------------------------------------------------*
1900 * Write to memory *
1901 *---------------------------------------------------------------------*/
1920l_ok
1921pixWriteMemPS(l_uint8 **pdata,
1922 size_t *psize,
1923 PIX *pix,
1924 BOX *box,
1925 l_int32 res,
1926 l_float32 scale)
1927{
1928 if (!pdata)
1929 return ERROR_INT("&data not defined", __func__, 1 );
1930 if (!psize)
1931 return ERROR_INT("&size not defined", __func__, 1 );
1932 if (!pix)
1933 return ERROR_INT("&pix not defined", __func__, 1 );
1934
1935 *pdata = (l_uint8 *)pixWriteStringPS(pix, box, res, scale);
1936 *psize = strlen((char *)(*pdata));
1937 return 0;
1938}
1939
1940
1941/*-------------------------------------------------------------*
1942 * Converting resolution *
1943 *-------------------------------------------------------------*/
1953l_int32
1955 l_int32 h,
1956 l_float32 fillfract)
1957{
1958l_int32 resw, resh, res;
1959
1960 if (fillfract == 0.0)
1961 fillfract = DefaultFillFraction;
1962 resw = (l_int32)((w * 72.) / (LetterWidth * fillfract));
1963 resh = (l_int32)((h * 72.) / (LetterHeight * fillfract));
1964 res = L_MAX(resw, resh);
1965 return res;
1966}
1967
1968
1978l_int32
1980 l_int32 h,
1981 l_float32 fillfract)
1982{
1983l_int32 resw, resh, res;
1984
1985 if (fillfract == 0.0)
1986 fillfract = DefaultFillFraction;
1987 resw = (l_int32)((w * 72.) / (A4Width * fillfract));
1988 resh = (l_int32)((h * 72.) / (A4Height * fillfract));
1989 res = L_MAX(resw, resh);
1990 return res;
1991}
1992
1993
1994/*-------------------------------------------------------------*
1995 * Setting flag for writing bounding box hint *
1996 *-------------------------------------------------------------*/
1997void
1998l_psWriteBoundingBox(l_int32 flag)
1999{
2000 var_PS_WRITE_BOUNDING_BOX = flag;
2001}
2002
2003
2004/* --------------------------------------------*/
2005#endif /* USE_PSIO */
2006/* --------------------------------------------*/
#define GET_DATA_BYTE(pdata, n)
@ L_COPY
Definition pix.h:505
@ L_INSERT
Definition pix.h:504
static char * generateFlatePS(const char *filein, L_COMP_DATA *cid, l_float32 xpt, l_float32 ypt, l_float32 wpt, l_float32 hpt, l_int32 pageno, l_int32 endpage)
generateFlatePS()
Definition psio2.c:1784
static l_ok convertG4ToPSString(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 maskflag, l_int32 endpage)
convertG4ToPSString()
Definition psio2.c:1223
l_ok convertFlateToPS(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)
convertFlateToPS()
Definition psio2.c:1637
static 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)
getScaledParametersPS()
Definition psio2.c:550
static l_ok convertFlateToPSString(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)
convertFlateToPSString()
Definition psio2.c:1702
l_ok pixWriteStreamPS(FILE *fp, PIX *pix, BOX *box, l_int32 res, l_float32 scale)
pixWriteStreamPS()
Definition psio2.c:239
l_ok 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)
convertJpegToPS()
Definition psio2.c:782
l_int32 getResA4Page(l_int32 w, l_int32 h, l_float32 fillfract)
getResA4Page()
Definition psio2.c:1979
l_ok pixWritePSEmbed(const char *filein, const char *fileout)
pixWritePSEmbed()
Definition psio2.c:188
char * pixWriteStringPS(PIX *pixs, BOX *box, l_int32 res, l_float32 scale)
pixWriteStringPS()
Definition psio2.c:337
static l_ok 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)
convertJpegToPSString()
Definition psio2.c:842
l_ok convertTiffMultipageToPS(const char *filein, const char *fileout, l_float32 fillfract)
convertTiffMultipageToPS()
Definition psio2.c:1447
static void convertByteToHexAscii(l_uint8 byteval, char *pnib1, char *pnib2)
convertByteToHexAscii()
Definition psio2.c:627
l_ok convertFlateToPSEmbed(const char *filein, const char *fileout)
convertFlateToPSEmbed()
Definition psio2.c:1525
l_ok convertG4ToPSEmbed(const char *filein, const char *fileout)
convertG4ToPSEmbed()
Definition psio2.c:1058
l_ok pixWriteMemPS(l_uint8 **pdata, size_t *psize, PIX *pix, BOX *box, l_int32 res, l_float32 scale)
pixWriteMemPS()
Definition psio2.c:1921
l_ok convertJpegToPSEmbed(const char *filein, const char *fileout)
convertJpegToPSEmbed()
Definition psio2.c:668
char * generateUncompressedPS(char *hexdata, l_int32 w, l_int32 h, l_int32 d, l_int32 psbpl, l_int32 bps, l_float32 xpt, l_float32 ypt, l_float32 wpt, l_float32 hpt, l_int32 boxflag)
generateUncompressedPS()
Definition psio2.c:445
l_ok convertG4ToPS(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 maskflag, l_int32 endpage)
convertG4ToPS()
Definition psio2.c:1162
static char * generateJpegPS(const char *filein, L_COMP_DATA *cid, l_float32 xpt, l_float32 ypt, l_float32 wpt, l_float32 hpt, l_int32 pageno, l_int32 endpage)
generateJpegPS()
Definition psio2.c:934
l_int32 getResLetterPage(l_int32 w, l_int32 h, l_float32 fillfract)
getResLetterPage()
Definition psio2.c:1954
static char * generateG4PS(const char *filein, L_COMP_DATA *cid, l_float32 xpt, l_float32 ypt, l_float32 wpt, l_float32 hpt, l_int32 maskflag, l_int32 pageno, l_int32 endpage)
generateG4PS()
Definition psio2.c:1317
l_int32 ncolors
Definition imageio.h:190
size_t nbytescomp
Definition imageio.h:185
l_int32 minisblack
Definition imageio.h:195
char * cmapdata85
Definition imageio.h:188