Leptonica 1.82.0
Image processing and image analysis suite
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 pixGetAutoFormat()
48 * const char *getFormatExtension()
49 *
50 * Write to memory
51 * l_int32 pixWriteMem()
52 *
53 * Image display for debugging
54 * l_int32 l_fileDisplay()
55 * l_int32 pixDisplay()
56 * l_int32 pixDisplayWithTitle()
57 * PIX *pixMakeColorSquare()
58 * void l_chooseDisplayProg()
59 *
60 * Change format for missing library
61 * void changeFormatForMissingLib()
62 *
63 * Nonfunctional stub of pix output for debugging
64 * l_int32 pixDisplayWrite()
65 *
66 * Supported file formats:
67 * (1) Writing is supported without any external libraries:
68 * bmp
69 * pnm (including pbm, pgm, etc)
70 * spix (raw serialized)
71 * (2) Writing is supported with installation of external libraries:
72 * png
73 * jpg (standard jfif version)
74 * tiff (including most varieties of compression)
75 * gif
76 * webp
77 * jp2 (jpeg2000)
78 * (3) Writing is supported through special interfaces:
79 * ps (PostScript, in psio1.c, psio2.c):
80 * level 1 (uncompressed)
81 * level 2 (g4 and dct encoding: requires tiff, jpg)
82 * level 3 (g4, dct and flate encoding: requires tiff, jpg, zlib)
83 * pdf (PDF, in pdfio.c):
84 * level 1 (g4 and dct encoding: requires tiff, jpg)
85 * level 2 (g4, dct and flate encoding: requires tiff, jpg, zlib)
86 */
87
88#ifdef HAVE_CONFIG_H
89#include <config_auto.h>
90#endif /* HAVE_CONFIG_H */
91
92#include <string.h>
93#include "allheaders.h"
94
95 /* Display program (xv, xli, xzgv, open) to be invoked by pixDisplay() */
96#ifdef _WIN32
97static l_int32 var_DISPLAY_PROG = L_DISPLAY_WITH_IV; /* default */
98#elif defined(__APPLE__)
99static l_int32 var_DISPLAY_PROG = L_DISPLAY_WITH_OPEN; /* default */
100#else
101static l_int32 var_DISPLAY_PROG = L_DISPLAY_WITH_XZGV; /* default */
102#endif /* _WIN32 */
103
104#define Bufsize 512
105static const l_int32 MaxDisplayWidth = 1000;
106static const l_int32 MaxDisplayHeight = 800;
107static const l_int32 MaxSizeForPng = 200;
108
109 /* PostScript output for printing */
110static const l_float32 DefaultScaling = 1.0;
111
112 /* Global array of image file format extension names. */
113 /* This is in 1-1 corrspondence with format enum in imageio.h. */
114 /* The empty string at the end represents the serialized format, */
115 /* which has no recognizable extension name, but the array must */
116 /* be padded to agree with the format enum. */
117 /* (Note on 'const': The size of the array can't be defined 'const' */
118 /* because that makes it static. The 'const' in the definition of */
119 /* the array refers to the strings in the array; the ptr to the */
120 /* array is not const and can be used 'extern' in other files.) */
121LEPT_DLL l_int32 NumImageFileFormatExtensions = 20; /* array size */
122LEPT_DLL const char *ImageFileFormatExtensions[] =
123 {"unknown",
124 "bmp",
125 "jpg",
126 "png",
127 "tif",
128 "tif",
129 "tif",
130 "tif",
131 "tif",
132 "tif",
133 "tif",
134 "pnm",
135 "ps",
136 "gif",
137 "jp2",
138 "webp",
139 "pdf",
140 "tif",
141 "default",
142 ""};
143
144 /* Local map of image file name extension to output format */
146{
147 char extension[8];
148 l_int32 format;
149};
150static const struct ExtensionMap extension_map[] =
151 { { ".bmp", IFF_BMP },
152 { ".jpg", IFF_JFIF_JPEG },
153 { ".jpeg", IFF_JFIF_JPEG },
154 { ".png", IFF_PNG },
155 { ".tif", IFF_TIFF },
156 { ".tiff", IFF_TIFF },
157 { ".pnm", IFF_PNM },
158 { ".gif", IFF_GIF },
159 { ".jp2", IFF_JP2 },
160 { ".ps", IFF_PS },
161 { ".pdf", IFF_LPDF },
162 { ".webp", IFF_WEBP } };
163
164
165/*---------------------------------------------------------------------*
166 * Set jpeg quality for pixWrite() and pixWriteMem() *
167 *---------------------------------------------------------------------*/
168 /* Parameter that controls jpeg quality for high-level calls. */
169static l_int32 var_JPEG_QUALITY = 75; /* default */
170
187l_int32
188l_jpegSetQuality(l_int32 new_quality)
189{
190l_int32 prevq, newq;
191
192 PROCNAME("l_jpeqSetQuality");
193
194 prevq = var_JPEG_QUALITY;
195 newq = (new_quality == 0) ? 75 : new_quality;
196 if (newq < 1 || newq > 100)
197 L_ERROR("invalid jpeg quality; unchanged\n", procName);
198 else
199 var_JPEG_QUALITY = newq;
200 return prevq;
201}
202
203
204/*----------------------------------------------------------------------*
205 * Set global variable LeptDebugOK for writing to named temp files *
206 *----------------------------------------------------------------------*/
207LEPT_DLL l_int32 LeptDebugOK = 0; /* default value */
222void
223setLeptDebugOK(l_int32 allow)
224{
225 if (allow != 0) allow = 1;
226 LeptDebugOK = allow;
227}
228
229
230/*---------------------------------------------------------------------*
231 * Top-level procedures for writing images to file *
232 *---------------------------------------------------------------------*/
247l_ok
248pixaWriteFiles(const char *rootname,
249 PIXA *pixa,
250 l_int32 format)
251{
252char bigbuf[Bufsize];
253l_int32 i, n, pixformat;
254PIX *pix;
255
256 PROCNAME("pixaWriteFiles");
257
258 if (!rootname)
259 return ERROR_INT("rootname not defined", procName, 1);
260 if (!pixa)
261 return ERROR_INT("pixa not defined", procName, 1);
262 if (format < 0 || format == IFF_UNKNOWN ||
263 format >= NumImageFileFormatExtensions)
264 return ERROR_INT("invalid format", procName, 1);
265
266 n = pixaGetCount(pixa);
267 for (i = 0; i < n; i++) {
268 pix = pixaGetPix(pixa, i, L_CLONE);
269 if (format == IFF_DEFAULT)
270 pixformat = pixChooseOutputFormat(pix);
271 else
272 pixformat = format;
273 snprintf(bigbuf, Bufsize, "%s%03d.%s", rootname, i,
274 ImageFileFormatExtensions[pixformat]);
275 pixWrite(bigbuf, pix, pixformat);
276 pixDestroy(&pix);
277 }
278
279 return 0;
280}
281
282
300l_ok
301pixWriteDebug(const char *fname,
302 PIX *pix,
303 l_int32 format)
304{
305 PROCNAME("pixWriteDebug");
306
307 if (LeptDebugOK) {
308 return pixWrite(fname, pix, format);
309 } else {
310 L_INFO("write to named temp file %s is disabled\n", procName, fname);
311 return 0;
312 }
313}
314
315
337l_ok
338pixWrite(const char *fname,
339 PIX *pix,
340 l_int32 format)
341{
342l_int32 ret;
343FILE *fp;
344
345 PROCNAME("pixWrite");
346
347 if (!pix)
348 return ERROR_INT("pix not defined", procName, 1);
349 if (!fname)
350 return ERROR_INT("fname not defined", procName, 1);
351
352 if ((fp = fopenWriteStream(fname, "wb+")) == NULL)
353 return ERROR_INT("stream not opened", procName, 1);
354
355 ret = pixWriteStream(fp, pix, format);
356 fclose(fp);
357 if (ret)
358 return ERROR_INT("pix not written to stream", procName, 1);
359 return 0;
360}
361
362
370l_ok
371pixWriteAutoFormat(const char *filename,
372 PIX *pix)
373{
374l_int32 format;
375
376 PROCNAME("pixWriteAutoFormat");
377
378 if (!pix)
379 return ERROR_INT("pix not defined", procName, 1);
380 if (!filename)
381 return ERROR_INT("filename not defined", procName, 1);
382
383 if (pixGetAutoFormat(pix, &format))
384 return ERROR_INT("auto format not returned", procName, 1);
385 return pixWrite(filename, pix, format);
386}
387
388
397l_ok
398pixWriteStream(FILE *fp,
399 PIX *pix,
400 l_int32 format)
401{
402 PROCNAME("pixWriteStream");
403
404 if (!fp)
405 return ERROR_INT("stream not defined", procName, 1);
406 if (!pix)
407 return ERROR_INT("pix not defined", procName, 1);
408
409 if (format == IFF_DEFAULT)
410 format = pixChooseOutputFormat(pix);
411
412 /* Use bmp format for testing if library for requested
413 * format for jpeg, png or tiff is not available */
414 changeFormatForMissingLib(&format);
415
416 switch(format)
417 {
418 case IFF_BMP:
419 pixWriteStreamBmp(fp, pix);
420 break;
421
422 case IFF_JFIF_JPEG: /* default quality; baseline sequential */
423 return pixWriteStreamJpeg(fp, pix, var_JPEG_QUALITY, 0);
424
425 case IFF_PNG: /* no gamma value stored */
426 return pixWriteStreamPng(fp, pix, 0.0);
427
428 case IFF_TIFF: /* uncompressed */
429 case IFF_TIFF_PACKBITS: /* compressed, binary only */
430 case IFF_TIFF_RLE: /* compressed, binary only */
431 case IFF_TIFF_G3: /* compressed, binary only */
432 case IFF_TIFF_G4: /* compressed, binary only */
433 case IFF_TIFF_LZW: /* compressed, all depths */
434 case IFF_TIFF_ZIP: /* compressed, all depths */
435 case IFF_TIFF_JPEG: /* compressed, 8 bpp gray and 32 bpp rgb */
436 return pixWriteStreamTiff(fp, pix, format);
437
438 case IFF_PNM:
439 return pixWriteStreamPnm(fp, pix);
440
441 case IFF_PS:
442 return pixWriteStreamPS(fp, pix, NULL, 0, DefaultScaling);
443
444 case IFF_GIF:
445 return pixWriteStreamGif(fp, pix);
446
447 case IFF_JP2:
448 return pixWriteStreamJp2k(fp, pix, 34, 4, L_JP2_CODEC, 0, 0);
449
450 case IFF_WEBP:
451 return pixWriteStreamWebP(fp, pix, 80, 0);
452
453 case IFF_LPDF:
454 return pixWriteStreamPdf(fp, pix, 0, NULL);
455
456 case IFF_SPIX:
457 return pixWriteStreamSpix(fp, pix);
458
459 default:
460 return ERROR_INT("unknown format", procName, 1);
461 }
462
463 return 0;
464}
465
466
483l_ok
484pixWriteImpliedFormat(const char *filename,
485 PIX *pix,
486 l_int32 quality,
487 l_int32 progressive)
488{
489l_int32 format;
490
491 PROCNAME("pixWriteImpliedFormat");
492
493 if (!filename)
494 return ERROR_INT("filename not defined", procName, 1);
495 if (!pix)
496 return ERROR_INT("pix not defined", procName, 1);
497
498 /* Determine output format */
499 format = getImpliedFileFormat(filename);
500 if (format == IFF_UNKNOWN) {
501 format = IFF_PNG;
502 } else if (format == IFF_TIFF) {
503 if (pixGetDepth(pix) == 1)
504 format = IFF_TIFF_G4;
505 else
506#ifdef _WIN32
507 format = IFF_TIFF_LZW; /* poor compression */
508#else
509 format = IFF_TIFF_ZIP; /* native windows tools can't handle this */
510#endif /* _WIN32 */
511 }
512
513 if (format == IFF_JFIF_JPEG) {
514 quality = L_MIN(quality, 100);
515 quality = L_MAX(quality, 0);
516 if (progressive != 0 && progressive != 1) {
517 progressive = 0;
518 L_WARNING("invalid progressive; setting to baseline\n", procName);
519 }
520 if (quality == 0)
521 quality = 75;
522 pixWriteJpeg (filename, pix, quality, progressive);
523 } else {
524 pixWrite(filename, pix, format);
525 }
526
527 return 0;
528}
529
530
531/*---------------------------------------------------------------------*
532 * Selection of output format if default is requested *
533 *---------------------------------------------------------------------*/
548l_int32
549pixChooseOutputFormat(PIX *pix)
550{
551l_int32 d, format;
552
553 PROCNAME("pixChooseOutputFormat");
554
555 if (!pix)
556 return ERROR_INT("pix not defined", procName, 0);
557
558 d = pixGetDepth(pix);
559 format = pixGetInputFormat(pix);
560 if (format == IFF_UNKNOWN) { /* output lossless */
561 if (d == 1)
562 format = IFF_TIFF_G4;
563 else
564 format = IFF_PNG;
565 }
566
567 return format;
568}
569
570
583l_int32
584getImpliedFileFormat(const char *filename)
585{
586char *extension;
587int i, numext;
588l_int32 format = IFF_UNKNOWN;
589
590 if (splitPathAtExtension (filename, NULL, &extension))
591 return IFF_UNKNOWN;
592
593 numext = sizeof(extension_map) / sizeof(extension_map[0]);
594 for (i = 0; i < numext; i++) {
595 if (!strcmp(extension, extension_map[i].extension)) {
596 format = extension_map[i].format;
597 break;
598 }
599 }
600
601 LEPT_FREE(extension);
602 return format;
603}
604
605
624l_ok
625pixGetAutoFormat(PIX *pix,
626 l_int32 *pformat)
627{
628l_int32 d;
629PIXCMAP *cmap;
630
631 PROCNAME("pixGetAutoFormat");
632
633 if (!pformat)
634 return ERROR_INT("&format not defined", procName, 0);
635 *pformat = IFF_UNKNOWN;
636 if (!pix)
637 return ERROR_INT("pix not defined", procName, 0);
638
639 d = pixGetDepth(pix);
640 cmap = pixGetColormap(pix);
641 if (d == 1 && !cmap) {
642 *pformat = IFF_TIFF_G4;
643 } else if ((d == 8 && !cmap) || d == 24 || d == 32) {
644 *pformat = IFF_JFIF_JPEG;
645 } else {
646 *pformat = IFF_PNG;
647 }
648
649 return 0;
650}
651
652
665const char *
666getFormatExtension(l_int32 format)
667{
668 PROCNAME("getFormatExtension");
669
670 if (format < 0 || format >= NumImageFileFormatExtensions)
671 return (const char *)ERROR_PTR("invalid format", procName, NULL);
672
673 return ImageFileFormatExtensions[format];
674}
675
676
677/*---------------------------------------------------------------------*
678 * Write to memory *
679 *---------------------------------------------------------------------*/
700l_ok
701pixWriteMem(l_uint8 **pdata,
702 size_t *psize,
703 PIX *pix,
704 l_int32 format)
705{
706l_int32 ret;
707
708 PROCNAME("pixWriteMem");
709
710 if (!pdata)
711 return ERROR_INT("&data not defined", procName, 1 );
712 if (!psize)
713 return ERROR_INT("&size not defined", procName, 1 );
714 if (!pix)
715 return ERROR_INT("&pix not defined", procName, 1 );
716
717 if (format == IFF_DEFAULT)
718 format = pixChooseOutputFormat(pix);
719
720 /* Use bmp format for testing if library for requested
721 * format for jpeg, png or tiff is not available */
722 changeFormatForMissingLib(&format);
723
724 switch(format)
725 {
726 case IFF_BMP:
727 ret = pixWriteMemBmp(pdata, psize, pix);
728 break;
729
730 case IFF_JFIF_JPEG: /* default quality; baseline sequential */
731 ret = pixWriteMemJpeg(pdata, psize, pix, var_JPEG_QUALITY, 0);
732 break;
733
734 case IFF_PNG: /* no gamma value stored */
735 ret = pixWriteMemPng(pdata, psize, pix, 0.0);
736 break;
737
738 case IFF_TIFF: /* uncompressed */
739 case IFF_TIFF_PACKBITS: /* compressed, binary only */
740 case IFF_TIFF_RLE: /* compressed, binary only */
741 case IFF_TIFF_G3: /* compressed, binary only */
742 case IFF_TIFF_G4: /* compressed, binary only */
743 case IFF_TIFF_LZW: /* compressed, all depths */
744 case IFF_TIFF_ZIP: /* compressed, all depths */
745 case IFF_TIFF_JPEG: /* compressed, 8 bpp gray or 32 bpp rgb */
746 ret = pixWriteMemTiff(pdata, psize, pix, format);
747 break;
748
749 case IFF_PNM:
750 ret = pixWriteMemPnm(pdata, psize, pix);
751 break;
752
753 case IFF_PS:
754 ret = pixWriteMemPS(pdata, psize, pix, NULL, 0, DefaultScaling);
755 break;
756
757 case IFF_GIF:
758 ret = pixWriteMemGif(pdata, psize, pix);
759 break;
760
761 case IFF_JP2:
762 ret = pixWriteMemJp2k(pdata, psize, pix, 34, 0, 0, 0);
763 break;
764
765 case IFF_WEBP:
766 ret = pixWriteMemWebP(pdata, psize, pix, 80, 0);
767 break;
768
769 case IFF_LPDF:
770 ret = pixWriteMemPdf(pdata, psize, pix, 0, NULL);
771 break;
772
773 case IFF_SPIX:
774 ret = pixWriteMemSpix(pdata, psize, pix);
775 break;
776
777 default:
778 return ERROR_INT("unknown format", procName, 1);
779 }
780
781 return ret;
782}
783
784
785/*---------------------------------------------------------------------*
786 * Image display for debugging *
787 *---------------------------------------------------------------------*/
804l_ok
805l_fileDisplay(const char *fname,
806 l_int32 x,
807 l_int32 y,
808 l_float32 scale)
809{
810PIX *pixs, *pixd;
811
812 PROCNAME("l_fileDisplay");
813
814 if (!LeptDebugOK) {
815 L_INFO("displaying files is disabled; "
816 "use setLeptDebugOK(1) to enable\n", procName);
817 return 0;
818 }
819 if (scale == 0.0)
820 return 0;
821 if (scale < 0.0)
822 return ERROR_INT("invalid scale factor", procName, 1);
823 if ((pixs = pixRead(fname)) == NULL)
824 return ERROR_INT("pixs not read", procName, 1);
825
826 if (scale == 1.0) {
827 pixd = pixClone(pixs);
828 } else {
829 if (scale < 1.0 && pixGetDepth(pixs) == 1)
830 pixd = pixScaleToGray(pixs, scale);
831 else
832 pixd = pixScale(pixs, scale, scale);
833 }
834 pixDisplay(pixd, x, y);
835 pixDestroy(&pixs);
836 pixDestroy(&pixd);
837 return 0;
838}
839
840
880l_ok
881pixDisplay(PIX *pixs,
882 l_int32 x,
883 l_int32 y)
884{
885 return pixDisplayWithTitle(pixs, x, y, NULL, 1);
886}
887
888
904l_ok
905pixDisplayWithTitle(PIX *pixs,
906 l_int32 x,
907 l_int32 y,
908 const char *title,
909 l_int32 dispflag)
910{
911char *tempname;
912char buffer[Bufsize];
913static l_int32 index = 0; /* caution: not .so or thread safe */
914l_int32 w, h, d, spp, maxheight, opaque, threeviews;
915l_float32 ratw, rath, ratmin;
916PIX *pix0, *pix1, *pix2;
917PIXCMAP *cmap;
918#ifndef _WIN32
919l_int32 wt, ht;
920#else
921char *pathname;
922char fullpath[_MAX_PATH];
923#endif /* _WIN32 */
924
925 PROCNAME("pixDisplayWithTitle");
926
927 if (!LeptDebugOK) {
928 L_INFO("displaying images is disabled;\n "
929 "use setLeptDebugOK(1) to enable\n", procName);
930 return 0;
931 }
932
933#ifdef OS_IOS /* iOS 11 does not support system() */
934 return ERROR_INT("iOS 11 does not support system()", procName, 1);
935#endif /* OS_IOS */
936
937 if (dispflag != 1) return 0;
938 if (!pixs)
939 return ERROR_INT("pixs not defined", procName, 1);
940 if (var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV &&
941 var_DISPLAY_PROG != L_DISPLAY_WITH_XLI &&
942 var_DISPLAY_PROG != L_DISPLAY_WITH_XV &&
943 var_DISPLAY_PROG != L_DISPLAY_WITH_IV &&
944 var_DISPLAY_PROG != L_DISPLAY_WITH_OPEN) {
945 return ERROR_INT("no program chosen for display", procName, 1);
946 }
947
948 /* Display with three views if either spp = 4 or if colormapped
949 * and the alpha component is not fully opaque */
950 opaque = TRUE;
951 if ((cmap = pixGetColormap(pixs)) != NULL)
952 pixcmapIsOpaque(cmap, &opaque);
953 spp = pixGetSpp(pixs);
954 threeviews = (spp == 4 || !opaque) ? TRUE : FALSE;
955
956 /* If colormapped and not opaque, remove the colormap to RGBA */
957 if (!opaque)
959 else
960 pix0 = pixClone(pixs);
961
962 /* Scale if necessary; this will also remove a colormap */
963 pixGetDimensions(pix0, &w, &h, &d);
964 maxheight = (threeviews) ? MaxDisplayHeight / 3 : MaxDisplayHeight;
965 if (w <= MaxDisplayWidth && h <= maxheight) {
966 if (d == 16) /* take MSB */
967 pix1 = pixConvert16To8(pix0, L_MS_BYTE);
968 else
969 pix1 = pixClone(pix0);
970 } else {
971 ratw = (l_float32)MaxDisplayWidth / (l_float32)w;
972 rath = (l_float32)maxheight / (l_float32)h;
973 ratmin = L_MIN(ratw, rath);
974 if (ratmin < 0.125 && d == 1)
975 pix1 = pixScaleToGray8(pix0);
976 else if (ratmin < 0.25 && d == 1)
977 pix1 = pixScaleToGray4(pix0);
978 else if (ratmin < 0.33 && d == 1)
979 pix1 = pixScaleToGray3(pix0);
980 else if (ratmin < 0.5 && d == 1)
981 pix1 = pixScaleToGray2(pix0);
982 else
983 pix1 = pixScale(pix0, ratmin, ratmin);
984 }
985 pixDestroy(&pix0);
986 if (!pix1)
987 return ERROR_INT("pix1 not made", procName, 1);
988
989 /* Generate the three views if required */
990 if (threeviews)
991 pix2 = pixDisplayLayersRGBA(pix1, 0xffffff00, 0);
992 else
993 pix2 = pixClone(pix1);
994
995 if (index == 0) { /* erase any existing images */
996 lept_rmdir("lept/disp");
997 lept_mkdir("lept/disp");
998 }
999
1000 index++;
1001 if (pixGetDepth(pix2) < 8 || pixGetColormap(pix2) ||
1002 (w < MaxSizeForPng && h < MaxSizeForPng)) {
1003 snprintf(buffer, Bufsize, "/tmp/lept/disp/write.%03d.png", index);
1004 pixWrite(buffer, pix2, IFF_PNG);
1005 } else {
1006 snprintf(buffer, Bufsize, "/tmp/lept/disp/write.%03d.jpg", index);
1007 pixWrite(buffer, pix2, IFF_JFIF_JPEG);
1008 }
1009 tempname = genPathname(buffer, NULL);
1010
1011#ifndef _WIN32
1012
1013 /* Unix */
1014 if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) {
1015 /* no way to display title */
1016 pixGetDimensions(pix2, &wt, &ht, NULL);
1017 snprintf(buffer, Bufsize,
1018 "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10,
1019 x, y, tempname);
1020 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) {
1021 if (title) {
1022 snprintf(buffer, Bufsize,
1023 "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &",
1024 x, y, title, tempname);
1025 } else {
1026 snprintf(buffer, Bufsize,
1027 "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &",
1028 x, y, tempname);
1029 }
1030 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) {
1031 if (title) {
1032 snprintf(buffer, Bufsize,
1033 "xv -quit -geometry +%d+%d -name \"%s\" %s &",
1034 x, y, title, tempname);
1035 } else {
1036 snprintf(buffer, Bufsize,
1037 "xv -quit -geometry +%d+%d %s &", x, y, tempname);
1038 }
1039 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_OPEN) {
1040 snprintf(buffer, Bufsize, "open %s &", tempname);
1041 }
1042 callSystemDebug(buffer);
1043
1044#else /* _WIN32 */
1045
1046 /* Windows: L_DISPLAY_WITH_IV */
1047 pathname = genPathname(tempname, NULL);
1048 _fullpath(fullpath, pathname, sizeof(fullpath));
1049 if (title) {
1050 snprintf(buffer, Bufsize,
1051 "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"",
1052 fullpath, x, y, title);
1053 } else {
1054 snprintf(buffer, Bufsize, "i_view32.exe \"%s\" /pos=(%d,%d)",
1055 fullpath, x, y);
1056 }
1057 callSystemDebug(buffer);
1058 LEPT_FREE(pathname);
1059
1060#endif /* _WIN32 */
1061
1062 pixDestroy(&pix1);
1063 pixDestroy(&pix2);
1064 LEPT_FREE(tempname);
1065 return 0;
1066}
1067
1068
1085PIX *
1086pixMakeColorSquare(l_uint32 color,
1087 l_int32 size,
1088 l_int32 addlabel,
1089 l_int32 location,
1090 l_uint32 textcolor)
1091{
1092char buf[32];
1093l_int32 w, rval, gval, bval;
1094L_BMF *bmf;
1095PIX *pix1, *pix2;
1096
1097 PROCNAME("pixMakeColorSquare");
1098
1099 w = (size <= 0) ? 100 : size;
1100 if (addlabel && w < 100) {
1101 L_WARNING("size too small for label; omitting label\n", procName);
1102 addlabel = 0;
1103 }
1104
1105 if ((pix1 = pixCreate(w, w, 32)) == NULL)
1106 return (PIX *)ERROR_PTR("pix1 not madel", procName, NULL);
1107 pixSetAllArbitrary(pix1, color);
1108 if (!addlabel)
1109 return pix1;
1110
1111 /* Adding text of color component values */
1112 if (location != L_ADD_ABOVE && location != L_ADD_AT_TOP &&
1113 location != L_ADD_AT_BOT && location != L_ADD_BELOW) {
1114 L_ERROR("invalid location: adding below\n", procName);
1115 location = L_ADD_BELOW;
1116 }
1117 bmf = bmfCreate(NULL, 4);
1118 extractRGBValues(color, &rval, &gval, &bval);
1119 snprintf(buf, sizeof(buf), "%d,%d,%d", rval, gval, bval);
1120 pix2 = pixAddSingleTextblock(pix1, bmf, buf, textcolor, location, NULL);
1121 pixDestroy(&pix1);
1122 bmfDestroy(&bmf);
1123 return pix2;
1124}
1125
1126
1127void
1128l_chooseDisplayProg(l_int32 selection)
1129{
1130 if (selection == L_DISPLAY_WITH_XLI ||
1131 selection == L_DISPLAY_WITH_XZGV ||
1132 selection == L_DISPLAY_WITH_XV ||
1133 selection == L_DISPLAY_WITH_IV ||
1134 selection == L_DISPLAY_WITH_OPEN) {
1135 var_DISPLAY_PROG = selection;
1136 } else {
1137 L_ERROR("invalid display program\n", "l_chooseDisplayProg");
1138 }
1139}
1140
1141
1142/*---------------------------------------------------------------------*
1143 * Change format for missing lib *
1144 *---------------------------------------------------------------------*/
1158void
1159changeFormatForMissingLib(l_int32 *pformat)
1160{
1161 PROCNAME("changeFormatForMissingLib");
1162
1163#if !defined(HAVE_LIBJPEG)
1164 if (*pformat == IFF_JFIF_JPEG) {
1165 L_WARNING("jpeg library missing; output bmp format\n", procName);
1166 *pformat = IFF_BMP;
1167 }
1168#endif /* !defined(HAVE_LIBJPEG) */
1169#if !defined(HAVE_LIBPNG)
1170 if (*pformat == IFF_PNG) {
1171 L_WARNING("png library missing; output bmp format\n", procName);
1172 *pformat = IFF_BMP;
1173 }
1174#endif /* !defined(HAVE_LIBPNG) */
1175#if !defined(HAVE_LIBTIFF)
1176 if (L_FORMAT_IS_TIFF(*pformat)) {
1177 L_WARNING("tiff library missing; output bmp format\n", procName);
1178 *pformat = IFF_BMP;
1179 }
1180#endif /* !defined(HAVE_LIBTIFF) */
1181}
1182
1183
1184/*---------------------------------------------------------------------*
1185 * Deprecated pix output for debugging *
1186 *---------------------------------------------------------------------*/
1199l_ok
1200pixDisplayWrite(PIX *pixs,
1201 l_int32 reduction)
1202{
1203 lept_stderr("\n########################################################\n"
1204 " pixDisplayWrite() was last used in tesseract 3.04,"
1205 " in Feb 2016. As of 1.80, it is a non-functional stub\n"
1206 "########################################################"
1207 "\n\n\n");
1208 return 1;
1209}
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:169
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:117
l_ok pixWriteStreamBmp(FILE *fp, PIX *pix)
pixWriteStreamBmp()
Definition: bmpio.c:400
l_ok pixWriteMemBmp(l_uint8 **pfdata, size_t *pfsize, PIX *pixs)
pixWriteMemBmp()
Definition: bmpio.c:445
l_ok pixcmapIsOpaque(PIXCMAP *cmap, l_int32 *popaque)
pixcmapIsOpaque()
Definition: colormap.c:1114
@ L_JP2_CODEC
Definition: imageio.h:149
l_ok pixWriteMemJpeg(l_uint8 **pdata, size_t *psize, PIX *pix, l_int32 quality, l_int32 progressive)
pixWriteMemJpeg()
Definition: jpegio.c:1131
l_ok pixWriteStreamJpeg(FILE *fp, PIX *pixs, l_int32 quality, l_int32 progressive)
pixWriteStreamJpeg()
Definition: jpegio.c:802
l_ok pixWriteJpeg(const char *filename, PIX *pix, l_int32 quality, l_int32 progressive)
pixWriteJpeg()
Definition: jpegio.c:741
l_ok pixWriteMemPdf(l_uint8 **pdata, size_t *pnbytes, PIX *pix, l_int32 res, const char *title)
pixWriteMemPdf()
Definition: pdfio1.c:1395
l_ok pixWriteStreamPdf(FILE *fp, PIX *pix, l_int32 res, const char *title)
pixWriteStreamPdf()
Definition: pdfio1.c:1346
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition: pix2.c:2351
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2820
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
@ REMOVE_CMAP_WITH_ALPHA
Definition: pix.h:259
@ L_ADD_AT_BOT
Definition: pix.h:1214
@ L_ADD_BELOW
Definition: pix.h:1210
@ L_ADD_AT_TOP
Definition: pix.h:1213
@ L_ADD_ABOVE
Definition: pix.h:1209
@ L_CLONE
Definition: pix.h:713
@ L_MS_BYTE
Definition: pix.h:849
@ L_DISPLAY_WITH_XV
Definition: pix.h:1248
@ L_DISPLAY_WITH_XZGV
Definition: pix.h:1246
@ L_DISPLAY_WITH_XLI
Definition: pix.h:1247
@ L_DISPLAY_WITH_OPEN
Definition: pix.h:1250
@ L_DISPLAY_WITH_IV
Definition: pix.h:1249
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
PIX * pixConvert16To8(PIX *pixs, l_int32 type)
pixConvert16To8()
Definition: pixconv.c:1762
l_ok pixWriteStreamPng(FILE *fp, PIX *pix, l_float32 gamma)
pixWriteStreamPng()
Definition: pngio.c:1072
l_ok pixWriteMemPng(l_uint8 **pfiledata, size_t *pfilesize, PIX *pix, l_float32 gamma)
pixWriteMemPng()
Definition: pngio.c:1986
l_ok pixWriteStreamPnm(FILE *fp, PIX *pix)
pixWriteStreamPnm()
Definition: pnmio.c:742
l_ok pixWriteMemPnm(l_uint8 **pdata, size_t *psize, PIX *pix)
pixWriteMemPnm()
Definition: pnmio.c:1234
l_ok pixWriteStreamPS(FILE *fp, PIX *pix, BOX *box, l_int32 res, l_float32 scale)
pixWriteStreamPS()
Definition: psio2.c:241
l_ok pixWriteMemPS(l_uint8 **pdata, size_t *psize, PIX *pix, BOX *box, l_int32 res, l_float32 scale)
pixWriteMemPS()
Definition: psio2.c:1957
PIX * pixRead(const char *filename)
pixRead()
Definition: readfile.c:193
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
PIX * pixScaleToGray3(PIX *pixs)
pixScaleToGray3()
Definition: scale2.c:448
PIX * pixScaleToGray(PIX *pixs, l_float32 scalefactor)
pixScaleToGray()
Definition: scale2.c:208
PIX * pixScaleToGray8(PIX *pixs)
pixScaleToGray8()
Definition: scale2.c:605
PIX * pixScaleToGray4(PIX *pixs)
pixScaleToGray4()
Definition: scale2.c:502
PIX * pixScaleToGray2(PIX *pixs)
pixScaleToGray2()
Definition: scale2.c:390
l_ok pixWriteMemSpix(l_uint8 **pdata, size_t *psize, PIX *pix)
pixWriteMemSpix()
Definition: spixio.c:321
l_ok pixWriteStreamSpix(FILE *fp, PIX *pix)
pixWriteStreamSpix()
Definition: spixio.c:273
Definition: bmf.h:47
Definition: pix.h:139
Definition: pix.h:456
PIX * pixAddSingleTextblock(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location, l_int32 *poverflow)
pixAddSingleTextblock()
Definition: textops.c:120
l_ok pixWriteStreamTiff(FILE *fp, PIX *pix, l_int32 comptype)
pixWriteStreamTiff()
Definition: tiffio.c:911
l_ok pixWriteMemTiff(l_uint8 **pdata, size_t *psize, PIX *pix, l_int32 comptype)
pixWriteMemTiff()
Definition: tiffio.c:2841
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
l_int32 lept_rmdir(const char *subdir)
lept_rmdir()
Definition: utils2.c:2295
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
l_ok splitPathAtExtension(const char *pathname, char **pbasename, char **pextension)
splitPathAtExtension()
Definition: utils2.c:2894
char * genPathname(const char *dir, const char *fname)
genPathname()
Definition: utils2.c:3173
void callSystemDebug(const char *cmd)
callSystemDebug()
Definition: utils2.c:2752
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2218