Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
writefile.c
1/*====================================================================*
2 - Copyright (C) 2001-2016 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
27/*
28 * writefile.c
29 *
30 * Set jpeg quality for pixWrite() and pixWriteMem()
31 * l_int32 l_jpegSetQuality()
32 *
33 * Set global variable LeptDebugOK for writing to named temp files
34 * l_int32 setLeptDebugOK()
35 *
36 * High-level procedures for writing images to file:
37 * l_int32 pixaWriteFiles()
38 * l_int32 pixWriteDebug()
39 * l_int32 pixWrite()
40 * l_int32 pixWriteAutoFormat()
41 * l_int32 pixWriteStream()
42 * l_int32 pixWriteImpliedFormat()
43 *
44 * Selection of output format if default is requested
45 * l_int32 pixChooseOutputFormat()
46 * l_int32 getImpliedFileFormat()
47 * l_int32 getFormatFromExtension()
48 * l_int32 pixGetAutoFormat()
49 * const char *getFormatExtension()
50 *
51 * Write to memory
52 * l_int32 pixWriteMem()
53 *
54 * Image display for debugging
55 * l_int32 l_fileDisplay()
56 * l_int32 pixDisplay()
57 * l_int32 pixDisplayWithTitle()
58 * PIX *pixMakeColorSquare()
59 * void l_chooseDisplayProg()
60 *
61 * Change format for missing library
62 * void changeFormatForMissingLib()
63 *
64 * Nonfunctional stub of pix output for debugging
65 * l_int32 pixDisplayWrite()
66 *
67 * Supported file formats:
68 * (1) Writing is supported without any external libraries:
69 * bmp
70 * pnm (including pbm, pgm, etc)
71 * spix (raw serialized)
72 * (2) Writing is supported with installation of external libraries:
73 * png
74 * jpg (standard jfif version)
75 * tiff (including most varieties of compression)
76 * gif
77 * webp
78 * jp2 (jpeg2000)
79 * (3) Writing is supported through special interfaces:
80 * ps (PostScript, in psio1.c, psio2.c):
81 * level 1 (uncompressed)
82 * level 2 (g4 and dct encoding: requires tiff, jpg)
83 * level 3 (g4, dct and flate encoding: requires tiff, jpg, zlib)
84 * pdf (PDF, in pdfio.c):
85 * level 1 (g4 and dct encoding: requires tiff, jpg)
86 * level 2 (g4, dct and flate encoding: requires tiff, jpg, zlib)
87 */
88
89#ifdef HAVE_CONFIG_H
90#include <config_auto.h>
91#endif /* HAVE_CONFIG_H */
92
93#include <string.h>
94#include "allheaders.h"
95
96 /* Set defaults for the display program (xv, xli, xzgv, open, irfanview)
97 * that is invoked by pixDisplay() */
98#ifdef _WIN32
99static l_int32 var_DISPLAY_PROG = L_DISPLAY_WITH_IV; /* default */
100#elif defined(__APPLE__)
101static l_int32 var_DISPLAY_PROG = L_DISPLAY_WITH_OPEN; /* default */
102#else
103static l_int32 var_DISPLAY_PROG = L_DISPLAY_WITH_XZGV; /* default */
104#endif /* _WIN32 */
105
106#define Bufsize 512
107static const l_int32 MaxDisplayWidth = 1000;
108static const l_int32 MaxDisplayHeight = 800;
109static const l_int32 MaxSizeForPng = 200;
110
111 /* PostScript output for printing */
112static const l_float32 DefaultScaling = 1.0;
113
114 /* Global array of image file format extension names. */
115 /* This is in 1-1 correspondence with format enum in imageio.h. */
116 /* The empty string at the end represents the serialized format, */
117 /* which has no recognizable extension name, but the array must */
118 /* be padded to agree with the format enum. */
119 /* (Note on 'const': The size of the array can't be defined 'const' */
120 /* because that makes it static. The 'const' in the definition of */
121 /* the array refers to the strings in the array; the ptr to the */
122 /* array is not const and can be used 'extern' in other files.) */
123LEPT_DLL l_int32 NumImageFileFormatExtensions = 20; /* array size */
124LEPT_DLL const char *ImageFileFormatExtensions[] =
125 {"unknown",
126 "bmp",
127 "jpg",
128 "png",
129 "tif",
130 "tif",
131 "tif",
132 "tif",
133 "tif",
134 "tif",
135 "tif",
136 "pnm",
137 "ps",
138 "gif",
139 "jp2",
140 "webp",
141 "pdf",
142 "tif",
143 "default",
144 ""};
145
146 /* Local map of image file name extension to output format.
147 * Note that the extension string always includes a '.' */
149{
150 char extension[16];
151 l_int32 format;
152};
153static const struct ExtensionMap extension_map[] =
154 { { ".bmp", IFF_BMP },
155 { ".jpg", IFF_JFIF_JPEG },
156 { ".jpeg", IFF_JFIF_JPEG },
157 { ".JPG", IFF_JFIF_JPEG },
158 { ".png", IFF_PNG },
159 { ".tif", IFF_TIFF },
160 { ".tiff", IFF_TIFF },
161 { ".tiffg4", IFF_TIFF_G4 },
162 { ".pbm", IFF_PNM },
163 { ".pgm", IFF_PNM },
164 { ".pnm", IFF_PNM },
165 { ".gif", IFF_GIF },
166 { ".jp2", IFF_JP2 },
167 { ".j2k", IFF_JP2 },
168 { ".ps", IFF_PS },
169 { ".pdf", IFF_LPDF },
170 { ".webp", IFF_WEBP } };
171
172
173/*---------------------------------------------------------------------*
174 * Set jpeg quality for pixWrite() and pixWriteMem() *
175 *---------------------------------------------------------------------*/
176 /* Parameter that controls jpeg quality for high-level calls. */
177static l_int32 var_JPEG_QUALITY = 75; /* default */
178
195l_int32
196l_jpegSetQuality(l_int32 new_quality)
197{
198l_int32 prevq, newq;
199
200 prevq = var_JPEG_QUALITY;
201 newq = (new_quality == 0) ? 75 : new_quality;
202 if (newq < 1 || newq > 100)
203 L_ERROR("invalid jpeg quality; unchanged\n", __func__);
204 else
205 var_JPEG_QUALITY = newq;
206 return prevq;
207}
208
209
210/*----------------------------------------------------------------------*
211 * Set global variable LeptDebugOK for writing to named temp files *
212 *----------------------------------------------------------------------*/
213LEPT_DLL l_int32 LeptDebugOK = 0; /* default value */
228void
229setLeptDebugOK(l_int32 allow)
230{
231 if (allow != 0) allow = 1;
232 LeptDebugOK = allow;
233}
234
235
236/*---------------------------------------------------------------------*
237 * Top-level procedures for writing images to file *
238 *---------------------------------------------------------------------*/
253l_ok
254pixaWriteFiles(const char *rootname,
255 PIXA *pixa,
256 l_int32 format)
257{
258char bigbuf[Bufsize];
259l_int32 i, n, pixformat;
260PIX *pix;
261
262 if (!rootname)
263 return ERROR_INT("rootname not defined", __func__, 1);
264 if (!pixa)
265 return ERROR_INT("pixa not defined", __func__, 1);
266 if (format < 0 || format == IFF_UNKNOWN ||
267 format >= NumImageFileFormatExtensions)
268 return ERROR_INT("invalid format", __func__, 1);
269
270 n = pixaGetCount(pixa);
271 for (i = 0; i < n; i++) {
272 pix = pixaGetPix(pixa, i, L_CLONE);
273 if (format == IFF_DEFAULT)
274 pixformat = pixChooseOutputFormat(pix);
275 else
276 pixformat = format;
277 snprintf(bigbuf, Bufsize, "%s%03d.%s", rootname, i,
278 ImageFileFormatExtensions[pixformat]);
279 pixWrite(bigbuf, pix, pixformat);
280 pixDestroy(&pix);
281 }
282
283 return 0;
284}
285
286
304l_ok
305pixWriteDebug(const char *fname,
306 PIX *pix,
307 l_int32 format)
308{
309 if (LeptDebugOK) {
310 return pixWrite(fname, pix, format);
311 } else {
312 L_INFO("write to named temp file %s is disabled\n", __func__, fname);
313 return 0;
314 }
315}
316
317
339l_ok
340pixWrite(const char *fname,
341 PIX *pix,
342 l_int32 format)
343{
344l_int32 ret;
345FILE *fp;
346
347 if (!pix)
348 return ERROR_INT("pix not defined", __func__, 1);
349 if (!fname)
350 return ERROR_INT("fname not defined", __func__, 1);
351
352 if ((fp = fopenWriteStream(fname, "wb+")) == NULL)
353 return ERROR_INT_1("stream not opened", fname, __func__, 1);
354
355 ret = pixWriteStream(fp, pix, format);
356 fclose(fp);
357 if (ret)
358 return ERROR_INT_1("pix not written to stream", fname, __func__, 1);
359 return 0;
360}
361
362
370l_ok
371pixWriteAutoFormat(const char *filename,
372 PIX *pix)
373{
374l_int32 format;
375
376 if (!pix)
377 return ERROR_INT("pix not defined", __func__, 1);
378 if (!filename)
379 return ERROR_INT("filename not defined", __func__, 1);
380
381 if (pixGetAutoFormat(pix, &format))
382 return ERROR_INT("auto format not returned", __func__, 1);
383 return pixWrite(filename, pix, format);
384}
385
386
395l_ok
396pixWriteStream(FILE *fp,
397 PIX *pix,
398 l_int32 format)
399{
400 if (!fp)
401 return ERROR_INT("stream not defined", __func__, 1);
402 if (!pix)
403 return ERROR_INT("pix not defined", __func__, 1);
404
405 if (format == IFF_DEFAULT)
406 format = pixChooseOutputFormat(pix);
407
408 /* Use bmp format for testing if library for requested
409 * format for jpeg, png or tiff is not available */
410 changeFormatForMissingLib(&format);
411
412 switch(format)
413 {
414 case IFF_BMP:
415 pixWriteStreamBmp(fp, pix);
416 break;
417
418 case IFF_JFIF_JPEG: /* default quality; baseline sequential */
419 return pixWriteStreamJpeg(fp, pix, var_JPEG_QUALITY, 0);
420
421 case IFF_PNG: /* no gamma value stored */
422 return pixWriteStreamPng(fp, pix, 0.0);
423
424 case IFF_TIFF: /* uncompressed */
425 case IFF_TIFF_PACKBITS: /* compressed, binary only */
426 case IFF_TIFF_RLE: /* compressed, binary only */
427 case IFF_TIFF_G3: /* compressed, binary only */
428 case IFF_TIFF_G4: /* compressed, binary only */
429 case IFF_TIFF_LZW: /* compressed, all depths */
430 case IFF_TIFF_ZIP: /* compressed, all depths */
431 case IFF_TIFF_JPEG: /* compressed, 8 bpp gray and 32 bpp rgb */
432 return pixWriteStreamTiff(fp, pix, format);
433
434 case IFF_PNM:
435 return pixWriteStreamPnm(fp, pix);
436
437 case IFF_PS:
438 return pixWriteStreamPS(fp, pix, NULL, 0, DefaultScaling);
439
440 case IFF_GIF:
441 return pixWriteStreamGif(fp, pix);
442
443 case IFF_JP2:
444 return pixWriteStreamJp2k(fp, pix, 34, 0, L_JP2_CODEC, 0, 0);
445
446 case IFF_WEBP:
447 return pixWriteStreamWebP(fp, pix, 80, 0);
448
449 case IFF_LPDF:
450 return pixWriteStreamPdf(fp, pix, 0, NULL);
451
452 case IFF_SPIX:
453 return pixWriteStreamSpix(fp, pix);
454
455 default:
456 return ERROR_INT("unknown format", __func__, 1);
457 }
458
459 return 0;
460}
461
462
479l_ok
480pixWriteImpliedFormat(const char *filename,
481 PIX *pix,
482 l_int32 quality,
483 l_int32 progressive)
484{
485l_int32 format;
486
487 if (!filename)
488 return ERROR_INT("filename not defined", __func__, 1);
489 if (!pix)
490 return ERROR_INT("pix not defined", __func__, 1);
491
492 /* Determine output format */
493 format = getImpliedFileFormat(filename);
494 if (format == IFF_UNKNOWN) {
495 format = IFF_PNG;
496 } else if (format == IFF_TIFF) {
497 if (pixGetDepth(pix) == 1)
498 format = IFF_TIFF_G4;
499 else
500#ifdef _WIN32
501 format = IFF_TIFF_LZW; /* poor compression */
502#else
503 format = IFF_TIFF_ZIP; /* native Windows tools can't handle this */
504#endif /* _WIN32 */
505 }
506
507 if (format == IFF_JFIF_JPEG) {
508 quality = L_MIN(quality, 100);
509 quality = L_MAX(quality, 0);
510 if (progressive != 0 && progressive != 1) {
511 progressive = 0;
512 L_WARNING("invalid progressive; setting to baseline\n", __func__);
513 }
514 if (quality == 0)
515 quality = 75;
516 pixWriteJpeg (filename, pix, quality, progressive);
517 } else {
518 pixWrite(filename, pix, format);
519 }
520
521 return 0;
522}
523
524
525/*---------------------------------------------------------------------*
526 * Selection of output format if default is requested *
527 *---------------------------------------------------------------------*/
542l_int32
543pixChooseOutputFormat(PIX *pix)
544{
545l_int32 d, format;
546
547 if (!pix)
548 return ERROR_INT("pix not defined", __func__, 0);
549
550 d = pixGetDepth(pix);
551 format = pixGetInputFormat(pix);
552 if (format == IFF_UNKNOWN) { /* output lossless */
553 if (d == 1)
554 format = IFF_TIFF_G4;
555 else
556 format = IFF_PNG;
557 }
558
559 return format;
560}
561
562
575l_int32
576getImpliedFileFormat(const char *filename)
577{
578char *extension;
579l_int32 format = IFF_UNKNOWN;
580
581 if (!filename)
582 return ERROR_INT("extension not defined", __func__, IFF_UNKNOWN);
583
584 if (splitPathAtExtension (filename, NULL, &extension))
585 return IFF_UNKNOWN;
586
587 format = getFormatFromExtension(extension);
588 LEPT_FREE(extension);
589 return format;
590}
591
592
607l_int32
608getFormatFromExtension(const char *extension)
609{
610int i, numext;
611l_int32 format = IFF_UNKNOWN;
612
613 if (!extension)
614 return ERROR_INT("extension not defined", __func__, IFF_UNKNOWN);
615
616 numext = sizeof(extension_map) / sizeof(extension_map[0]);
617 for (i = 0; i < numext; i++) {
618 if (!strcmp(extension, extension_map[i].extension)) {
619 format = extension_map[i].format;
620 break;
621 }
622 }
623 return format;
624}
625
626
645l_ok
646pixGetAutoFormat(PIX *pix,
647 l_int32 *pformat)
648{
649l_int32 d;
650PIXCMAP *cmap;
651
652 if (!pformat)
653 return ERROR_INT("&format not defined", __func__, 0);
654 *pformat = IFF_UNKNOWN;
655 if (!pix)
656 return ERROR_INT("pix not defined", __func__, 0);
657
658 d = pixGetDepth(pix);
659 cmap = pixGetColormap(pix);
660 if (d == 1 && !cmap) {
661 *pformat = IFF_TIFF_G4;
662 } else if ((d == 8 && !cmap) || d == 24 || d == 32) {
663 *pformat = IFF_JFIF_JPEG;
664 } else {
665 *pformat = IFF_PNG;
666 }
667
668 return 0;
669}
670
671
684const char *
685getFormatExtension(l_int32 format)
686{
687 if (format < 0 || format >= NumImageFileFormatExtensions)
688 return (const char *)ERROR_PTR("invalid format", __func__, NULL);
689
690 return ImageFileFormatExtensions[format];
691}
692
693
694/*---------------------------------------------------------------------*
695 * Write to memory *
696 *---------------------------------------------------------------------*/
717l_ok
718pixWriteMem(l_uint8 **pdata,
719 size_t *psize,
720 PIX *pix,
721 l_int32 format)
722{
723l_int32 ret;
724
725 if (!pdata)
726 return ERROR_INT("&data not defined", __func__, 1 );
727 if (!psize)
728 return ERROR_INT("&size not defined", __func__, 1 );
729 if (!pix)
730 return ERROR_INT("&pix not defined", __func__, 1 );
731
732 if (format == IFF_DEFAULT)
733 format = pixChooseOutputFormat(pix);
734
735 /* Use bmp format for testing if library for requested
736 * format for jpeg, png or tiff is not available */
737 changeFormatForMissingLib(&format);
738
739 switch(format)
740 {
741 case IFF_BMP:
742 ret = pixWriteMemBmp(pdata, psize, pix);
743 break;
744
745 case IFF_JFIF_JPEG: /* default quality; baseline sequential */
746 ret = pixWriteMemJpeg(pdata, psize, pix, var_JPEG_QUALITY, 0);
747 break;
748
749 case IFF_PNG: /* no gamma value stored */
750 ret = pixWriteMemPng(pdata, psize, pix, 0.0);
751 break;
752
753 case IFF_TIFF: /* uncompressed */
754 case IFF_TIFF_PACKBITS: /* compressed, binary only */
755 case IFF_TIFF_RLE: /* compressed, binary only */
756 case IFF_TIFF_G3: /* compressed, binary only */
757 case IFF_TIFF_G4: /* compressed, binary only */
758 case IFF_TIFF_LZW: /* compressed, all depths */
759 case IFF_TIFF_ZIP: /* compressed, all depths */
760 case IFF_TIFF_JPEG: /* compressed, 8 bpp gray or 32 bpp rgb */
761 ret = pixWriteMemTiff(pdata, psize, pix, format);
762 break;
763
764 case IFF_PNM:
765 ret = pixWriteMemPnm(pdata, psize, pix);
766 break;
767
768 case IFF_PS:
769 ret = pixWriteMemPS(pdata, psize, pix, NULL, 0, DefaultScaling);
770 break;
771
772 case IFF_GIF:
773 ret = pixWriteMemGif(pdata, psize, pix);
774 break;
775
776 case IFF_JP2:
777 ret = pixWriteMemJp2k(pdata, psize, pix, 34, 0, 0, 0);
778 break;
779
780 case IFF_WEBP:
781 ret = pixWriteMemWebP(pdata, psize, pix, 80, 0);
782 break;
783
784 case IFF_LPDF:
785 ret = pixWriteMemPdf(pdata, psize, pix, 0, NULL);
786 break;
787
788 case IFF_SPIX:
789 ret = pixWriteMemSpix(pdata, psize, pix);
790 break;
791
792 default:
793 return ERROR_INT("unknown format", __func__, 1);
794 }
795
796 return ret;
797}
798
799
800/*---------------------------------------------------------------------*
801 * Image display for debugging *
802 *---------------------------------------------------------------------*/
819l_ok
820l_fileDisplay(const char *fname,
821 l_int32 x,
822 l_int32 y,
823 l_float32 scale)
824{
825PIX *pixs, *pixd;
826
827 if (!LeptDebugOK) {
828 L_INFO("displaying files is disabled; "
829 "use setLeptDebugOK(1) to enable\n", __func__);
830 return 0;
831 }
832 if (scale == 0.0)
833 return 0;
834 if (scale < 0.0)
835 return ERROR_INT("invalid scale factor", __func__, 1);
836 if ((pixs = pixRead(fname)) == NULL)
837 return ERROR_INT("pixs not read", __func__, 1);
838
839 if (scale == 1.0) {
840 pixd = pixClone(pixs);
841 } else {
842 if (scale < 1.0 && pixGetDepth(pixs) == 1)
843 pixd = pixScaleToGray(pixs, scale);
844 else
845 pixd = pixScale(pixs, scale, scale);
846 }
847 pixDisplay(pixd, x, y);
848 pixDestroy(&pixs);
849 pixDestroy(&pixd);
850 return 0;
851}
852
853
897l_ok
898pixDisplay(PIX *pixs,
899 l_int32 x,
900 l_int32 y)
901{
902 return pixDisplayWithTitle(pixs, x, y, NULL, 1);
903}
904
905
922l_ok
923pixDisplayWithTitle(PIX *pixs,
924 l_int32 x,
925 l_int32 y,
926 const char *title,
927 l_int32 dispflag)
928{
929char *tempname;
930char buffer[Bufsize];
931static l_atomic index = 0; /* caution: not .so safe */
932l_int32 w, h, d, spp, maxheight, opaque, threeviews;
933l_float32 ratw, rath, ratmin;
934PIX *pix0, *pix1, *pix2;
935PIXCMAP *cmap;
936#ifndef _WIN32
937l_int32 wt, ht;
938#else
939char *pathname;
940char fullpath[_MAX_PATH];
941#endif /* _WIN32 */
942
943 if (!LeptDebugOK) {
944 L_INFO("displaying images is disabled;\n "
945 "use setLeptDebugOK(1) to enable\n", __func__);
946 return 0;
947 }
948
949#ifdef OS_IOS /* iOS 11 does not support system() */
950 return ERROR_INT("iOS 11 does not support system()", __func__, 1);
951#endif /* OS_IOS */
952
953 if (dispflag != 1 || var_DISPLAY_PROG == L_DISPLAY_WITH_NONE)
954 return 0;
955 if (!pixs)
956 return ERROR_INT("pixs not defined", __func__, 1);
957
958#ifndef _WIN32 /* unix */
959 if (var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV &&
960 var_DISPLAY_PROG != L_DISPLAY_WITH_XLI &&
961 var_DISPLAY_PROG != L_DISPLAY_WITH_XV &&
962 var_DISPLAY_PROG != L_DISPLAY_WITH_OPEN)
963 return ERROR_INT("invalid unix program chosen for display",
964 __func__, 1);
965#else /* _WIN32 */
966 if (var_DISPLAY_PROG != L_DISPLAY_WITH_IV &&
967 var_DISPLAY_PROG != L_DISPLAY_WITH_OPEN)
968 return ERROR_INT("invalid windows program chosen for display",
969 __func__, 1);
970#endif /* _WIN32 */
971
972 /* Display with three views if either spp = 4 or if colormapped
973 * and the alpha component is not fully opaque */
974 opaque = TRUE;
975 if ((cmap = pixGetColormap(pixs)) != NULL)
976 pixcmapIsOpaque(cmap, &opaque);
977 spp = pixGetSpp(pixs);
978 threeviews = (spp == 4 || !opaque) ? TRUE : FALSE;
979
980 /* If colormapped and not opaque, remove the colormap to RGBA */
981 if (!opaque)
982 pix0 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA);
983 else
984 pix0 = pixClone(pixs);
985
986 /* Scale if necessary; this will also remove a colormap */
987 pixGetDimensions(pix0, &w, &h, &d);
988 maxheight = (threeviews) ? MaxDisplayHeight / 3 : MaxDisplayHeight;
989 if (w <= MaxDisplayWidth && h <= maxheight) {
990 if (d == 16) /* take MSB */
991 pix1 = pixConvert16To8(pix0, L_MS_BYTE);
992 else
993 pix1 = pixClone(pix0);
994 } else {
995 ratw = (l_float32)MaxDisplayWidth / (l_float32)w;
996 rath = (l_float32)maxheight / (l_float32)h;
997 ratmin = L_MIN(ratw, rath);
998 if (ratmin < 0.125 && d == 1)
999 pix1 = pixScaleToGray8(pix0);
1000 else if (ratmin < 0.25 && d == 1)
1001 pix1 = pixScaleToGray4(pix0);
1002 else if (ratmin < 0.33 && d == 1)
1003 pix1 = pixScaleToGray3(pix0);
1004 else if (ratmin < 0.5 && d == 1)
1005 pix1 = pixScaleToGray2(pix0);
1006 else
1007 pix1 = pixScale(pix0, ratmin, ratmin);
1008 }
1009 pixDestroy(&pix0);
1010 if (!pix1)
1011 return ERROR_INT("pix1 not made", __func__, 1);
1012
1013 /* Generate the three views if required */
1014 if (threeviews)
1015 pix2 = pixDisplayLayersRGBA(pix1, 0xffffff00, 0);
1016 else
1017 pix2 = pixClone(pix1);
1018
1019 if (index == 0) { /* erase any existing images */
1020 lept_rmdir("lept/disp");
1021 lept_mkdir("lept/disp");
1022 }
1023
1024 index++;
1025 if (pixGetDepth(pix2) < 8 || pixGetColormap(pix2) ||
1026 (w < MaxSizeForPng && h < MaxSizeForPng)) {
1027 snprintf(buffer, Bufsize, "/tmp/lept/disp/write.%03d.png", index);
1028 pixWrite(buffer, pix2, IFF_PNG);
1029 } else {
1030 snprintf(buffer, Bufsize, "/tmp/lept/disp/write.%03d.jpg", index);
1031 pixWrite(buffer, pix2, IFF_JFIF_JPEG);
1032 }
1033 tempname = genPathname(buffer, NULL);
1034
1035#ifndef _WIN32
1036
1037 /* Unix */
1038 if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) {
1039 /* no way to display title */
1040 pixGetDimensions(pix2, &wt, &ht, NULL);
1041 snprintf(buffer, Bufsize,
1042 "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10,
1043 x, y, tempname);
1044 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) {
1045 if (title) {
1046 snprintf(buffer, Bufsize,
1047 "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &",
1048 x, y, title, tempname);
1049 } else {
1050 snprintf(buffer, Bufsize,
1051 "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &",
1052 x, y, tempname);
1053 }
1054 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) {
1055 if (title) {
1056 snprintf(buffer, Bufsize,
1057 "xv -quit -geometry +%d+%d -name \"%s\" %s &",
1058 x, y, title, tempname);
1059 } else {
1060 snprintf(buffer, Bufsize,
1061 "xv -quit -geometry +%d+%d %s &", x, y, tempname);
1062 }
1063 } else { /* L_DISPLAY_WITH_OPEN */
1064 snprintf(buffer, Bufsize, "open %s &", tempname);
1065 }
1066 callSystemDebug(buffer);
1067
1068#else /* _WIN32 */
1069
1070 /* Windows: L_DISPLAY_WITH_IV || L_DISPLAY_WITH_OPEN */
1071 pathname = genPathname(tempname, NULL);
1072 _fullpath(fullpath, pathname, sizeof(fullpath));
1073 if (var_DISPLAY_PROG == L_DISPLAY_WITH_IV) {
1074 if (title) {
1075 snprintf(buffer, Bufsize,
1076 "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"",
1077 fullpath, x, y, title);
1078 } else {
1079 snprintf(buffer, Bufsize, "i_view32.exe \"%s\" /pos=(%d,%d)",
1080 fullpath, x, y);
1081 }
1082 } else { /* L_DISPLAY_WITH_OPEN */
1083 snprintf(buffer, Bufsize, "explorer.exe /open,\"%s\"", fullpath);
1084 }
1085 callSystemDebug(buffer);
1086 LEPT_FREE(pathname);
1087
1088#endif /* _WIN32 */
1089
1090 pixDestroy(&pix1);
1091 pixDestroy(&pix2);
1092 LEPT_FREE(tempname);
1093 return 0;
1094}
1095
1096
1113PIX *
1114pixMakeColorSquare(l_uint32 color,
1115 l_int32 size,
1116 l_int32 addlabel,
1117 l_int32 location,
1118 l_uint32 textcolor)
1119{
1120char buf[32];
1121l_int32 w, rval, gval, bval;
1122L_BMF *bmf;
1123PIX *pix1, *pix2;
1124
1125 w = (size <= 0) ? 100 : size;
1126 if (addlabel && w < 100) {
1127 L_WARNING("size too small for label; omitting label\n", __func__);
1128 addlabel = 0;
1129 }
1130
1131 if ((pix1 = pixCreate(w, w, 32)) == NULL)
1132 return (PIX *)ERROR_PTR("pix1 not madel", __func__, NULL);
1133 pixSetAllArbitrary(pix1, color);
1134 if (!addlabel)
1135 return pix1;
1136
1137 /* Adding text of color component values */
1138 if (location != L_ADD_ABOVE && location != L_ADD_AT_TOP &&
1139 location != L_ADD_AT_BOT && location != L_ADD_BELOW) {
1140 L_ERROR("invalid location: adding below\n", __func__);
1141 location = L_ADD_BELOW;
1142 }
1143 bmf = bmfCreate(NULL, 4);
1144 extractRGBValues(color, &rval, &gval, &bval);
1145 snprintf(buf, sizeof(buf), "%d,%d,%d", rval, gval, bval);
1146 pix2 = pixAddSingleTextblock(pix1, bmf, buf, textcolor, location, NULL);
1147 pixDestroy(&pix1);
1148 bmfDestroy(&bmf);
1149 return pix2;
1150}
1151
1152
1153void
1154l_chooseDisplayProg(l_int32 selection)
1155{
1156 if (selection == L_DISPLAY_WITH_XLI ||
1157 selection == L_DISPLAY_WITH_XZGV ||
1158 selection == L_DISPLAY_WITH_XV ||
1159 selection == L_DISPLAY_WITH_IV ||
1160 selection == L_DISPLAY_WITH_OPEN) {
1161 var_DISPLAY_PROG = selection;
1162 } else {
1163 L_ERROR("invalid display program\n", "l_chooseDisplayProg");
1164 }
1165}
1166
1167
1168/*---------------------------------------------------------------------*
1169 * Change format for missing lib *
1170 *---------------------------------------------------------------------*/
1184void
1185changeFormatForMissingLib(l_int32 *pformat)
1186{
1187#if !defined(HAVE_LIBJPEG)
1188 if (*pformat == IFF_JFIF_JPEG) {
1189 L_WARNING("jpeg library missing; output bmp format\n", __func__);
1190 *pformat = IFF_BMP;
1191 }
1192#endif /* !defined(HAVE_LIBJPEG) */
1193#if !defined(HAVE_LIBPNG)
1194 if (*pformat == IFF_PNG) {
1195 L_WARNING("png library missing; output bmp format\n", __func__);
1196 *pformat = IFF_BMP;
1197 }
1198#endif /* !defined(HAVE_LIBPNG) */
1199#if !defined(HAVE_LIBTIFF)
1200 if (L_FORMAT_IS_TIFF(*pformat)) {
1201 L_WARNING("tiff library missing; output bmp format\n", __func__);
1202 *pformat = IFF_BMP;
1203 }
1204#endif /* !defined(HAVE_LIBTIFF) */
1205}
1206
1207
1208/*---------------------------------------------------------------------*
1209 * Deprecated pix output for debugging *
1210 *---------------------------------------------------------------------*/
1223l_ok
1224pixDisplayWrite(PIX *pixs,
1225 l_int32 reduction)
1226{
1227 lept_stderr("\n########################################################\n"
1228 " pixDisplayWrite() was last used in tesseract 3.04,"
1229 " in Feb 2016. As of 1.80, it is a non-functional stub\n"
1230 "########################################################"
1231 "\n\n\n");
1232 return 1;
1233}
@ L_JP2_CODEC
Definition imageio.h:149
@ REMOVE_CMAP_WITH_ALPHA
Definition pix.h:383
@ L_ADD_AT_BOT
Definition pix.h:1007
@ L_ADD_BELOW
Definition pix.h:1003
@ L_ADD_AT_TOP
Definition pix.h:1006
@ L_ADD_ABOVE
Definition pix.h:1002
@ L_CLONE
Definition pix.h:506
@ L_MS_BYTE
Definition pix.h:642
@ L_DISPLAY_WITH_NONE
Definition pix.h:1039
@ L_DISPLAY_WITH_XV
Definition pix.h:1042
@ L_DISPLAY_WITH_XZGV
Definition pix.h:1040
@ L_DISPLAY_WITH_XLI
Definition pix.h:1041
@ L_DISPLAY_WITH_OPEN
Definition pix.h:1044
@ L_DISPLAY_WITH_IV
Definition pix.h:1043
Definition bmf.h:47