90#include <config_auto.h>
94#include "allheaders.h"
100#elif defined(__APPLE__)
107static const l_int32 MaxDisplayWidth = 1000;
108static const l_int32 MaxDisplayHeight = 800;
109static const l_int32 MaxSizeForPng = 200;
112static const l_float32 DefaultScaling = 1.0;
123LEPT_DLL l_int32 NumImageFileFormatExtensions = 20;
124LEPT_DLL
const char *ImageFileFormatExtensions[] =
154 { {
".bmp", IFF_BMP },
155 {
".jpg", IFF_JFIF_JPEG },
156 {
".jpeg", IFF_JFIF_JPEG },
157 {
".JPG", IFF_JFIF_JPEG },
159 {
".tif", IFF_TIFF },
160 {
".tiff", IFF_TIFF },
161 {
".tiffg4", IFF_TIFF_G4 },
169 {
".pdf", IFF_LPDF },
170 {
".webp", IFF_WEBP } };
177static l_int32 var_JPEG_QUALITY = 75;
196l_jpegSetQuality(l_int32 new_quality)
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__);
205 var_JPEG_QUALITY = newq;
213LEPT_DLL l_int32 LeptDebugOK = 0;
229setLeptDebugOK(l_int32 allow)
231 if (allow != 0) allow = 1;
254pixaWriteFiles(
const char *rootname,
259l_int32 i, n, pixformat;
263 return ERROR_INT(
"rootname not defined", __func__, 1);
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);
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);
277 snprintf(bigbuf, Bufsize,
"%s%03d.%s", rootname, i,
278 ImageFileFormatExtensions[pixformat]);
279 pixWrite(bigbuf, pix, pixformat);
305pixWriteDebug(
const char *fname,
310 return pixWrite(fname, pix, format);
312 L_INFO(
"write to named temp file %s is disabled\n", __func__, fname);
340pixWrite(
const char *fname,
348 return ERROR_INT(
"pix not defined", __func__, 1);
350 return ERROR_INT(
"fname not defined", __func__, 1);
352 if ((fp = fopenWriteStream(fname,
"wb+")) == NULL)
353 return ERROR_INT_1(
"stream not opened", fname, __func__, 1);
355 ret = pixWriteStream(fp, pix, format);
358 return ERROR_INT_1(
"pix not written to stream", fname, __func__, 1);
371pixWriteAutoFormat(
const char *filename,
377 return ERROR_INT(
"pix not defined", __func__, 1);
379 return ERROR_INT(
"filename not defined", __func__, 1);
381 if (pixGetAutoFormat(pix, &format))
382 return ERROR_INT(
"auto format not returned", __func__, 1);
383 return pixWrite(filename, pix, format);
396pixWriteStream(FILE *fp,
401 return ERROR_INT(
"stream not defined", __func__, 1);
403 return ERROR_INT(
"pix not defined", __func__, 1);
405 if (format == IFF_DEFAULT)
406 format = pixChooseOutputFormat(pix);
410 changeFormatForMissingLib(&format);
415 pixWriteStreamBmp(fp, pix);
419 return pixWriteStreamJpeg(fp, pix, var_JPEG_QUALITY, 0);
422 return pixWriteStreamPng(fp, pix, 0.0);
425 case IFF_TIFF_PACKBITS:
432 return pixWriteStreamTiff(fp, pix, format);
435 return pixWriteStreamPnm(fp, pix);
438 return pixWriteStreamPS(fp, pix, NULL, 0, DefaultScaling);
441 return pixWriteStreamGif(fp, pix);
444 return pixWriteStreamJp2k(fp, pix, 34, 0,
L_JP2_CODEC, 0, 0);
447 return pixWriteStreamWebP(fp, pix, 80, 0);
450 return pixWriteStreamPdf(fp, pix, 0, NULL);
453 return pixWriteStreamSpix(fp, pix);
456 return ERROR_INT(
"unknown format", __func__, 1);
480pixWriteImpliedFormat(
const char *filename,
488 return ERROR_INT(
"filename not defined", __func__, 1);
490 return ERROR_INT(
"pix not defined", __func__, 1);
493 format = getImpliedFileFormat(filename);
494 if (format == IFF_UNKNOWN) {
496 }
else if (format == IFF_TIFF) {
497 if (pixGetDepth(pix) == 1)
498 format = IFF_TIFF_G4;
501 format = IFF_TIFF_LZW;
503 format = IFF_TIFF_ZIP;
507 if (format == IFF_JFIF_JPEG) {
508 quality = L_MIN(quality, 100);
509 quality = L_MAX(quality, 0);
510 if (progressive != 0 && progressive != 1) {
512 L_WARNING(
"invalid progressive; setting to baseline\n", __func__);
516 pixWriteJpeg (filename, pix, quality, progressive);
518 pixWrite(filename, pix, format);
543pixChooseOutputFormat(
PIX *pix)
548 return ERROR_INT(
"pix not defined", __func__, 0);
550 d = pixGetDepth(pix);
551 format = pixGetInputFormat(pix);
552 if (format == IFF_UNKNOWN) {
554 format = IFF_TIFF_G4;
576getImpliedFileFormat(
const char *filename)
579l_int32 format = IFF_UNKNOWN;
582 return ERROR_INT(
"extension not defined", __func__, IFF_UNKNOWN);
584 if (splitPathAtExtension (filename, NULL, &extension))
587 format = getFormatFromExtension(extension);
588 LEPT_FREE(extension);
608getFormatFromExtension(
const char *extension)
611l_int32 format = IFF_UNKNOWN;
614 return ERROR_INT(
"extension not defined", __func__, IFF_UNKNOWN);
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;
646pixGetAutoFormat(
PIX *pix,
653 return ERROR_INT(
"&format not defined", __func__, 0);
654 *pformat = IFF_UNKNOWN;
656 return ERROR_INT(
"pix not defined", __func__, 0);
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;
685getFormatExtension(l_int32 format)
687 if (format < 0 || format >= NumImageFileFormatExtensions)
688 return (
const char *)ERROR_PTR(
"invalid format", __func__, NULL);
690 return ImageFileFormatExtensions[format];
718pixWriteMem(l_uint8 **pdata,
726 return ERROR_INT(
"&data not defined", __func__, 1 );
728 return ERROR_INT(
"&size not defined", __func__, 1 );
730 return ERROR_INT(
"&pix not defined", __func__, 1 );
732 if (format == IFF_DEFAULT)
733 format = pixChooseOutputFormat(pix);
737 changeFormatForMissingLib(&format);
742 ret = pixWriteMemBmp(pdata, psize, pix);
746 ret = pixWriteMemJpeg(pdata, psize, pix, var_JPEG_QUALITY, 0);
750 ret = pixWriteMemPng(pdata, psize, pix, 0.0);
754 case IFF_TIFF_PACKBITS:
761 ret = pixWriteMemTiff(pdata, psize, pix, format);
765 ret = pixWriteMemPnm(pdata, psize, pix);
769 ret = pixWriteMemPS(pdata, psize, pix, NULL, 0, DefaultScaling);
773 ret = pixWriteMemGif(pdata, psize, pix);
777 ret = pixWriteMemJp2k(pdata, psize, pix, 34, 0, 0, 0);
781 ret = pixWriteMemWebP(pdata, psize, pix, 80, 0);
785 ret = pixWriteMemPdf(pdata, psize, pix, 0, NULL);
789 ret = pixWriteMemSpix(pdata, psize, pix);
793 return ERROR_INT(
"unknown format", __func__, 1);
820l_fileDisplay(
const char *fname,
828 L_INFO(
"displaying files is disabled; "
829 "use setLeptDebugOK(1) to enable\n", __func__);
835 return ERROR_INT(
"invalid scale factor", __func__, 1);
836 if ((pixs = pixRead(fname)) == NULL)
837 return ERROR_INT(
"pixs not read", __func__, 1);
840 pixd = pixClone(pixs);
842 if (scale < 1.0 && pixGetDepth(pixs) == 1)
843 pixd = pixScaleToGray(pixs, scale);
845 pixd = pixScale(pixs, scale, scale);
847 pixDisplay(pixd, x, y);
902 return pixDisplayWithTitle(pixs, x, y, NULL, 1);
923pixDisplayWithTitle(
PIX *pixs,
931static l_atomic index = 0;
932l_int32 w, h, d, spp, maxheight, opaque, threeviews;
933l_float32 ratw, rath, ratmin;
934PIX *pix0, *pix1, *pix2;
940char fullpath[_MAX_PATH];
944 L_INFO(
"displaying images is disabled;\n "
945 "use setLeptDebugOK(1) to enable\n", __func__);
950 return ERROR_INT(
"iOS 11 does not support system()", __func__, 1);
956 return ERROR_INT(
"pixs not defined", __func__, 1);
963 return ERROR_INT(
"invalid unix program chosen for display",
968 return ERROR_INT(
"invalid windows program chosen for display",
975 if ((cmap = pixGetColormap(pixs)) != NULL)
976 pixcmapIsOpaque(cmap, &opaque);
977 spp = pixGetSpp(pixs);
978 threeviews = (spp == 4 || !opaque) ? TRUE : FALSE;
984 pix0 = pixClone(pixs);
987 pixGetDimensions(pix0, &w, &h, &d);
988 maxheight = (threeviews) ? MaxDisplayHeight / 3 : MaxDisplayHeight;
989 if (w <= MaxDisplayWidth && h <= maxheight) {
993 pix1 = pixClone(pix0);
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);
1007 pix1 = pixScale(pix0, ratmin, ratmin);
1011 return ERROR_INT(
"pix1 not made", __func__, 1);
1015 pix2 = pixDisplayLayersRGBA(pix1, 0xffffff00, 0);
1017 pix2 = pixClone(pix1);
1020 lept_rmdir(
"lept/disp");
1021 lept_mkdir(
"lept/disp");
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);
1030 snprintf(buffer, Bufsize,
"/tmp/lept/disp/write.%03d.jpg", index);
1031 pixWrite(buffer, pix2, IFF_JFIF_JPEG);
1033 tempname = genPathname(buffer, NULL);
1040 pixGetDimensions(pix2, &wt, &ht, NULL);
1041 snprintf(buffer, Bufsize,
1042 "xzgv --geometry %dx%d+%d+%d %s &", wt + 10, ht + 10,
1046 snprintf(buffer, Bufsize,
1047 "xli -dispgamma 1.0 -quiet -geometry +%d+%d -title \"%s\" %s &",
1048 x, y, title, tempname);
1050 snprintf(buffer, Bufsize,
1051 "xli -dispgamma 1.0 -quiet -geometry +%d+%d %s &",
1056 snprintf(buffer, Bufsize,
1057 "xv -quit -geometry +%d+%d -name \"%s\" %s &",
1058 x, y, title, tempname);
1060 snprintf(buffer, Bufsize,
1061 "xv -quit -geometry +%d+%d %s &", x, y, tempname);
1064 snprintf(buffer, Bufsize,
"open %s &", tempname);
1066 callSystemDebug(buffer);
1071 pathname = genPathname(tempname, NULL);
1072 _fullpath(fullpath, pathname,
sizeof(fullpath));
1075 snprintf(buffer, Bufsize,
1076 "i_view32.exe \"%s\" /pos=(%d,%d) /title=\"%s\"",
1077 fullpath, x, y, title);
1079 snprintf(buffer, Bufsize,
"i_view32.exe \"%s\" /pos=(%d,%d)",
1083 snprintf(buffer, Bufsize,
"explorer.exe /open,\"%s\"", fullpath);
1085 callSystemDebug(buffer);
1086 LEPT_FREE(pathname);
1092 LEPT_FREE(tempname);
1114pixMakeColorSquare(l_uint32 color,
1121l_int32 w, rval, gval, bval;
1125 w = (size <= 0) ? 100 : size;
1126 if (addlabel && w < 100) {
1127 L_WARNING(
"size too small for label; omitting label\n", __func__);
1131 if ((pix1 = pixCreate(w, w, 32)) == NULL)
1132 return (
PIX *)ERROR_PTR(
"pix1 not madel", __func__, NULL);
1133 pixSetAllArbitrary(pix1, color);
1140 L_ERROR(
"invalid location: adding below\n", __func__);
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);
1154l_chooseDisplayProg(l_int32 selection)
1161 var_DISPLAY_PROG = selection;
1163 L_ERROR(
"invalid display program\n",
"l_chooseDisplayProg");
1185changeFormatForMissingLib(l_int32 *pformat)
1187#if !defined(HAVE_LIBJPEG)
1188 if (*pformat == IFF_JFIF_JPEG) {
1189 L_WARNING(
"jpeg library missing; output bmp format\n", __func__);
1193#if !defined(HAVE_LIBPNG)
1194 if (*pformat == IFF_PNG) {
1195 L_WARNING(
"png library missing; output bmp format\n", __func__);
1199#if !defined(HAVE_LIBTIFF)
1200 if (L_FORMAT_IS_TIFF(*pformat)) {
1201 L_WARNING(
"tiff library missing; output bmp format\n", __func__);
1224pixDisplayWrite(
PIX *pixs,
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 "########################################################"