Leptonica 1.83.1
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 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 prevq = var_JPEG_QUALITY;
193 newq = (new_quality == 0) ? 75 : new_quality;
194 if (newq < 1 || newq > 100)
195 L_ERROR("invalid jpeg quality; unchanged\n", __func__);
196 else
197 var_JPEG_QUALITY = newq;
198 return prevq;
199}
200
201
202/*----------------------------------------------------------------------*
203 * Set global variable LeptDebugOK for writing to named temp files *
204 *----------------------------------------------------------------------*/
205LEPT_DLL l_int32 LeptDebugOK = 0; /* default value */
220void
221setLeptDebugOK(l_int32 allow)
222{
223 if (allow != 0) allow = 1;
224 LeptDebugOK = allow;
225}
226
227
228/*---------------------------------------------------------------------*
229 * Top-level procedures for writing images to file *
230 *---------------------------------------------------------------------*/
245l_ok
246pixaWriteFiles(const char *rootname,
247 PIXA *pixa,
248 l_int32 format)
249{
250char bigbuf[Bufsize];
251l_int32 i, n, pixformat;
252PIX *pix;
253
254 if (!rootname)
255 return ERROR_INT("rootname not defined", __func__, 1);
256 if (!pixa)
257 return ERROR_INT("pixa not defined", __func__, 1);
258 if (format < 0 || format == IFF_UNKNOWN ||
259 format >= NumImageFileFormatExtensions)
260 return ERROR_INT("invalid format", __func__, 1);
261
262 n = pixaGetCount(pixa);
263 for (i = 0; i < n; i++) {
264 pix = pixaGetPix(pixa, i, L_CLONE);
265 if (format == IFF_DEFAULT)
266 pixformat = pixChooseOutputFormat(pix);
267 else
268 pixformat = format;
269 snprintf(bigbuf, Bufsize, "%s%03d.%s", rootname, i,
270 ImageFileFormatExtensions[pixformat]);
271 pixWrite(bigbuf, pix, pixformat);
272 pixDestroy(&pix);
273 }
274
275 return 0;
276}
277
278
296l_ok
297pixWriteDebug(const char *fname,
298 PIX *pix,
299 l_int32 format)
300{
301 if (LeptDebugOK) {
302 return pixWrite(fname, pix, format);
303 } else {
304 L_INFO("write to named temp file %s is disabled\n", __func__, fname);
305 return 0;
306 }
307}
308
309
331l_ok
332pixWrite(const char *fname,
333 PIX *pix,
334 l_int32 format)
335{
336l_int32 ret;
337FILE *fp;
338
339 if (!pix)
340 return ERROR_INT("pix not defined", __func__, 1);
341 if (!fname)
342 return ERROR_INT("fname not defined", __func__, 1);
343
344 if ((fp = fopenWriteStream(fname, "wb+")) == NULL)
345 return ERROR_INT("stream not opened", __func__, 1);
346
347 ret = pixWriteStream(fp, pix, format);
348 fclose(fp);
349 if (ret)
350 return ERROR_INT("pix not written to stream", __func__, 1);
351 return 0;
352}
353
354
362l_ok
363pixWriteAutoFormat(const char *filename,
364 PIX *pix)
365{
366l_int32 format;
367
368 if (!pix)
369 return ERROR_INT("pix not defined", __func__, 1);
370 if (!filename)
371 return ERROR_INT("filename not defined", __func__, 1);
372
373 if (pixGetAutoFormat(pix, &format))
374 return ERROR_INT("auto format not returned", __func__, 1);
375 return pixWrite(filename, pix, format);
376}
377
378
387l_ok
388pixWriteStream(FILE *fp,
389 PIX *pix,
390 l_int32 format)
391{
392 if (!fp)
393 return ERROR_INT("stream not defined", __func__, 1);
394 if (!pix)
395 return ERROR_INT("pix not defined", __func__, 1);
396
397 if (format == IFF_DEFAULT)
398 format = pixChooseOutputFormat(pix);
399
400 /* Use bmp format for testing if library for requested
401 * format for jpeg, png or tiff is not available */
402 changeFormatForMissingLib(&format);
403
404 switch(format)
405 {
406 case IFF_BMP:
407 pixWriteStreamBmp(fp, pix);
408 break;
409
410 case IFF_JFIF_JPEG: /* default quality; baseline sequential */
411 return pixWriteStreamJpeg(fp, pix, var_JPEG_QUALITY, 0);
412
413 case IFF_PNG: /* no gamma value stored */
414 return pixWriteStreamPng(fp, pix, 0.0);
415
416 case IFF_TIFF: /* uncompressed */
417 case IFF_TIFF_PACKBITS: /* compressed, binary only */
418 case IFF_TIFF_RLE: /* compressed, binary only */
419 case IFF_TIFF_G3: /* compressed, binary only */
420 case IFF_TIFF_G4: /* compressed, binary only */
421 case IFF_TIFF_LZW: /* compressed, all depths */
422 case IFF_TIFF_ZIP: /* compressed, all depths */
423 case IFF_TIFF_JPEG: /* compressed, 8 bpp gray and 32 bpp rgb */
424 return pixWriteStreamTiff(fp, pix, format);
425
426 case IFF_PNM:
427 return pixWriteStreamPnm(fp, pix);
428
429 case IFF_PS:
430 return pixWriteStreamPS(fp, pix, NULL, 0, DefaultScaling);
431
432 case IFF_GIF:
433 return pixWriteStreamGif(fp, pix);
434
435 case IFF_JP2:
436 return pixWriteStreamJp2k(fp, pix, 34, 4, L_JP2_CODEC, 0, 0);
437
438 case IFF_WEBP:
439 return pixWriteStreamWebP(fp, pix, 80, 0);
440
441 case IFF_LPDF:
442 return pixWriteStreamPdf(fp, pix, 0, NULL);
443
444 case IFF_SPIX:
445 return pixWriteStreamSpix(fp, pix);
446
447 default:
448 return ERROR_INT("unknown format", __func__, 1);
449 }
450
451 return 0;
452}
453
454
471l_ok
472pixWriteImpliedFormat(const char *filename,
473 PIX *pix,
474 l_int32 quality,
475 l_int32 progressive)
476{
477l_int32 format;
478
479 if (!filename)
480 return ERROR_INT("filename not defined", __func__, 1);
481 if (!pix)
482 return ERROR_INT("pix not defined", __func__, 1);
483
484 /* Determine output format */
485 format = getImpliedFileFormat(filename);
486 if (format == IFF_UNKNOWN) {
487 format = IFF_PNG;
488 } else if (format == IFF_TIFF) {
489 if (pixGetDepth(pix) == 1)
490 format = IFF_TIFF_G4;
491 else
492#ifdef _WIN32
493 format = IFF_TIFF_LZW; /* poor compression */
494#else
495 format = IFF_TIFF_ZIP; /* native Windows tools can't handle this */
496#endif /* _WIN32 */
497 }
498
499 if (format == IFF_JFIF_JPEG) {
500 quality = L_MIN(quality, 100);
501 quality = L_MAX(quality, 0);
502 if (progressive != 0 && progressive != 1) {
503 progressive = 0;
504 L_WARNING("invalid progressive; setting to baseline\n", __func__);
505 }
506 if (quality == 0)
507 quality = 75;
508 pixWriteJpeg (filename, pix, quality, progressive);
509 } else {
510 pixWrite(filename, pix, format);
511 }
512
513 return 0;
514}
515
516
517/*---------------------------------------------------------------------*
518 * Selection of output format if default is requested *
519 *---------------------------------------------------------------------*/
534l_int32
535pixChooseOutputFormat(PIX *pix)
536{
537l_int32 d, format;
538
539 if (!pix)
540 return ERROR_INT("pix not defined", __func__, 0);
541
542 d = pixGetDepth(pix);
543 format = pixGetInputFormat(pix);
544 if (format == IFF_UNKNOWN) { /* output lossless */
545 if (d == 1)
546 format = IFF_TIFF_G4;
547 else
548 format = IFF_PNG;
549 }
550
551 return format;
552}
553
554
567l_int32
568getImpliedFileFormat(const char *filename)
569{
570char *extension;
571int i, numext;
572l_int32 format = IFF_UNKNOWN;
573
574 if (splitPathAtExtension (filename, NULL, &extension))
575 return IFF_UNKNOWN;
576
577 numext = sizeof(extension_map) / sizeof(extension_map[0]);
578 for (i = 0; i < numext; i++) {
579 if (!strcmp(extension, extension_map[i].extension)) {
580 format = extension_map[i].format;
581 break;
582 }
583 }
584
585 LEPT_FREE(extension);
586 return format;
587}
588
589
608l_ok
609pixGetAutoFormat(PIX *pix,
610 l_int32 *pformat)
611{
612l_int32 d;
613PIXCMAP *cmap;
614
615 if (!pformat)
616 return ERROR_INT("&format not defined", __func__, 0);
617 *pformat = IFF_UNKNOWN;
618 if (!pix)
619 return ERROR_INT("pix not defined", __func__, 0);
620
621 d = pixGetDepth(pix);
622 cmap = pixGetColormap(pix);
623 if (d == 1 && !cmap) {
624 *pformat = IFF_TIFF_G4;
625 } else if ((d == 8 && !cmap) || d == 24 || d == 32) {
626 *pformat = IFF_JFIF_JPEG;
627 } else {
628 *pformat = IFF_PNG;
629 }
630
631 return 0;
632}
633
634
647const char *
648getFormatExtension(l_int32 format)
649{
650 if (format < 0 || format >= NumImageFileFormatExtensions)
651 return (const char *)ERROR_PTR("invalid format", __func__, NULL);
652
653 return ImageFileFormatExtensions[format];
654}
655
656
657/*---------------------------------------------------------------------*
658 * Write to memory *
659 *---------------------------------------------------------------------*/
680l_ok
681pixWriteMem(l_uint8 **pdata,
682 size_t *psize,
683 PIX *pix,
684 l_int32 format)
685{
686l_int32 ret;
687
688 if (!pdata)
689 return ERROR_INT("&data not defined", __func__, 1 );
690 if (!psize)
691 return ERROR_INT("&size not defined", __func__, 1 );
692 if (!pix)
693 return ERROR_INT("&pix not defined", __func__, 1 );
694
695 if (format == IFF_DEFAULT)
696 format = pixChooseOutputFormat(pix);
697
698 /* Use bmp format for testing if library for requested
699 * format for jpeg, png or tiff is not available */
700 changeFormatForMissingLib(&format);
701
702 switch(format)
703 {
704 case IFF_BMP:
705 ret = pixWriteMemBmp(pdata, psize, pix);
706 break;
707
708 case IFF_JFIF_JPEG: /* default quality; baseline sequential */
709 ret = pixWriteMemJpeg(pdata, psize, pix, var_JPEG_QUALITY, 0);
710 break;
711
712 case IFF_PNG: /* no gamma value stored */
713 ret = pixWriteMemPng(pdata, psize, pix, 0.0);
714 break;
715
716 case IFF_TIFF: /* uncompressed */
717 case IFF_TIFF_PACKBITS: /* compressed, binary only */
718 case IFF_TIFF_RLE: /* compressed, binary only */
719 case IFF_TIFF_G3: /* compressed, binary only */
720 case IFF_TIFF_G4: /* compressed, binary only */
721 case IFF_TIFF_LZW: /* compressed, all depths */
722 case IFF_TIFF_ZIP: /* compressed, all depths */
723 case IFF_TIFF_JPEG: /* compressed, 8 bpp gray or 32 bpp rgb */
724 ret = pixWriteMemTiff(pdata, psize, pix, format);
725 break;
726
727 case IFF_PNM:
728 ret = pixWriteMemPnm(pdata, psize, pix);
729 break;
730
731 case IFF_PS:
732 ret = pixWriteMemPS(pdata, psize, pix, NULL, 0, DefaultScaling);
733 break;
734
735 case IFF_GIF:
736 ret = pixWriteMemGif(pdata, psize, pix);
737 break;
738
739 case IFF_JP2:
740 ret = pixWriteMemJp2k(pdata, psize, pix, 34, 0, 0, 0);
741 break;
742
743 case IFF_WEBP:
744 ret = pixWriteMemWebP(pdata, psize, pix, 80, 0);
745 break;
746
747 case IFF_LPDF:
748 ret = pixWriteMemPdf(pdata, psize, pix, 0, NULL);
749 break;
750
751 case IFF_SPIX:
752 ret = pixWriteMemSpix(pdata, psize, pix);
753 break;
754
755 default:
756 return ERROR_INT("unknown format", __func__, 1);
757 }
758
759 return ret;
760}
761
762
763/*---------------------------------------------------------------------*
764 * Image display for debugging *
765 *---------------------------------------------------------------------*/
782l_ok
783l_fileDisplay(const char *fname,
784 l_int32 x,
785 l_int32 y,
786 l_float32 scale)
787{
788PIX *pixs, *pixd;
789
790 if (!LeptDebugOK) {
791 L_INFO("displaying files is disabled; "
792 "use setLeptDebugOK(1) to enable\n", __func__);
793 return 0;
794 }
795 if (scale == 0.0)
796 return 0;
797 if (scale < 0.0)
798 return ERROR_INT("invalid scale factor", __func__, 1);
799 if ((pixs = pixRead(fname)) == NULL)
800 return ERROR_INT("pixs not read", __func__, 1);
801
802 if (scale == 1.0) {
803 pixd = pixClone(pixs);
804 } else {
805 if (scale < 1.0 && pixGetDepth(pixs) == 1)
806 pixd = pixScaleToGray(pixs, scale);
807 else
808 pixd = pixScale(pixs, scale, scale);
809 }
810 pixDisplay(pixd, x, y);
811 pixDestroy(&pixs);
812 pixDestroy(&pixd);
813 return 0;
814}
815
816
856l_ok
857pixDisplay(PIX *pixs,
858 l_int32 x,
859 l_int32 y)
860{
861 return pixDisplayWithTitle(pixs, x, y, NULL, 1);
862}
863
864
880l_ok
881pixDisplayWithTitle(PIX *pixs,
882 l_int32 x,
883 l_int32 y,
884 const char *title,
885 l_int32 dispflag)
886{
887char *tempname;
888char buffer[Bufsize];
889static l_int32 index = 0; /* caution: not .so or thread safe */
890l_int32 w, h, d, spp, maxheight, opaque, threeviews;
891l_float32 ratw, rath, ratmin;
892PIX *pix0, *pix1, *pix2;
893PIXCMAP *cmap;
894#ifndef _WIN32
895l_int32 wt, ht;
896#else
897char *pathname;
898char fullpath[_MAX_PATH];
899#endif /* _WIN32 */
900
901 if (!LeptDebugOK) {
902 L_INFO("displaying images is disabled;\n "
903 "use setLeptDebugOK(1) to enable\n", __func__);
904 return 0;
905 }
906
907#ifdef OS_IOS /* iOS 11 does not support system() */
908 return ERROR_INT("iOS 11 does not support system()", __func__, 1);
909#endif /* OS_IOS */
910
911 if (dispflag != 1) return 0;
912 if (!pixs)
913 return ERROR_INT("pixs not defined", __func__, 1);
914 if (var_DISPLAY_PROG != L_DISPLAY_WITH_XZGV &&
915 var_DISPLAY_PROG != L_DISPLAY_WITH_XLI &&
916 var_DISPLAY_PROG != L_DISPLAY_WITH_XV &&
917 var_DISPLAY_PROG != L_DISPLAY_WITH_IV &&
918 var_DISPLAY_PROG != L_DISPLAY_WITH_OPEN) {
919 return ERROR_INT("no program chosen for display", __func__, 1);
920 }
921
922 /* Display with three views if either spp = 4 or if colormapped
923 * and the alpha component is not fully opaque */
924 opaque = TRUE;
925 if ((cmap = pixGetColormap(pixs)) != NULL)
926 pixcmapIsOpaque(cmap, &opaque);
927 spp = pixGetSpp(pixs);
928 threeviews = (spp == 4 || !opaque) ? TRUE : FALSE;
929
930 /* If colormapped and not opaque, remove the colormap to RGBA */
931 if (!opaque)
932 pix0 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA);
933 else
934 pix0 = pixClone(pixs);
935
936 /* Scale if necessary; this will also remove a colormap */
937 pixGetDimensions(pix0, &w, &h, &d);
938 maxheight = (threeviews) ? MaxDisplayHeight / 3 : MaxDisplayHeight;
939 if (w <= MaxDisplayWidth && h <= maxheight) {
940 if (d == 16) /* take MSB */
941 pix1 = pixConvert16To8(pix0, L_MS_BYTE);
942 else
943 pix1 = pixClone(pix0);
944 } else {
945 ratw = (l_float32)MaxDisplayWidth / (l_float32)w;
946 rath = (l_float32)maxheight / (l_float32)h;
947 ratmin = L_MIN(ratw, rath);
948 if (ratmin < 0.125 && d == 1)
949 pix1 = pixScaleToGray8(pix0);
950 else if (ratmin < 0.25 && d == 1)
951 pix1 = pixScaleToGray4(pix0);
952 else if (ratmin < 0.33 && d == 1)
953 pix1 = pixScaleToGray3(pix0);
954 else if (ratmin < 0.5 && d == 1)
955 pix1 = pixScaleToGray2(pix0);
956 else
957 pix1 = pixScale(pix0, ratmin, ratmin);
958 }
959 pixDestroy(&pix0);
960 if (!pix1)
961 return ERROR_INT("pix1 not made", __func__, 1);
962
963 /* Generate the three views if required */
964 if (threeviews)
965 pix2 = pixDisplayLayersRGBA(pix1, 0xffffff00, 0);
966 else
967 pix2 = pixClone(pix1);
968
969 if (index == 0) { /* erase any existing images */
970 lept_rmdir("lept/disp");
971 lept_mkdir("lept/disp");
972 }
973
974 index++;
975 if (pixGetDepth(pix2) < 8 || pixGetColormap(pix2) ||
976 (w < MaxSizeForPng && h < MaxSizeForPng)) {
977 snprintf(buffer, Bufsize, "/tmp/lept/disp/write.%03d.png", index);
978 pixWrite(buffer, pix2, IFF_PNG);
979 } else {
980 snprintf(buffer, Bufsize, "/tmp/lept/disp/write.%03d.jpg", index);
981 pixWrite(buffer, pix2, IFF_JFIF_JPEG);
982 }
983 tempname = genPathname(buffer, NULL);
984
985#ifndef _WIN32
986
987 /* Unix */
988 if (var_DISPLAY_PROG == L_DISPLAY_WITH_XZGV) {
989 /* no way to display title */
990 pixGetDimensions(pix2, &wt, &ht, NULL);
991 snprintf(buffer, Bufsize,
992 "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10,
993 x, y, tempname);
994 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XLI) {
995 if (title) {
996 snprintf(buffer, Bufsize,
997 "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &",
998 x, y, title, tempname);
999 } else {
1000 snprintf(buffer, Bufsize,
1001 "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &",
1002 x, y, tempname);
1003 }
1004 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_XV) {
1005 if (title) {
1006 snprintf(buffer, Bufsize,
1007 "xv -quit -geometry +%d+%d -name \"%s\" %s &",
1008 x, y, title, tempname);
1009 } else {
1010 snprintf(buffer, Bufsize,
1011 "xv -quit -geometry +%d+%d %s &", x, y, tempname);
1012 }
1013 } else if (var_DISPLAY_PROG == L_DISPLAY_WITH_OPEN) {
1014 snprintf(buffer, Bufsize, "open %s &", tempname);
1015 }
1016 callSystemDebug(buffer);
1017
1018#else /* _WIN32 */
1019
1020 /* Windows: L_DISPLAY_WITH_IV */
1021 pathname = genPathname(tempname, NULL);
1022 _fullpath(fullpath, pathname, sizeof(fullpath));
1023 if (title) {
1024 snprintf(buffer, Bufsize,
1025 "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"",
1026 fullpath, x, y, title);
1027 } else {
1028 snprintf(buffer, Bufsize, "i_view32.exe \"%s\" /pos=(%d,%d)",
1029 fullpath, x, y);
1030 }
1031 callSystemDebug(buffer);
1032 LEPT_FREE(pathname);
1033
1034#endif /* _WIN32 */
1035
1036 pixDestroy(&pix1);
1037 pixDestroy(&pix2);
1038 LEPT_FREE(tempname);
1039 return 0;
1040}
1041
1042
1059PIX *
1060pixMakeColorSquare(l_uint32 color,
1061 l_int32 size,
1062 l_int32 addlabel,
1063 l_int32 location,
1064 l_uint32 textcolor)
1065{
1066char buf[32];
1067l_int32 w, rval, gval, bval;
1068L_BMF *bmf;
1069PIX *pix1, *pix2;
1070
1071 w = (size <= 0) ? 100 : size;
1072 if (addlabel && w < 100) {
1073 L_WARNING("size too small for label; omitting label\n", __func__);
1074 addlabel = 0;
1075 }
1076
1077 if ((pix1 = pixCreate(w, w, 32)) == NULL)
1078 return (PIX *)ERROR_PTR("pix1 not madel", __func__, NULL);
1079 pixSetAllArbitrary(pix1, color);
1080 if (!addlabel)
1081 return pix1;
1082
1083 /* Adding text of color component values */
1084 if (location != L_ADD_ABOVE && location != L_ADD_AT_TOP &&
1085 location != L_ADD_AT_BOT && location != L_ADD_BELOW) {
1086 L_ERROR("invalid location: adding below\n", __func__);
1087 location = L_ADD_BELOW;
1088 }
1089 bmf = bmfCreate(NULL, 4);
1090 extractRGBValues(color, &rval, &gval, &bval);
1091 snprintf(buf, sizeof(buf), "%d,%d,%d", rval, gval, bval);
1092 pix2 = pixAddSingleTextblock(pix1, bmf, buf, textcolor, location, NULL);
1093 pixDestroy(&pix1);
1094 bmfDestroy(&bmf);
1095 return pix2;
1096}
1097
1098
1099void
1100l_chooseDisplayProg(l_int32 selection)
1101{
1102 if (selection == L_DISPLAY_WITH_XLI ||
1103 selection == L_DISPLAY_WITH_XZGV ||
1104 selection == L_DISPLAY_WITH_XV ||
1105 selection == L_DISPLAY_WITH_IV ||
1106 selection == L_DISPLAY_WITH_OPEN) {
1107 var_DISPLAY_PROG = selection;
1108 } else {
1109 L_ERROR("invalid display program\n", "l_chooseDisplayProg");
1110 }
1111}
1112
1113
1114/*---------------------------------------------------------------------*
1115 * Change format for missing lib *
1116 *---------------------------------------------------------------------*/
1130void
1131changeFormatForMissingLib(l_int32 *pformat)
1132{
1133#if !defined(HAVE_LIBJPEG)
1134 if (*pformat == IFF_JFIF_JPEG) {
1135 L_WARNING("jpeg library missing; output bmp format\n", __func__);
1136 *pformat = IFF_BMP;
1137 }
1138#endif /* !defined(HAVE_LIBJPEG) */
1139#if !defined(HAVE_LIBPNG)
1140 if (*pformat == IFF_PNG) {
1141 L_WARNING("png library missing; output bmp format\n", __func__);
1142 *pformat = IFF_BMP;
1143 }
1144#endif /* !defined(HAVE_LIBPNG) */
1145#if !defined(HAVE_LIBTIFF)
1146 if (L_FORMAT_IS_TIFF(*pformat)) {
1147 L_WARNING("tiff library missing; output bmp format\n", __func__);
1148 *pformat = IFF_BMP;
1149 }
1150#endif /* !defined(HAVE_LIBTIFF) */
1151}
1152
1153
1154/*---------------------------------------------------------------------*
1155 * Deprecated pix output for debugging *
1156 *---------------------------------------------------------------------*/
1169l_ok
1170pixDisplayWrite(PIX *pixs,
1171 l_int32 reduction)
1172{
1173 lept_stderr("\n########################################################\n"
1174 " pixDisplayWrite() was last used in tesseract 3.04,"
1175 " in Feb 2016. As of 1.80, it is a non-functional stub\n"
1176 "########################################################"
1177 "\n\n\n");
1178 return 1;
1179}
@ L_JP2_CODEC
Definition imageio.h:149
@ REMOVE_CMAP_WITH_ALPHA
Definition pix.h:383
@ L_CLONE
Definition pix.h:506
struct Pix PIX
Definition pix.h:228
struct PixColormap PIXCMAP
Definition pix.h:231
@ 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_MS_BYTE
Definition pix.h:642
struct Pixa PIXA
Definition pix.h:243
@ L_DISPLAY_WITH_XV
Definition pix.h:1041
@ L_DISPLAY_WITH_XZGV
Definition pix.h:1039
@ L_DISPLAY_WITH_XLI
Definition pix.h:1040
@ L_DISPLAY_WITH_OPEN
Definition pix.h:1043
@ L_DISPLAY_WITH_IV
Definition pix.h:1042