100 #include "config_auto.h" 105 #include <sys/types.h> 112 #include "allheaders.h" 121 static const l_int32 DEFAULT_RESOLUTION = 300;
122 static const l_int32 MANY_PAGES_IN_TIFF_FILE = 3000;
130 l_int32 *pheight, l_int32 *pbps,
131 l_int32 *pspp, l_int32 *pres,
132 l_int32 *pcmap, l_int32 *pformat);
139 static TIFF *
fopenTiff(FILE *fp,
const char *modestring);
140 static TIFF *
openTiff(
const char *filename,
const char *modestring);
147 l_uint8 **pdata,
size_t *pdatasize);
180 static struct tiff_transform tiff_partial_orientation_transforms[] = {
208 lept_read_proc(thandle_t cookie,
212 FILE* fp = (FILE *)cookie;
214 if (!buff || !cookie || !fp)
216 done = fread(buff, 1, size, fp);
221 lept_write_proc(thandle_t cookie,
225 FILE* fp = (FILE *)cookie;
227 if (!buff || !cookie || !fp)
229 done = fwrite(buff, 1, size, fp);
234 lept_seek_proc(thandle_t cookie,
238 FILE* fp = (FILE *)cookie;
239 #if defined(_MSC_VER) 251 _fseeki64(fp, 0, SEEK_END);
255 pos = (__int64)(pos + offs);
256 _fseeki64(fp, pos, SEEK_SET);
257 if (pos == _ftelli64(fp))
259 #elif defined(_LARGEFILE_SOURCE) 271 fseeko(fp, 0, SEEK_END);
275 pos = (off64_t)(pos + offs);
276 fseeko(fp, pos, SEEK_SET);
277 if (pos == ftello(fp))
291 fseek(fp, 0, SEEK_END);
295 pos = (off_t)(pos + offs);
296 fseek(fp, pos, SEEK_SET);
297 if (pos == ftell(fp))
304 lept_close_proc(thandle_t cookie)
306 FILE* fp = (FILE *)cookie;
309 fseek(fp, 0, SEEK_SET);
314 lept_size_proc(thandle_t cookie)
316 FILE* fp = (FILE *)cookie;
317 #if defined(_MSC_VER) 323 _fseeki64(fp, 0, SEEK_END);
324 size = _ftelli64(fp);
325 _fseeki64(fp, pos, SEEK_SET);
326 #elif defined(_LARGEFILE_SOURCE) 332 fseeko(fp, 0, SEEK_END);
334 fseeko(fp, pos, SEEK_SET);
341 fseek(fp, 0, SEEK_END);
343 fseek(fp, pos, SEEK_SET);
375 PROCNAME(
"pixReadTiff");
378 return (
PIX *)ERROR_PTR(
"filename not defined", procName, NULL);
381 return (
PIX *)ERROR_PTR(
"image file not found", procName, NULL);
412 PROCNAME(
"pixReadStreamTiff");
415 return (
PIX *)ERROR_PTR(
"stream not defined", procName, NULL);
418 return (
PIX *)ERROR_PTR(
"tif not opened", procName, NULL);
420 if (TIFFSetDirectory(tif, n) == 0) {
470 l_uint8 *linebuf, *data;
471 l_uint16 spp, bps, bpp, photometry, tiffcomp, orientation;
472 l_uint16 *redmap, *greenmap, *bluemap;
473 l_int32 d, wpl, bpl, comptype, i, j, ncolors, rval, gval, bval;
475 l_uint32 w, h, tiffbpl, tiffword, read_oriented;
476 l_uint32 *line, *ppixel, *tiffdata, *pixdata;
480 PROCNAME(
"pixReadFromTiffStream");
483 return (
PIX *)ERROR_PTR(
"tif not defined", procName, NULL);
488 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps);
489 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
490 if (bps != 1 && bps != 2 && bps != 4 && bps != 8 && bps != 16) {
491 L_ERROR(
"invalid bps = %d\n", procName, bps);
496 else if (spp == 3 || spp == 4)
499 return (
PIX *)ERROR_PTR(
"spp not in set {1,3,4}", procName, NULL);
502 L_WARNING(
"bpp = %d; stripping 16 bit rgb samples down to 8\n",
507 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
508 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
509 tiffbpl = TIFFScanlineSize(tif);
512 return (
PIX *)ERROR_PTR(
"pix not made", procName, NULL);
513 pixSetInputFormat(pix, IFF_TIFF);
515 wpl = pixGetWpl(pix);
518 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &tiffcomp);
525 if (spp == 1 && tiffcomp != COMPRESSION_OJPEG) {
526 linebuf = (l_uint8 *)LEPT_CALLOC(tiffbpl + 1,
sizeof(l_uint8));
527 for (i = 0 ; i < h ; i++) {
528 if (TIFFReadScanline(tif, linebuf, i, 0) < 0) {
531 return (
PIX *)ERROR_PTR(
"line read fail", procName, NULL);
533 memcpy(data, linebuf, tiffbpl);
543 if ((tiffdata = (l_uint32 *)LEPT_CALLOC((
size_t)w * h,
544 sizeof(l_uint32))) == NULL) {
546 return (
PIX *)ERROR_PTR(
"calloc fail for tiffdata", procName, NULL);
549 if (!TIFFReadRGBAImageOriented(tif, w, h, (uint32 *)tiffdata,
550 ORIENTATION_TOPLEFT, 0)) {
553 return (
PIX *)ERROR_PTR(
"failed to read tiffdata", procName, NULL);
560 for (i = 0; i < h; i++) {
561 line = pixdata + i * wpl;
562 for (j = 0; j < w; j++) {
563 tiffword = tiffdata[i * w + j];
564 rval = TIFFGetR(tiffword);
570 for (i = 0; i < h; i++, line += wpl) {
571 for (j = 0, ppixel = line; j < w; j++) {
573 tiffword = tiffdata[i * w + j];
574 rval = TIFFGetR(tiffword);
575 gval = TIFFGetG(tiffword);
576 bval = TIFFGetB(tiffword);
586 pixSetXRes(pix, xres);
587 pixSetYRes(pix, yres);
591 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &tiffcomp);
593 pixSetInputFormat(pix, comptype);
595 if (TIFFGetField(tif, TIFFTAG_COLORMAP, &redmap, &greenmap, &bluemap)) {
602 return (
PIX *)ERROR_PTR(
"invalid bps; > 8", procName, NULL);
606 return (
PIX *)ERROR_PTR(
"cmap not made", procName, NULL);
609 for (i = 0; i < ncolors; i++)
614 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometry)) {
617 if (tiffcomp == COMPRESSION_CCITTFAX3 ||
618 tiffcomp == COMPRESSION_CCITTFAX4 ||
619 tiffcomp == COMPRESSION_CCITTRLE ||
620 tiffcomp == COMPRESSION_CCITTRLEW) {
621 photometry = PHOTOMETRIC_MINISWHITE;
623 photometry = PHOTOMETRIC_MINISBLACK;
626 if ((d == 1 && photometry == PHOTOMETRIC_MINISBLACK) ||
627 (d == 8 && photometry == PHOTOMETRIC_MINISWHITE))
631 if (TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) {
632 if (orientation >= 1 && orientation <= 8) {
634 &tiff_partial_orientation_transforms[orientation - 1] :
635 &tiff_orientation_transforms[orientation - 1];
636 if (transform->vflip)
pixFlipTB(pix, pix);
637 if (transform->hflip)
pixFlipLR(pix, pix);
638 if (transform->rotate) {
647 TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &text);
685 NULL, NULL, NULL, NULL);
749 PROCNAME(
"pixWriteTiffCustom");
752 return ERROR_INT(
"filename not defined", procName, 1);
754 return ERROR_INT(
"pix not defined", procName, 1);
755 if (pixGetColormap(pix))
760 if ((tif =
openTiff(filename, modestr)) == NULL) {
762 return ERROR_INT(
"tif not opened", procName, 1);
831 PROCNAME(
"pixWriteStreamTiffWA");
834 return ERROR_INT(
"stream not defined", procName, 1 );
836 return ERROR_INT(
"pix not defined", procName, 1 );
837 if (strcmp(modestr,
"w") && strcmp(modestr,
"a"))
838 return ERROR_INT(
"modestr not 'w' or 'a'", procName, 1 );
840 if (pixGetColormap(pix))
844 if (pixGetDepth(pix1) != 1 && comptype != IFF_TIFF &&
845 comptype != IFF_TIFF_LZW && comptype != IFF_TIFF_ZIP &&
846 comptype != IFF_TIFF_JPEG) {
847 L_WARNING(
"invalid compression type for bpp > 1\n", procName);
848 comptype = IFF_TIFF_ZIP;
851 if ((tif =
fopenTiff(fp, modestr)) == NULL) {
853 return ERROR_INT(
"tif not opened", procName, 1);
859 return ERROR_INT(
"tif write error", procName, 1);
912 l_uint8 *linebuf, *data;
913 l_uint16 redmap[256], greenmap[256], bluemap[256];
914 l_int32 w, h, d, i, j, k, wpl, bpl, tiffbpl, ncolors, cmapsize;
915 l_int32 *rmap, *gmap, *bmap;
917 l_uint32 *line, *ppixel;
922 PROCNAME(
"pixWriteToTiffStream");
925 return ERROR_INT(
"tif stream not defined", procName, 1);
927 return ERROR_INT(
"pix not defined", procName, 1 );
931 xres = pixGetXRes(pix);
932 yres = pixGetYRes(pix);
933 if (xres == 0) xres = DEFAULT_RESOLUTION;
934 if (yres == 0) yres = DEFAULT_RESOLUTION;
937 TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (l_uint32)RESUNIT_INCH);
938 TIFFSetField(tif, TIFFTAG_XRESOLUTION, (l_float64)xres);
939 TIFFSetField(tif, TIFFTAG_YRESOLUTION, (l_float64)yres);
941 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (l_uint32)w);
942 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (l_uint32)h);
943 TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
946 TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, text);
949 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
950 else if (d == 32 || d == 24) {
951 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
952 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,
953 (l_uint16)8, (l_uint16)8, (l_uint16)8);
954 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (l_uint16)3);
955 }
else if ((cmap = pixGetColormap(pix)) == NULL) {
956 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
960 ncolors = L_MIN(256, ncolors);
962 cmapsize = L_MIN(256, cmapsize);
963 if (ncolors > cmapsize) {
964 L_WARNING(
"too many colors in cmap for tiff; truncating\n",
968 for (i = 0; i < ncolors; i++) {
969 redmap[i] = (rmap[i] << 8) | rmap[i];
970 greenmap[i] = (gmap[i] << 8) | gmap[i];
971 bluemap[i] = (bmap[i] << 8) | bmap[i];
973 for (i = ncolors; i < cmapsize; i++)
974 redmap[i] = greenmap[i] = bluemap[i] = 0;
979 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
980 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (l_uint16)1);
981 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, (l_uint16)d);
982 TIFFSetField(tif, TIFFTAG_COLORMAP, redmap, greenmap, bluemap);
985 if (d != 24 && d != 32) {
986 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, (l_uint16)d);
987 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, (l_uint16)1);
990 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
991 if (comptype == IFF_TIFF) {
992 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
993 }
else if (comptype == IFF_TIFF_G4) {
994 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
995 }
else if (comptype == IFF_TIFF_G3) {
996 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3);
997 }
else if (comptype == IFF_TIFF_RLE) {
998 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_CCITTRLE);
999 }
else if (comptype == IFF_TIFF_PACKBITS) {
1000 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
1001 }
else if (comptype == IFF_TIFF_LZW) {
1002 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
1003 }
else if (comptype == IFF_TIFF_ZIP) {
1004 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_ADOBE_DEFLATE);
1005 }
else if (comptype == IFF_TIFF_JPEG) {
1006 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
1008 L_WARNING(
"unknown tiff compression; using none\n", procName);
1009 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1016 tiffbpl = TIFFScanlineSize(tif);
1017 wpl = pixGetWpl(pix);
1020 fprintf(stderr,
"Big trouble: tiffbpl = %d, bpl = %d\n", tiffbpl, bpl);
1021 if ((linebuf = (l_uint8 *)LEPT_CALLOC(1, bpl)) == NULL)
1022 return ERROR_INT(
"calloc fail for linebuf", procName, 1);
1025 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, h);
1027 if (d != 24 && d != 32) {
1033 for (i = 0; i < h; i++, data += bpl) {
1034 memcpy(linebuf, data, tiffbpl);
1035 if (TIFFWriteScanline(tif, linebuf, i, 0) < 0)
1039 }
else if (d == 24) {
1040 for (i = 0; i < h; i++) {
1042 if (TIFFWriteScanline(tif, (l_uint8 *)line, i, 0) < 0)
1046 for (i = 0; i < h; i++) {
1048 for (j = 0, k = 0, ppixel = line; j < w; j++) {
1054 if (TIFFWriteScanline(tif, linebuf, i, 0) < 0)
1103 l_int32 i, n, ns, size, tagval, val;
1105 l_uint32 uval, uval2;
1107 PROCNAME(
"writeCustomTiffTags");
1110 return ERROR_INT(
"tif stream not defined", procName, 1);
1111 if (!natags && !savals && !satypes)
1113 if (!natags || !savals || !satypes)
1114 return ERROR_INT(
"not all arrays defined", procName, 1);
1117 return ERROR_INT(
"not all sa the same size", procName, 1);
1123 return ERROR_INT(
"too many 4-arg tag calls", procName, 1);
1124 for (i = 0; i < ns; i++) {
1129 if (strcmp(type,
"char*") && strcmp(type,
"l_uint8*"))
1130 L_WARNING(
"array type not char* or l_uint8*; ignore\n",
1132 TIFFSetField(tif, tagval, size, sval);
1139 for (i = ns; i < n; i++) {
1143 if (!strcmp(type,
"char*")) {
1144 TIFFSetField(tif, tagval, sval);
1145 }
else if (!strcmp(type,
"l_uint16")) {
1146 if (sscanf(sval,
"%u", &uval) == 1) {
1147 TIFFSetField(tif, tagval, (l_uint16)uval);
1149 fprintf(stderr,
"val %s not of type %s\n", sval, type);
1150 return ERROR_INT(
"custom tag(s) not written", procName, 1);
1152 }
else if (!strcmp(type,
"l_uint32")) {
1153 if (sscanf(sval,
"%u", &uval) == 1) {
1154 TIFFSetField(tif, tagval, uval);
1156 fprintf(stderr,
"val %s not of type %s\n", sval, type);
1157 return ERROR_INT(
"custom tag(s) not written", procName, 1);
1159 }
else if (!strcmp(type,
"l_int32")) {
1160 if (sscanf(sval,
"%d", &val) == 1) {
1161 TIFFSetField(tif, tagval, val);
1163 fprintf(stderr,
"val %s not of type %s\n", sval, type);
1164 return ERROR_INT(
"custom tag(s) not written", procName, 1);
1166 }
else if (!strcmp(type,
"l_float64")) {
1167 if (sscanf(sval,
"%lf", &dval) == 1) {
1168 TIFFSetField(tif, tagval, dval);
1170 fprintf(stderr,
"val %s not of type %s\n", sval, type);
1171 return ERROR_INT(
"custom tag(s) not written", procName, 1);
1173 }
else if (!strcmp(type,
"l_uint16-l_uint16")) {
1174 if (sscanf(sval,
"%u-%u", &uval, &uval2) == 2) {
1175 TIFFSetField(tif, tagval, (l_uint16)uval, (l_uint16)uval2);
1177 fprintf(stderr,
"val %s not of type %s\n", sval, type);
1178 return ERROR_INT(
"custom tag(s) not written", procName, 1);
1181 return ERROR_INT(
"unknown type; tag(s) not written", procName, 1);
1231 PROCNAME(
"pixReadFromMultipageTiff");
1234 return (
PIX *)ERROR_PTR(
"fname not defined", procName, NULL);
1236 return (
PIX *)ERROR_PTR(
"&offset not defined", procName, NULL);
1238 if ((tif =
openTiff(fname,
"r")) == NULL) {
1239 L_ERROR(
"tif open failed for %s\n", procName, fname);
1245 retval = (offset == 0) ? TIFFSetDirectory(tif, 0)
1246 : TIFFSetSubDirectory(tif, offset);
1258 TIFFReadDirectory(tif);
1259 *poffset = TIFFCurrentDirOffset(tif);
1280 PROCNAME(
"pixaReadMultipageTiff");
1283 return (
PIXA *)ERROR_PTR(
"filename not defined", procName, NULL);
1286 return (
PIXA *)ERROR_PTR(
"stream not opened", procName, NULL);
1289 L_INFO(
" Tiff: %d pages\n", procName, npages);
1291 return (
PIXA *)ERROR_PTR(
"file not tiff", procName, NULL);
1295 return (
PIXA *)ERROR_PTR(
"tif not opened", procName, NULL);
1299 for (i = 0; i < npages; i++) {
1303 L_WARNING(
"pix not read for page %d\n", procName, i);
1307 if (TIFFReadDirectory(tif) == 0)
1335 const char *modestr;
1339 PROCNAME(
"pixaWriteMultipageTiff");
1342 return ERROR_INT(
"fname not defined", procName, 1);
1344 return ERROR_INT(
"pixa not defined", procName, 1);
1347 for (i = 0; i < n; i++) {
1348 modestr = (i == 0) ?
"w" :
"a";
1350 if (pixGetDepth(pix1) == 1) {
1353 if (pixGetColormap(pix1)) {
1395 const char *fileout)
1399 PROCNAME(
"writeMultipageTiff");
1402 return ERROR_INT(
"dirin not defined", procName, 1);
1404 return ERROR_INT(
"fileout not defined", procName, 1);
1430 const char *fileout)
1434 l_int32 i, nfiles, firstfile, format;
1437 PROCNAME(
"writeMultipageTiffSA");
1440 return ERROR_INT(
"sa not defined", procName, 1);
1442 return ERROR_INT(
"fileout not defined", procName, 1);
1446 for (i = 0; i < nfiles; i++) {
1447 op = (firstfile) ?
"w" :
"a";
1450 if (format == IFF_UNKNOWN) {
1451 L_INFO(
"format of %s not known\n", procName, fname);
1455 if ((pix =
pixRead(fname)) == NULL) {
1456 L_WARNING(
"pix not made for file: %s\n", procName, fname);
1459 if (pixGetDepth(pix) == 1) {
1462 if (pixGetColormap(pix)) {
1490 const char *tiffile)
1494 PROCNAME(
"fprintTiffInfo");
1497 return ERROR_INT(
"tiffile not defined", procName, 1);
1499 return ERROR_INT(
"stream out not defined", procName, 1);
1501 if ((tif =
openTiff(tiffile,
"rb")) == NULL)
1502 return ERROR_INT(
"tif not open for read", procName, 1);
1504 TIFFPrintDirectory(tif, fpout, 0);
1528 PROCNAME(
"tiffGetCount");
1531 return ERROR_INT(
"stream not defined", procName, 1);
1533 return ERROR_INT(
"&n not defined", procName, 1);
1537 return ERROR_INT(
"tif not open for read", procName, 1);
1539 for (i = 1; ; i++) {
1540 if (TIFFReadDirectory(tif) == 0)
1542 if (i == MANY_PAGES_IN_TIFF_FILE + 1) {
1543 L_WARNING(
"big file: more than %d pages\n", procName,
1544 MANY_PAGES_IN_TIFF_FILE);
1576 PROCNAME(
"getTiffResolution");
1578 if (!pxres || !pyres)
1579 return ERROR_INT(
"&xres and &yres not both defined", procName, 1);
1580 *pxres = *pyres = 0;
1582 return ERROR_INT(
"stream not opened", procName, 1);
1585 return ERROR_INT(
"tif not open for read", procName, 1);
1611 l_int32 foundxres, foundyres;
1612 l_float32 fxres, fyres;
1614 PROCNAME(
"getTiffStreamResolution");
1617 return ERROR_INT(
"tif not opened", procName, 1);
1618 if (!pxres || !pyres)
1619 return ERROR_INT(
"&xres and &yres not both defined", procName, 1);
1620 *pxres = *pyres = 0;
1622 TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
1623 foundxres = TIFFGetField(tif, TIFFTAG_XRESOLUTION, &fxres);
1624 foundyres = TIFFGetField(tif, TIFFTAG_YRESOLUTION, &fyres);
1625 if (!foundxres && !foundyres)
return 1;
1626 if (isnan(fxres) || isnan(fyres))
return 1;
1627 if (!foundxres && foundyres)
1629 else if (foundxres && !foundyres)
1633 if (fxres < 0 || fxres > (1L << 29) || fyres < 0 || fyres > (1L << 29))
1634 return ERROR_INT(
"fxres and/or fyres values are invalid", procName, 1);
1636 if (resunit == RESUNIT_CENTIMETER) {
1637 *pxres = (l_int32)(2.54 * fxres + 0.5);
1638 *pyres = (l_int32)(2.54 * fyres + 0.5);
1640 *pxres = (l_int32)fxres;
1641 *pyres = (l_int32)fyres;
1685 PROCNAME(
"readHeaderTiff");
1689 if (pbps) *pbps = 0;
1690 if (pspp) *pspp = 0;
1691 if (pres) *pres = 0;
1692 if (pcmap) *pcmap = 0;
1693 if (pformat) *pformat = 0;
1695 return ERROR_INT(
"filename not defined", procName, 1);
1696 if (!pw && !ph && !pbps && !pspp && !pres && !pcmap && !pformat)
1697 return ERROR_INT(
"no results requested", procName, 1);
1700 return ERROR_INT(
"image file not found", procName, 1);
1701 ret =
freadHeaderTiff(fp, n, pw, ph, pbps, pspp, pres, pcmap, pformat);
1738 l_int32 i, ret, format;
1741 PROCNAME(
"freadHeaderTiff");
1745 if (pbps) *pbps = 0;
1746 if (pspp) *pspp = 0;
1747 if (pres) *pres = 0;
1748 if (pcmap) *pcmap = 0;
1749 if (pformat) *pformat = 0;
1751 return ERROR_INT(
"stream not defined", procName, 1);
1753 return ERROR_INT(
"image index must be >= 0", procName, 1);
1754 if (!pw && !ph && !pbps && !pspp && !pres && !pcmap && !pformat)
1755 return ERROR_INT(
"no results requested", procName, 1);
1758 if (format != IFF_TIFF &&
1759 format != IFF_TIFF_G3 && format != IFF_TIFF_G4 &&
1760 format != IFF_TIFF_RLE && format != IFF_TIFF_PACKBITS &&
1761 format != IFF_TIFF_LZW && format != IFF_TIFF_ZIP &&
1762 format != IFF_TIFF_JPEG)
1763 return ERROR_INT(
"file not tiff format", procName, 1);
1766 return ERROR_INT(
"tif not open for read", procName, 1);
1768 for (i = 0; i < n; i++) {
1769 if (TIFFReadDirectory(tif) == 0)
1770 return ERROR_INT(
"image n not found in file", procName, 1);
1815 PROCNAME(
"readHeaderMemTiff");
1819 if (pbps) *pbps = 0;
1820 if (pspp) *pspp = 0;
1821 if (pres) *pres = 0;
1822 if (pcmap) *pcmap = 0;
1823 if (pformat) *pformat = 0;
1824 if (!pw && !ph && !pbps && !pspp && !pres && !pcmap && !pformat)
1825 return ERROR_INT(
"no results requested", procName, 1);
1827 return ERROR_INT(
"cdata not defined", procName, 1);
1830 data = (l_uint8 *)cdata;
1832 return ERROR_INT(
"tiff stream not opened", procName, 1);
1834 for (i = 0; i < n; i++) {
1835 if (TIFFReadDirectory(tif) == 0) {
1837 return ERROR_INT(
"image n not found in file", procName, 1);
1872 l_uint16 *rmap, *gmap, *bmap;
1876 PROCNAME(
"tiffReadHeaderTiff");
1879 return ERROR_INT(
"tif not opened", procName, 1);
1882 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
1886 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
1890 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps);
1894 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
1900 *pres = (l_int32)xres;
1904 if (TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap))
1908 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &tiffcomp);
1941 PROCNAME(
"findTiffCompression");
1944 return ERROR_INT(
"&comptype not defined", procName, 1);
1945 *pcomptype = IFF_UNKNOWN;
1947 return ERROR_INT(
"stream not defined", procName, 1);
1950 return ERROR_INT(
"tif not opened", procName, 1);
1951 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &tiffcomp);
1979 case COMPRESSION_CCITTFAX4:
1980 comptype = IFF_TIFF_G4;
1982 case COMPRESSION_CCITTFAX3:
1983 comptype = IFF_TIFF_G3;
1985 case COMPRESSION_CCITTRLE:
1986 comptype = IFF_TIFF_RLE;
1988 case COMPRESSION_PACKBITS:
1989 comptype = IFF_TIFF_PACKBITS;
1991 case COMPRESSION_LZW:
1992 comptype = IFF_TIFF_LZW;
1994 case COMPRESSION_ADOBE_DEFLATE:
1995 comptype = IFF_TIFF_ZIP;
1997 case COMPRESSION_JPEG:
1998 comptype = IFF_TIFF_JPEG;
2001 comptype = IFF_TIFF;
2028 l_int32 *pminisblack)
2030 l_uint8 *inarray, *data;
2031 l_uint16 minisblack, comptype;
2033 l_uint32 w, h, rowsperstrip;
2035 size_t fbytes, nbytes;
2039 PROCNAME(
"extractG4DataFromFile");
2042 return ERROR_INT(
"&data not defined", procName, 1);
2044 return ERROR_INT(
"&nbytes not defined", procName, 1);
2045 if (!pw && !ph && !pminisblack)
2046 return ERROR_INT(
"no output data requested", procName, 1);
2051 return ERROR_INT(
"stream not opened to file", procName, 1);
2055 return ERROR_INT(
"filein not tiff", procName, 1);
2058 return ERROR_INT(
"inarray not made", procName, 1);
2061 if ((tif =
openTiff(filein,
"rb")) == NULL) {
2063 return ERROR_INT(
"tif not open for read", procName, 1);
2065 TIFFGetField(tif, TIFFTAG_COMPRESSION, &comptype);
2066 if (comptype != COMPRESSION_CCITTFAX4) {
2069 return ERROR_INT(
"filein is not g4 compressed", procName, 1);
2072 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
2073 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
2074 TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2075 if (h != rowsperstrip)
2076 L_WARNING(
"more than 1 strip\n", procName);
2077 TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &minisblack);
2080 if (pw) *pw = (l_int32)w;
2081 if (ph) *ph = (l_int32)h;
2082 if (pminisblack) *pminisblack = (l_int32)minisblack;
2088 if (inarray[0] == 0x4d) {
2089 diroff = (inarray[4] << 24) | (inarray[5] << 16) |
2090 (inarray[6] << 8) | inarray[7];
2092 diroff = (inarray[7] << 24) | (inarray[6] << 16) |
2093 (inarray[5] << 8) | inarray[4];
2100 nbytes = diroff - 8;
2102 if ((data = (l_uint8 *)LEPT_CALLOC(nbytes,
sizeof(l_uint8))) == NULL) {
2104 return ERROR_INT(
"data not allocated", procName, 1);
2107 memcpy(data, inarray + 8, nbytes);
2139 const char *modestring)
2141 PROCNAME(
"fopenTiff");
2144 return (TIFF *)ERROR_PTR(
"stream not opened", procName, NULL);
2146 return (TIFF *)ERROR_PTR(
"modestring not defined", procName, NULL);
2148 TIFFSetWarningHandler(NULL);
2149 TIFFSetErrorHandler(NULL);
2151 fseek(fp, 0, SEEK_SET);
2152 return TIFFClientOpen(
"TIFFstream", modestring, (thandle_t)fp,
2153 lept_read_proc, lept_write_proc, lept_seek_proc,
2154 lept_close_proc, lept_size_proc, NULL, NULL);
2175 const char *modestring)
2180 PROCNAME(
"openTiff");
2183 return (TIFF *)ERROR_PTR(
"filename not defined", procName, NULL);
2185 return (TIFF *)ERROR_PTR(
"modestring not defined", procName, NULL);
2187 TIFFSetWarningHandler(NULL);
2188 TIFFSetErrorHandler(NULL);
2191 tif = TIFFOpen(fname, modestring);
2246 static L_MEMSTREAM *memstreamCreateForRead(l_uint8 *indata,
size_t pinsize);
2247 static L_MEMSTREAM *memstreamCreateForWrite(l_uint8 **poutdata,
2249 static tsize_t tiffReadCallback(thandle_t handle, tdata_t data, tsize_t length);
2250 static tsize_t tiffWriteCallback(thandle_t handle, tdata_t data,
2252 static toff_t tiffSeekCallback(thandle_t handle, toff_t offset, l_int32 whence);
2253 static l_int32 tiffCloseCallback(thandle_t handle);
2254 static toff_t tiffSizeCallback(thandle_t handle);
2255 static l_int32 tiffMapCallback(thandle_t handle, tdata_t *data, toff_t *length);
2256 static void tiffUnmapCallback(thandle_t handle, tdata_t data, toff_t length);
2260 memstreamCreateForRead(l_uint8 *indata,
2266 mstream->buffer = indata;
2267 mstream->bufsize = insize;
2268 mstream->hw = insize;
2269 mstream->offset = 0;
2275 memstreamCreateForWrite(l_uint8 **poutdata,
2281 mstream->buffer = (l_uint8 *)LEPT_CALLOC(8 * 1024, 1);
2282 mstream->bufsize = 8 * 1024;
2283 mstream->poutdata = poutdata;
2284 mstream->poutsize = poutsize;
2285 mstream->hw = mstream->offset = 0;
2291 tiffReadCallback(thandle_t handle,
2299 amount = L_MIN((
size_t)length, mstream->hw - mstream->offset);
2302 if (mstream->offset + amount > mstream->hw) {
2303 fprintf(stderr,
"Bad file: amount too big: %lu\n",
2304 (
unsigned long)amount);
2308 memcpy(data, mstream->buffer + mstream->offset, amount);
2309 mstream->offset += amount;
2315 tiffWriteCallback(thandle_t handle,
2327 if (mstream->offset + length > mstream->bufsize) {
2328 newsize = 2 * (mstream->offset + length);
2329 mstream->buffer = (l_uint8 *)
reallocNew((
void **)&mstream->buffer,
2330 mstream->hw, newsize);
2331 mstream->bufsize = newsize;
2334 memcpy(mstream->buffer + mstream->offset, data, length);
2335 mstream->offset += length;
2336 mstream->hw = L_MAX(mstream->offset, mstream->hw);
2342 tiffSeekCallback(thandle_t handle,
2348 PROCNAME(
"tiffSeekCallback");
2353 mstream->offset = offset;
2357 mstream->offset += offset;
2362 mstream->offset = mstream->hw - offset;
2365 return (toff_t)ERROR_INT(
"bad whence value", procName,
2369 return mstream->offset;
2374 tiffCloseCallback(thandle_t handle)
2379 if (mstream->poutdata) {
2380 *mstream->poutdata = mstream->buffer;
2381 *mstream->poutsize = mstream->hw;
2389 tiffSizeCallback(thandle_t handle)
2399 tiffMapCallback(thandle_t handle,
2406 *data = mstream->buffer;
2407 *length = mstream->hw;
2413 tiffUnmapCallback(thandle_t handle,
2443 const char *operation,
2450 PROCNAME(
"fopenTiffMemstream");
2453 return (TIFF *)ERROR_PTR(
"filename not defined", procName, NULL);
2455 return (TIFF *)ERROR_PTR(
"operation not defined", procName, NULL);
2457 return (TIFF *)ERROR_PTR(
"&data not defined", procName, NULL);
2459 return (TIFF *)ERROR_PTR(
"&datasize not defined", procName, NULL);
2460 if (strcmp(operation,
"r") && strcmp(operation,
"w"))
2461 return (TIFF *)ERROR_PTR(
"op not 'r' or 'w'", procName, NULL);
2463 if (!strcmp(operation,
"r"))
2464 mstream = memstreamCreateForRead(*pdata, *pdatasize);
2466 mstream = memstreamCreateForWrite(pdata, pdatasize);
2468 TIFFSetWarningHandler(NULL);
2469 TIFFSetErrorHandler(NULL);
2471 tif = TIFFClientOpen(filename, operation, (thandle_t)mstream,
2472 tiffReadCallback, tiffWriteCallback,
2473 tiffSeekCallback, tiffCloseCallback,
2474 tiffSizeCallback, tiffMapCallback,
2512 PROCNAME(
"pixReadMemTiff");
2515 return (
PIX *)ERROR_PTR(
"cdata not defined", procName, NULL);
2517 data = (l_uint8 *)cdata;
2519 return (
PIX *)ERROR_PTR(
"tiff stream not opened", procName, NULL);
2522 for (i = 0; ; i++) {
2528 pixSetInputFormat(pix, IFF_TIFF);
2531 if (TIFFReadDirectory(tif) == 0)
2533 if (i == MANY_PAGES_IN_TIFF_FILE + 1) {
2534 L_WARNING(
"big file: more than %d pages\n", procName,
2535 MANY_PAGES_IN_TIFF_FILE);
2578 PROCNAME(
"pixReadMemFromMultipageTiff");
2581 return (
PIX *)ERROR_PTR(
"cdata not defined", procName, NULL);
2583 return (
PIX *)ERROR_PTR(
"&offset not defined", procName, NULL);
2585 data = (l_uint8 *)cdata;
2587 return (
PIX *)ERROR_PTR(
"tiff stream not opened", procName, NULL);
2591 retval = (offset == 0) ? TIFFSetDirectory(tif, 0)
2592 : TIFFSetSubDirectory(tif, offset);
2604 TIFFReadDirectory(tif);
2605 *poffset = TIFFCurrentDirOffset(tif);
2631 PROCNAME(
"pixaReadMemMultipageTiff");
2634 return (
PIXA *)ERROR_PTR(
"data not defined", procName, NULL);
2641 }
while (offset != 0);
2668 const char *modestr;
2673 PROCNAME(
"pixaWriteMemMultipageTiff");
2675 if (pdata) *pdata = NULL;
2677 return ERROR_INT(
"pdata not defined", procName, 1);
2679 return ERROR_INT(
"pixa not defined", procName, 1);
2683 return ERROR_INT(
"tmpfile stream not opened", procName, 1);
2685 if ((fp = tmpfile()) == NULL)
2686 return ERROR_INT(
"tmpfile stream not opened", procName, 1);
2690 for (i = 0; i < n; i++) {
2691 modestr = (i == 0) ?
"w" :
"a";
2693 if (pixGetDepth(pix1) == 1) {
2696 if (pixGetColormap(pix1)) {
2736 NULL, NULL, NULL, NULL);
2773 PROCNAME(
"pixWriteMemTiffCustom");
2776 return ERROR_INT(
"&data not defined", procName, 1);
2778 return ERROR_INT(
"&size not defined", procName, 1);
2780 return ERROR_INT(
"&pix not defined", procName, 1);
2781 if (pixGetDepth(pix) != 1 && comptype != IFF_TIFF &&
2782 comptype != IFF_TIFF_LZW && comptype != IFF_TIFF_ZIP &&
2783 comptype != IFF_TIFF_JPEG) {
2784 L_WARNING(
"invalid compression type for bpp > 1\n", procName);
2785 comptype = IFF_TIFF_ZIP;
2789 return ERROR_INT(
"tiff stream not opened", procName, 1);
l_ok pixWriteTiff(const char *filename, PIX *pix, l_int32 comptype, const char *modestr)
pixWriteTiff()
PIX * pixFlipLR(PIX *pixd, PIX *pixs)
pixFlipLR()
l_ok readHeaderTiff(const char *filename, l_int32 n, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap, l_int32 *pformat)
readHeaderTiff()
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
PIX * pixReadStreamTiff(FILE *fp, l_int32 n)
pixReadStreamTiff()
static l_int32 getTiffStreamResolution(TIFF *tif, l_int32 *pxres, l_int32 *pyres)
getTiffStreamResolution()
l_ok pixWriteMemTiff(l_uint8 **pdata, size_t *psize, PIX *pix, l_int32 comptype)
pixWriteMemTiff()
l_ok fprintTiffInfo(FILE *fpout, const char *tiffile)
fprintTiffInfo()
PIXA * pixaReadMultipageTiff(const char *filename)
pixaReadMultipageTiff()
l_ok pixWriteStreamTiffWA(FILE *fp, PIX *pix, l_int32 comptype, const char *modestr)
pixWriteStreamTiffWA()
l_ok extractG4DataFromFile(const char *filein, l_uint8 **pdata, size_t *pnbytes, l_int32 *pw, l_int32 *ph, l_int32 *pminisblack)
extractG4DataFromFile()
static l_int32 tiffReadHeaderTiff(TIFF *tif, l_int32 *pwidth, l_int32 *pheight, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap, l_int32 *pformat)
tiffReadHeaderTiff()
char * genPathname(const char *dir, const char *fname)
genPathname()
PIXA * pixaCreate(l_int32 n)
pixaCreate()
l_ok pixaWriteMultipageTiff(const char *fname, PIXA *pixa)
pixaWriteMultipageTiff()
l_ok writeMultipageTiff(const char *dirin, const char *substr, const char *fileout)
writeMultipageTiff()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
l_ok pixWriteStreamTiff(FILE *fp, PIX *pix, l_int32 comptype)
pixWriteStreamTiff()
l_ok readHeaderMemTiff(const l_uint8 *cdata, size_t size, l_int32 n, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap, l_int32 *pformat)
readHeaderMemTiff()
Memory stream buffer used with TIFFClientOpen()
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
PIX * pixReadMemFromMultipageTiff(const l_uint8 *cdata, size_t size, size_t *poffset)
pixReadMemFromMultipageTiff()
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
static TIFF * fopenTiff(FILE *fp, const char *modestring)
fopenTiff()
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
l_ok freadHeaderTiff(FILE *fp, l_int32 n, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *pres, l_int32 *pcmap, l_int32 *pformat)
freadHeaderTiff()
l_ok findFileFormatStream(FILE *fp, l_int32 *pformat)
findFileFormatStream()
l_uint8 * l_binaryRead(const char *filename, size_t *pnbytes)
l_binaryRead()
PIX * pixEndianTwoByteSwapNew(PIX *pixs)
pixEndianTwoByteSwapNew()
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
PIX * pixFlipTB(PIX *pixd, PIX *pixs)
pixFlipTB()
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
l_int32 numaGetCount(NUMA *na)
numaGetCount()
l_ok getTiffResolution(FILE *fp, l_int32 *pxres, l_int32 *pyres)
getTiffResolution()
l_ok pixcmapToArrays(PIXCMAP *cmap, l_int32 **prmap, l_int32 **pgmap, l_int32 **pbmap, l_int32 **pamap)
pixcmapToArrays()
l_ok pixWriteTiffCustom(const char *filename, PIX *pix, l_int32 comptype, const char *modestr, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
pixWriteTiffCustom()
static TIFF * fopenTiffMemstream(const char *filename, const char *operation, l_uint8 **pdata, size_t *pdatasize)
fopenTiffMemstream()
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
#define SET_DATA_BYTE(pdata, n, val)
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
static PIX * pixReadFromTiffStream(TIFF *tif)
pixReadFromTiffStream()
l_ok pixEndianTwoByteSwap(PIX *pixs)
pixEndianTwoByteSwap()
static l_int32 pixWriteToTiffStream(TIFF *tif, PIX *pix, l_int32 comptype, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
pixWriteToTiffStream()
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
static TIFF * openTiff(const char *filename, const char *modestring)
openTiff()
#define GET_DATA_BYTE(pdata, n)
l_ok findFileFormat(const char *filename, l_int32 *pformat)
findFileFormat()
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
PIX * pixClone(PIX *pixs)
pixClone()
void pixDestroy(PIX **ppix)
pixDestroy()
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
PIX * pixReadMemTiff(const l_uint8 *cdata, size_t size, l_int32 n)
pixReadMemTiff()
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
l_int32 fileFormatIsTiff(FILE *fp)
fileFormatIsTiff()
FILE * fopenReadStream(const char *filename)
fopenReadStream()
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
PIX * pixRead(const char *filename)
pixRead()
l_ok writeMultipageTiffSA(SARRAY *sa, const char *fileout)
writeMultipageTiffSA()
char * pixGetText(PIX *pix)
pixGetText()
l_ok findTiffCompression(FILE *fp, l_int32 *pcomptype)
findTiffCompression()
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
static l_int32 getTiffCompressedFormat(l_uint16 tiffcomp)
getTiffCompressedFormat()
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
l_ok pixaWriteMemMultipageTiff(l_uint8 **pdata, size_t *psize, PIXA *pixa)
pixaWriteMemMultipageTiff()
PIX * pixReadTiff(const char *filename, l_int32 n)
pixReadTiff()
PIX * pixReadFromMultipageTiff(const char *fname, size_t *poffset)
pixReadFromMultipageTiff()
PIX * pixRotate90(PIX *pixs, l_int32 direction)
pixRotate90()
static l_int32 writeCustomTiffTags(TIFF *tif, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
writeCustomTiffTags()
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
l_ok tiffGetCount(FILE *fp, l_int32 *pn)
tiffGetCount()
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
l_ok pixWriteMemTiffCustom(l_uint8 **pdata, size_t *psize, PIX *pix, l_int32 comptype, NUMA *natags, SARRAY *savals, SARRAY *satypes, NUMA *nasizes)
pixWriteMemTiffCustom()
PIXA * pixaReadMemMultipageTiff(const l_uint8 *data, size_t size)
pixaReadMemMultipageTiff()
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()