From 0ef31e1f62aa7a8b1c488a59c4930775ee0046e4 Mon Sep 17 00:00:00 2001 From: Mike Welles Date: Tue, 27 Jul 1999 21:50:26 +0000 Subject: [PATCH] Initial revision --- 1 | 5 + COPYRIGHT | 21 + Makefile | 505 ++++++++ Makefile.in | 505 ++++++++ README | 60 + README-IPTC | 41 + README-v3.5 | 8 + TODO | 7 + VERSION | 1 + config.guess | 473 +++++++ config.site | 160 +++ config.sub | 793 +++++++++++ configure | 1831 ++++++++++++++++++++++++++ contrib/acorn/Makefile | 165 +++ contrib/acorn/ReadMe | 79 ++ contrib/acorn/SetVars | 3 + contrib/acorn/cleanlib | 5 + contrib/acorn/convert | 175 +++ contrib/acorn/install | 128 ++ contrib/dbs/Imakefile | 12 + contrib/dbs/README | 7 + contrib/dbs/tiff-bi.c | 85 ++ contrib/dbs/tiff-grayscale.c | 141 ++ contrib/dbs/tiff-palette.c | 277 ++++ contrib/dbs/tiff-rgb.c | 196 +++ contrib/dbs/xtiff/Imakefile | 17 + contrib/dbs/xtiff/README | 6 + contrib/dbs/xtiff/patchlevel.h | 1 + contrib/dbs/xtiff/xtiff.c | 1275 ++++++++++++++++++ contrib/dbs/xtiff/xtifficon.h | 14 + contrib/dosdjgpp/Makefile.lib | 247 ++++ contrib/dosdjgpp/Makefile.tools | 217 ++++ contrib/dosdjgpp/Makefile.top | 54 + contrib/dosdjgpp/README | 30 + contrib/dosdjgpp/conf.bat | 11 + contrib/dosdjgpp/port.h | 29 + contrib/iptcutil/Makefile | 12 + contrib/iptcutil/iptcutil.c | 920 +++++++++++++ contrib/iptcutil/test.iptc | Bin 0 -> 1107 bytes contrib/iptcutil/test.txt | 32 + contrib/mac-cw/Makefile.script | 72 + contrib/mac-cw/README | 18 + contrib/mac-cw/mac_main.c | 20 + contrib/mac-cw/mac_main.h | 12 + contrib/mac-cw/metrowerks.note | 84 ++ contrib/mac-cw/mkg3_main.c | 14 + contrib/mac-cw/version.h | 4 + contrib/mac-mpw/BUILD.mpw | 47 + contrib/mac-mpw/README | 20 + contrib/mac-mpw/libtiff.make | 202 +++ contrib/mac-mpw/mactrans.c | 56 + contrib/mac-mpw/port.make | 53 + contrib/mac-mpw/tools.make | 138 ++ contrib/mac-mpw/top.make | 133 ++ contrib/mfs/README | 37 + contrib/mfs/mfs_file.c | 579 +++++++++ contrib/pds/README | 90 ++ contrib/pds/tif_imageiter.c | 518 ++++++++ contrib/pds/tif_imageiter.h | 57 + contrib/pds/tif_pdsdirread.c | 1124 ++++++++++++++++ contrib/pds/tif_pdsdirwrite.c | 964 ++++++++++++++ contrib/ras/README | 10 + contrib/ras/ras2tif.c | 244 ++++ contrib/ras/tif2ras.c | 337 +++++ contrib/vms/libtiff/makevms.com | 229 ++++ contrib/vms/libtiff/tiff.opt | 1 + contrib/vms/libtiff/tiffshraxp.opt | 122 ++ contrib/vms/libtiff/tiffshrvax.opt | 18 + contrib/vms/libtiff/tiffvec.mar | 131 ++ contrib/vms/tools/makevms.com | 113 ++ contrib/win32/README | 111 ++ contrib/win32/dllshell.c | 38 + contrib/win32/libtiff.def | 72 + contrib/win95/Makefile.w95 | 134 ++ contrib/win95/README | 50 + contrib/win95/tiff2dib.c | 372 ++++++ contrib/winnt/README | 26 + contrib/winnt/README.console | 182 +++ contrib/winnt/fax3sm.c | 1046 +++++++++++++++ contrib/winnt/libtiff.def | 72 + contrib/winnt/libtiff.mak | 1947 ++++++++++++++++++++++++++++ contrib/winnt/libtiff.vcp | Bin 0 -> 17408 bytes contrib/winnt/version.h | 1 + dist/newalpha | 8 + dist/newversion | 32 + dist/tiff.alpha | 1 + dist/tiff.spec | 68 + dist/tiff.version | 1 + html/Makefile.in | 104 ++ html/bugs.html | 66 + html/build.html | 1153 ++++++++++++++++ html/contrib.html | 159 +++ html/document.html | 52 + html/images.html | 39 + html/images/back.gif | Bin 0 -> 1000 bytes html/images/bali.jpg | Bin 0 -> 26152 bytes html/images/cat.gif | Bin 0 -> 12477 bytes html/images/cover.jpg | Bin 0 -> 20189 bytes html/images/cramps.gif | Bin 0 -> 13137 bytes html/images/dave.gif | Bin 0 -> 8220 bytes html/images/info.gif | Bin 0 -> 131 bytes html/images/jello.jpg | Bin 0 -> 13744 bytes html/images/jim.gif | Bin 0 -> 14493 bytes html/images/note.gif | Bin 0 -> 264 bytes html/images/oxford.gif | Bin 0 -> 6069 bytes html/images/quad.jpg | Bin 0 -> 23904 bytes html/images/ring.gif | Bin 0 -> 4275 bytes html/images/smallliz.jpg | Bin 0 -> 16463 bytes html/images/strike.gif | Bin 0 -> 5610 bytes html/images/warning.gif | Bin 0 -> 287 bytes html/index.html | 83 ++ html/internals.html | 655 ++++++++++ html/intro.html | 80 ++ html/libtiff.html | 730 +++++++++++ html/misc.html | 95 ++ html/support.html | 684 ++++++++++ html/tools.html | 178 +++ html/v3.4beta007.html | 111 ++ html/v3.4beta016.html | 121 ++ html/v3.4beta018.html | 83 ++ html/v3.4beta024.html | 138 ++ html/v3.4beta028.html | 145 +++ html/v3.4beta029.html | 85 ++ html/v3.4beta031.html | 93 ++ html/v3.4beta032.html | 89 ++ html/v3.4beta033.html | 81 ++ html/v3.4beta034.html | 67 + html/v3.4beta035.html | 62 + html/v3.4beta036.html | 116 ++ html/v3.5.html | 76 ++ html/where_is_sam.html | 35 + libtiff/Makefile | 342 +++++ libtiff/Makefile.in | 342 +++++ libtiff/Makefile.lcc | 129 ++ libtiff/mkg3states.c | 436 +++++++ libtiff/mkspans.c | 72 + libtiff/mkversion.c | 132 ++ libtiff/port.h | 32 + libtiff/t4.h | 285 ++++ libtiff/tif_acorn.c | 519 ++++++++ libtiff/tif_apple.c | 256 ++++ libtiff/tif_atari.c | 243 ++++ libtiff/tif_aux.c | 203 +++ libtiff/tif_close.c | 50 + libtiff/tif_codec.c | 116 ++ libtiff/tif_compress.c | 223 ++++ libtiff/tif_dir.c | 1131 ++++++++++++++++ libtiff/tif_dir.h | 252 ++++ libtiff/tif_dirinfo.c | 386 ++++++ libtiff/tif_dirread.c | 1368 +++++++++++++++++++ libtiff/tif_dirwrite.c | 998 ++++++++++++++ libtiff/tif_dumpmode.c | 114 ++ libtiff/tif_error.c | 49 + libtiff/tif_fax3.c | 1534 ++++++++++++++++++++++ libtiff/tif_fax3.h | 522 ++++++++ libtiff/tif_flush.c | 60 + libtiff/tif_getimage.c | 1850 ++++++++++++++++++++++++++ libtiff/tif_jpeg.c | 1477 +++++++++++++++++++++ libtiff/tif_luv.c | 1428 ++++++++++++++++++++ libtiff/tif_lzw.c | 1013 +++++++++++++++ libtiff/tif_msdos.c | 179 +++ libtiff/tif_next.c | 142 ++ libtiff/tif_open.c | 475 +++++++ libtiff/tif_packbits.c | 261 ++++ libtiff/tif_pixarlog.c | 1309 +++++++++++++++++++ libtiff/tif_predict.c | 461 +++++++ libtiff/tif_predict.h | 61 + libtiff/tif_print.c | 483 +++++++ libtiff/tif_read.c | 622 +++++++++ libtiff/tif_strip.c | 192 +++ libtiff/tif_swab.c | 217 ++++ libtiff/tif_thunder.c | 154 +++ libtiff/tif_tile.c | 219 ++++ libtiff/tif_unix.c | 209 +++ libtiff/tif_version.c | 34 + libtiff/tif_vms.c | 588 +++++++++ libtiff/tif_warning.c | 49 + libtiff/tif_win3.c | 225 ++++ libtiff/tif_win32.c | 288 ++++ libtiff/tif_write.c | 628 +++++++++ libtiff/tif_zip.c | 367 ++++++ libtiff/tiff.h | 422 ++++++ libtiff/tiffcomp.h | 214 +++ libtiff/tiffconf.h | 137 ++ libtiff/tiffio.h | 316 +++++ libtiff/tiffiop.h | 278 ++++ libtiff/uvcode.h | 173 +++ man/Makefile | 398 ++++++ man/Makefile.in | 398 ++++++ man/TIFFClose.3t | 51 + man/TIFFError.3t | 69 + man/TIFFFlush.3t | 64 + man/TIFFGetField.3t | 210 +++ man/TIFFOpen.3t | 273 ++++ man/TIFFPrintDirectory.3t | 71 + man/TIFFRGBAImage.3t | 275 ++++ man/TIFFReadDirectory.3t | 164 +++ man/TIFFReadEncodedStrip.3t | 73 ++ man/TIFFReadEncodedTile.3t | 76 ++ man/TIFFReadRGBAImage.3t | 185 +++ man/TIFFReadRawStrip.3t | 63 + man/TIFFReadRawTile.3t | 65 + man/TIFFReadScanline.3t | 99 ++ man/TIFFReadTile.3t | 85 ++ man/TIFFSetDirectory.3t | 78 ++ man/TIFFSetField.3t | 213 +++ man/TIFFWarning.3t | 70 + man/TIFFWriteDirectory.3t | 104 ++ man/TIFFWriteEncodedStrip.3t | 105 ++ man/TIFFWriteEncodedTile.3t | 98 ++ man/TIFFWriteRawStrip.3t | 94 ++ man/TIFFWriteRawTile.3t | 83 ++ man/TIFFWriteScanline.3t | 162 +++ man/TIFFbuffer.3t | 77 ++ man/TIFFcodec.3t | 73 ++ man/TIFFmemory.3t | 84 ++ man/TIFFquery.3t | 137 ++ man/TIFFsize.3t | 57 + man/TIFFstrip.3t | 96 ++ man/TIFFswab.3t | 73 ++ man/TIFFtile.3t | 134 ++ man/fax2ps.1 | 158 +++ man/fax2tiff.1 | 205 +++ man/gif2tiff.1 | 78 ++ man/libtiff.3t | 511 ++++++++ man/pal2rgb.1 | 108 ++ man/ppm2tiff.1 | 97 ++ man/ras2tiff.1 | 92 ++ man/rgb2ycbcr.1 | 98 ++ man/sgi2tiff.1 | 90 ++ man/thumbnail.1 | 87 ++ man/tiff2bw.1 | 91 ++ man/tiff2ps.1 | 177 +++ man/tiffcmp.1 | 74 ++ man/tiffcp.1 | 221 ++++ man/tiffdither.1 | 125 ++ man/tiffdump.1 | 74 ++ man/tiffgt.1 | 242 ++++ man/tiffinfo.1 | 85 ++ man/tiffmedian.1 | 109 ++ man/tiffsplit.1 | 66 + man/tiffsv.1 | 139 ++ port/Makefile.in | 67 + port/getopt.c | 116 ++ port/install.sh | 246 ++++ port/install.sh.in | 246 ++++ port/irix/so_locations | 4 + port/strcasecmp.c | 98 ++ port/strtoul.c | 107 ++ tiff.h | 421 ++++++ tools/Makefile | 251 ++++ tools/Makefile.in | 251 ++++ tools/Makefile.lcc | 132 ++ tools/fax2ps.c | 433 +++++++ tools/fax2tiff.c | 358 +++++ tools/gif2tiff.c | 512 ++++++++ tools/pal2rgb.c | 385 ++++++ tools/ppm2tiff.c | 241 ++++ tools/ras2tiff.c | 265 ++++ tools/rasterfile.h | 41 + tools/rgb2ycbcr.c | 340 +++++ tools/sgi2tiff.c | 320 +++++ tools/sgigt.c | 984 ++++++++++++++ tools/sgisv.c | 309 +++++ tools/thumbnail.c | 572 ++++++++ tools/tiff2bw.c | 400 ++++++ tools/tiff2ps.c | 1408 ++++++++++++++++++++ tools/tiffcmp.c | 483 +++++++ tools/tiffcp.c | 1266 ++++++++++++++++++ tools/tiffdither.c | 313 +++++ tools/tiffdump.c | 755 +++++++++++ tools/tiffinfo.c | 429 ++++++ tools/tiffmedian.c | 888 +++++++++++++ tools/tiffsplit.c | 226 ++++ tools/ycbcr.c | 161 +++ 275 files changed, 68113 insertions(+) create mode 100644 1 create mode 100644 COPYRIGHT create mode 100644 Makefile create mode 100644 Makefile.in create mode 100644 README create mode 100644 README-IPTC create mode 100644 README-v3.5 create mode 100644 TODO create mode 100644 VERSION create mode 100755 config.guess create mode 100644 config.site create mode 100755 config.sub create mode 100755 configure create mode 100644 contrib/acorn/Makefile create mode 100644 contrib/acorn/ReadMe create mode 100755 contrib/acorn/SetVars create mode 100755 contrib/acorn/cleanlib create mode 100644 contrib/acorn/convert create mode 100755 contrib/acorn/install create mode 100644 contrib/dbs/Imakefile create mode 100644 contrib/dbs/README create mode 100644 contrib/dbs/tiff-bi.c create mode 100644 contrib/dbs/tiff-grayscale.c create mode 100644 contrib/dbs/tiff-palette.c create mode 100644 contrib/dbs/tiff-rgb.c create mode 100644 contrib/dbs/xtiff/Imakefile create mode 100644 contrib/dbs/xtiff/README create mode 100644 contrib/dbs/xtiff/patchlevel.h create mode 100644 contrib/dbs/xtiff/xtiff.c create mode 100644 contrib/dbs/xtiff/xtifficon.h create mode 100644 contrib/dosdjgpp/Makefile.lib create mode 100644 contrib/dosdjgpp/Makefile.tools create mode 100644 contrib/dosdjgpp/Makefile.top create mode 100644 contrib/dosdjgpp/README create mode 100644 contrib/dosdjgpp/conf.bat create mode 100644 contrib/dosdjgpp/port.h create mode 100644 contrib/iptcutil/Makefile create mode 100644 contrib/iptcutil/iptcutil.c create mode 100644 contrib/iptcutil/test.iptc create mode 100644 contrib/iptcutil/test.txt create mode 100644 contrib/mac-cw/Makefile.script create mode 100644 contrib/mac-cw/README create mode 100644 contrib/mac-cw/mac_main.c create mode 100644 contrib/mac-cw/mac_main.h create mode 100644 contrib/mac-cw/metrowerks.note create mode 100644 contrib/mac-cw/mkg3_main.c create mode 100644 contrib/mac-cw/version.h create mode 100644 contrib/mac-mpw/BUILD.mpw create mode 100644 contrib/mac-mpw/README create mode 100644 contrib/mac-mpw/libtiff.make create mode 100644 contrib/mac-mpw/mactrans.c create mode 100644 contrib/mac-mpw/port.make create mode 100644 contrib/mac-mpw/tools.make create mode 100644 contrib/mac-mpw/top.make create mode 100644 contrib/mfs/README create mode 100644 contrib/mfs/mfs_file.c create mode 100644 contrib/pds/README create mode 100644 contrib/pds/tif_imageiter.c create mode 100644 contrib/pds/tif_imageiter.h create mode 100644 contrib/pds/tif_pdsdirread.c create mode 100644 contrib/pds/tif_pdsdirwrite.c create mode 100644 contrib/ras/README create mode 100644 contrib/ras/ras2tif.c create mode 100644 contrib/ras/tif2ras.c create mode 100755 contrib/vms/libtiff/makevms.com create mode 100755 contrib/vms/libtiff/tiff.opt create mode 100755 contrib/vms/libtiff/tiffshraxp.opt create mode 100755 contrib/vms/libtiff/tiffshrvax.opt create mode 100755 contrib/vms/libtiff/tiffvec.mar create mode 100755 contrib/vms/tools/makevms.com create mode 100644 contrib/win32/README create mode 100644 contrib/win32/dllshell.c create mode 100644 contrib/win32/libtiff.def create mode 100644 contrib/win95/Makefile.w95 create mode 100644 contrib/win95/README create mode 100644 contrib/win95/tiff2dib.c create mode 100644 contrib/winnt/README create mode 100644 contrib/winnt/README.console create mode 100644 contrib/winnt/fax3sm.c create mode 100644 contrib/winnt/libtiff.def create mode 100644 contrib/winnt/libtiff.mak create mode 100644 contrib/winnt/libtiff.vcp create mode 100644 contrib/winnt/version.h create mode 100755 dist/newalpha create mode 100644 dist/newversion create mode 100644 dist/tiff.alpha create mode 100644 dist/tiff.spec create mode 100644 dist/tiff.version create mode 100644 html/Makefile.in create mode 100644 html/bugs.html create mode 100644 html/build.html create mode 100644 html/contrib.html create mode 100644 html/document.html create mode 100644 html/images.html create mode 100644 html/images/back.gif create mode 100644 html/images/bali.jpg create mode 100644 html/images/cat.gif create mode 100644 html/images/cover.jpg create mode 100644 html/images/cramps.gif create mode 100644 html/images/dave.gif create mode 100644 html/images/info.gif create mode 100644 html/images/jello.jpg create mode 100644 html/images/jim.gif create mode 100644 html/images/note.gif create mode 100644 html/images/oxford.gif create mode 100644 html/images/quad.jpg create mode 100644 html/images/ring.gif create mode 100644 html/images/smallliz.jpg create mode 100644 html/images/strike.gif create mode 100644 html/images/warning.gif create mode 100644 html/index.html create mode 100644 html/internals.html create mode 100644 html/intro.html create mode 100644 html/libtiff.html create mode 100644 html/misc.html create mode 100644 html/support.html create mode 100644 html/tools.html create mode 100644 html/v3.4beta007.html create mode 100644 html/v3.4beta016.html create mode 100644 html/v3.4beta018.html create mode 100644 html/v3.4beta024.html create mode 100644 html/v3.4beta028.html create mode 100644 html/v3.4beta029.html create mode 100644 html/v3.4beta031.html create mode 100644 html/v3.4beta032.html create mode 100644 html/v3.4beta033.html create mode 100644 html/v3.4beta034.html create mode 100644 html/v3.4beta035.html create mode 100644 html/v3.4beta036.html create mode 100644 html/v3.5.html create mode 100644 html/where_is_sam.html create mode 100644 libtiff/Makefile create mode 100644 libtiff/Makefile.in create mode 100644 libtiff/Makefile.lcc create mode 100644 libtiff/mkg3states.c create mode 100644 libtiff/mkspans.c create mode 100644 libtiff/mkversion.c create mode 100644 libtiff/port.h create mode 100644 libtiff/t4.h create mode 100644 libtiff/tif_acorn.c create mode 100644 libtiff/tif_apple.c create mode 100644 libtiff/tif_atari.c create mode 100644 libtiff/tif_aux.c create mode 100644 libtiff/tif_close.c create mode 100644 libtiff/tif_codec.c create mode 100644 libtiff/tif_compress.c create mode 100644 libtiff/tif_dir.c create mode 100644 libtiff/tif_dir.h create mode 100644 libtiff/tif_dirinfo.c create mode 100644 libtiff/tif_dirread.c create mode 100644 libtiff/tif_dirwrite.c create mode 100644 libtiff/tif_dumpmode.c create mode 100644 libtiff/tif_error.c create mode 100644 libtiff/tif_fax3.c create mode 100644 libtiff/tif_fax3.h create mode 100644 libtiff/tif_flush.c create mode 100644 libtiff/tif_getimage.c create mode 100644 libtiff/tif_jpeg.c create mode 100644 libtiff/tif_luv.c create mode 100644 libtiff/tif_lzw.c create mode 100644 libtiff/tif_msdos.c create mode 100644 libtiff/tif_next.c create mode 100644 libtiff/tif_open.c create mode 100644 libtiff/tif_packbits.c create mode 100644 libtiff/tif_pixarlog.c create mode 100644 libtiff/tif_predict.c create mode 100644 libtiff/tif_predict.h create mode 100644 libtiff/tif_print.c create mode 100644 libtiff/tif_read.c create mode 100644 libtiff/tif_strip.c create mode 100644 libtiff/tif_swab.c create mode 100644 libtiff/tif_thunder.c create mode 100644 libtiff/tif_tile.c create mode 100644 libtiff/tif_unix.c create mode 100644 libtiff/tif_version.c create mode 100644 libtiff/tif_vms.c create mode 100644 libtiff/tif_warning.c create mode 100644 libtiff/tif_win3.c create mode 100644 libtiff/tif_win32.c create mode 100644 libtiff/tif_write.c create mode 100644 libtiff/tif_zip.c create mode 100644 libtiff/tiff.h create mode 100644 libtiff/tiffcomp.h create mode 100644 libtiff/tiffconf.h create mode 100644 libtiff/tiffio.h create mode 100644 libtiff/tiffiop.h create mode 100644 libtiff/uvcode.h create mode 100644 man/Makefile create mode 100644 man/Makefile.in create mode 100644 man/TIFFClose.3t create mode 100644 man/TIFFError.3t create mode 100644 man/TIFFFlush.3t create mode 100644 man/TIFFGetField.3t create mode 100644 man/TIFFOpen.3t create mode 100644 man/TIFFPrintDirectory.3t create mode 100644 man/TIFFRGBAImage.3t create mode 100644 man/TIFFReadDirectory.3t create mode 100644 man/TIFFReadEncodedStrip.3t create mode 100644 man/TIFFReadEncodedTile.3t create mode 100644 man/TIFFReadRGBAImage.3t create mode 100644 man/TIFFReadRawStrip.3t create mode 100644 man/TIFFReadRawTile.3t create mode 100644 man/TIFFReadScanline.3t create mode 100644 man/TIFFReadTile.3t create mode 100644 man/TIFFSetDirectory.3t create mode 100644 man/TIFFSetField.3t create mode 100644 man/TIFFWarning.3t create mode 100644 man/TIFFWriteDirectory.3t create mode 100644 man/TIFFWriteEncodedStrip.3t create mode 100644 man/TIFFWriteEncodedTile.3t create mode 100644 man/TIFFWriteRawStrip.3t create mode 100644 man/TIFFWriteRawTile.3t create mode 100644 man/TIFFWriteScanline.3t create mode 100644 man/TIFFbuffer.3t create mode 100644 man/TIFFcodec.3t create mode 100644 man/TIFFmemory.3t create mode 100644 man/TIFFquery.3t create mode 100644 man/TIFFsize.3t create mode 100644 man/TIFFstrip.3t create mode 100644 man/TIFFswab.3t create mode 100644 man/TIFFtile.3t create mode 100644 man/fax2ps.1 create mode 100644 man/fax2tiff.1 create mode 100644 man/gif2tiff.1 create mode 100644 man/libtiff.3t create mode 100644 man/pal2rgb.1 create mode 100644 man/ppm2tiff.1 create mode 100644 man/ras2tiff.1 create mode 100644 man/rgb2ycbcr.1 create mode 100644 man/sgi2tiff.1 create mode 100644 man/thumbnail.1 create mode 100644 man/tiff2bw.1 create mode 100644 man/tiff2ps.1 create mode 100644 man/tiffcmp.1 create mode 100644 man/tiffcp.1 create mode 100644 man/tiffdither.1 create mode 100644 man/tiffdump.1 create mode 100644 man/tiffgt.1 create mode 100644 man/tiffinfo.1 create mode 100644 man/tiffmedian.1 create mode 100644 man/tiffsplit.1 create mode 100644 man/tiffsv.1 create mode 100644 port/Makefile.in create mode 100644 port/getopt.c create mode 100644 port/install.sh create mode 100644 port/install.sh.in create mode 100644 port/irix/so_locations create mode 100644 port/strcasecmp.c create mode 100644 port/strtoul.c create mode 100644 tiff.h create mode 100644 tools/Makefile create mode 100644 tools/Makefile.in create mode 100644 tools/Makefile.lcc create mode 100644 tools/fax2ps.c create mode 100644 tools/fax2tiff.c create mode 100644 tools/gif2tiff.c create mode 100644 tools/pal2rgb.c create mode 100644 tools/ppm2tiff.c create mode 100644 tools/ras2tiff.c create mode 100644 tools/rasterfile.h create mode 100644 tools/rgb2ycbcr.c create mode 100644 tools/sgi2tiff.c create mode 100644 tools/sgigt.c create mode 100644 tools/sgisv.c create mode 100644 tools/thumbnail.c create mode 100644 tools/tiff2bw.c create mode 100644 tools/tiff2ps.c create mode 100644 tools/tiffcmp.c create mode 100644 tools/tiffcp.c create mode 100644 tools/tiffdither.c create mode 100644 tools/tiffdump.c create mode 100644 tools/tiffinfo.c create mode 100644 tools/tiffmedian.c create mode 100644 tools/tiffsplit.c create mode 100644 tools/ycbcr.c diff --git a/1 b/1 new file mode 100644 index 00000000..a0104914 --- /dev/null +++ b/1 @@ -0,0 +1,5 @@ +First post-maintenance grab version. +CVS: ---------------------------------------------------------------------- +CVS: Enter Log. Lines beginning with `CVS:' are removed automatically +CVS: +CVS: ---------------------------------------------------------------------- diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 00000000..82821861 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,21 @@ +Copyright (c) 1988-1997 Sam Leffler +Copyright (c) 1991-1997 Silicon Graphics, Inc. + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Sam Leffler and Silicon Graphics may not be used in any advertising or +publicity relating to the software without the specific, prior written +permission of Sam Leffler and Silicon Graphics. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..d7c7d68b --- /dev/null +++ b/Makefile @@ -0,0 +1,505 @@ +#! smake +# $Header: /cvs/maptools/cvsroot/libtiff/Attic/Makefile,v 1.1 1999-07-27 21:50:26 mike Exp $ +# +# Warning, this file was automatically created by the TIFF configure script +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +SRCDIR = . + +# +# VERSION: v3.4beta037 +# DATE: Wed Feb 3 19:53:27 EST 1999 +# TARGET: i586-unknown-linux +# CCOMPILER: /usr/bin/gcc +# + +SHELL = /bin/sh +NULL = +ECHO = echo +GENDIST = ${TOOLROOT}/usr/sbin/gendist +INSTALL = ${SHELL} ../port/install.sh + +all default: + @if [ "no" = yes ]; then \ + ${ECHO} "= "port; cd port; ${MAKE}; \ + else \ + true; \ + fi + @${ECHO} "= "libtiff; cd libtiff; ${MAKE} + @${ECHO} "= "tools; cd tools; ${MAKE} + @${ECHO} "= "man; cd man; ${MAKE} + +install: + @${ECHO} "= "libtiff; cd libtiff; ${MAKE} install + @${ECHO} "= "tools; cd tools; ${MAKE} install + @${ECHO} "= "man; cd man; ${MAKE} install + @if [ "no" = yes ]; then \ + ${ECHO} "= "html; cd html; ${MAKE} install; \ + else \ + true; \ + fi + +clean: + @if [ "no" = yes ]; then \ + ${ECHO} "= "port; cd port; ${MAKE} clean; \ + else \ + true; \ + fi + @${ECHO} "= "libtiff; cd libtiff; ${MAKE} clean + @${ECHO} "= "tools; cd tools; ${MAKE} clean + @${ECHO} "= "man; cd man; ${MAKE} clean +# -cd contrib/dbs; ${MAKE} clean +# -cd contrib/dbs/xtiff; ${MAKE} clean + +clobber distclean: clean + rm -f Makefile libtiff/port.h config.log + rm -f libtiff/Makefile + rm -f tools/Makefile + rm -f man/Makefile + rm -f port/Makefile port/install.sh + rm -f html/Makefile + +# +# The folllowing rule creates a binary distribution for IRIX. +# +installLink:: + if [ /usr/local/lib != /usr/lib ]; then \ + ${INSTALL} -idb tiff.sw.tools -F /usr/lib \ + -lns /usr/local/lib/libtiff.a -O libtiff.a; \ + else \ + true; \ + fi +product:: + test -d dist || mkdir dist + rm -f dist/rawidb + SRC=`pwd` RAWIDB=`pwd`/dist/rawidb ${MAKE} install installLink + rm -f dist/idb + sort -u +4 dist/rawidb > dist/idb + ${GENDIST} -v -dist dist -idb dist/idb \ + -sbase `pwd` -spec ${SRCDIR}/dist/tiff.spec + +# +# These rules are used to create the source distribution images +# + +HOST = sgi +COMPRESS= gzip +ZIPSUF = gz + +TIFFFILES=\ + configure \ + config.guess \ + config.sub \ + config.site \ + Makefile.in \ + README \ + VERSION \ + COPYRIGHT \ + TODO \ + dist/tiff.spec \ + dist/newalpha \ + dist/newversion \ + libtiff/Makefile.in \ + libtiff/Makefile.lcc \ + libtiff/t4.h \ + libtiff/tiff.h \ + libtiff/tiffcomp.h \ + libtiff/tiffconf.h \ + libtiff/tiffio.h \ + libtiff/tiffiop.h \ + libtiff/uvcode.h \ + libtiff/mkg3states.c \ + libtiff/mkspans.c \ + libtiff/mkversion.c \ + libtiff/tif_acorn.c \ + libtiff/tif_apple.c \ + libtiff/tif_atari.c \ + libtiff/tif_aux.c \ + libtiff/tif_close.c \ + libtiff/tif_codec.c \ + libtiff/tif_compress.c \ + libtiff/tif_dir.h \ + libtiff/tif_dir.c \ + libtiff/tif_dirinfo.c \ + libtiff/tif_dirread.c \ + libtiff/tif_dirwrite.c \ + libtiff/tif_dumpmode.c \ + libtiff/tif_error.c \ + libtiff/tif_fax3.c \ + libtiff/tif_fax3.h \ + libtiff/tif_flush.c \ + libtiff/tif_getimage.c \ + libtiff/tif_jpeg.c \ + libtiff/tif_luv.c \ + libtiff/tif_lzw.c \ + libtiff/tif_msdos.c \ + libtiff/tif_next.c \ + libtiff/tif_open.c \ + libtiff/tif_packbits.c \ + libtiff/tif_pixarlog.c \ + libtiff/tif_predict.h \ + libtiff/tif_predict.c \ + libtiff/tif_print.c \ + libtiff/tif_read.c \ + libtiff/tif_strip.c \ + libtiff/tif_swab.c \ + libtiff/tif_thunder.c \ + libtiff/tif_tile.c \ + libtiff/tif_unix.c \ + libtiff/tif_version.c \ + libtiff/tif_vms.c \ + libtiff/tif_warning.c \ + libtiff/tif_win3.c \ + libtiff/tif_win32.c \ + libtiff/tif_write.c \ + libtiff/tif_zip.c \ + port/Makefile.in \ + port/getopt.c \ + port/install.sh.in \ + port/irix/so_locations \ + port/strcasecmp.c \ + port/strtoul.c \ + tools/Makefile.in \ + tools/Makefile.lcc \ + tools/fax2tiff.c \ + tools/fax2ps.c \ + tools/gif2tiff.c \ + tools/pal2rgb.c \ + tools/ppm2tiff.c \ + tools/ras2tiff.c \ + tools/rasterfile.h \ + tools/rgb2ycbcr.c \ + tools/sgi2tiff.c \ + tools/sgigt.c \ + tools/sgisv.c \ + tools/thumbnail.c \ + tools/tiff2bw.c \ + tools/tiff2ps.c \ + tools/tiffcmp.c \ + tools/tiffcp.c \ + tools/tiffdither.c \ + tools/tiffdump.c \ + tools/tiffinfo.c \ + tools/tiffmedian.c \ + tools/tiffsplit.c \ + tools/ycbcr.c \ + man/Makefile.in \ + man/fax2tiff.1 \ + man/fax2ps.1 \ + man/gif2tiff.1 \ + man/pal2rgb.1 \ + man/ppm2tiff.1 \ + man/ras2tiff.1 \ + man/rgb2ycbcr.1 \ + man/sgi2tiff.1 \ + man/thumbnail.1 \ + man/tiff2bw.1 \ + man/tiff2ps.1 \ + man/tiffcmp.1 \ + man/tiffcp.1 \ + man/tiffdither.1 \ + man/tiffdump.1 \ + man/tiffgt.1 \ + man/tiffinfo.1 \ + man/tiffmedian.1 \ + man/tiffsplit.1 \ + man/tiffsv.1 \ + man/TIFFClose.3t \ + man/TIFFError.3t \ + man/TIFFFlush.3t \ + man/TIFFGetField.3t \ + man/TIFFOpen.3t \ + man/TIFFPrintDirectory.3t \ + man/TIFFReadDirectory.3t \ + man/TIFFReadEncodedStrip.3t \ + man/TIFFReadEncodedTile.3t \ + man/TIFFReadRGBAImage.3t \ + man/TIFFReadRawStrip.3t \ + man/TIFFReadRawTile.3t \ + man/TIFFReadScanline.3t \ + man/TIFFReadTile.3t \ + man/TIFFRGBAImage.3t \ + man/TIFFSetDirectory.3t \ + man/TIFFSetField.3t \ + man/TIFFWarning.3t \ + man/TIFFWriteDirectory.3t \ + man/TIFFWriteEncodedStrip.3t \ + man/TIFFWriteEncodedTile.3t \ + man/TIFFWriteRawStrip.3t \ + man/TIFFWriteRawTile.3t \ + man/TIFFWriteScanline.3t \ + man/libtiff.3t \ + man/TIFFbuffer.3t \ + man/TIFFcodec.3t \ + man/TIFFmemory.3t \ + man/TIFFquery.3t \ + man/TIFFsize.3t \ + man/TIFFstrip.3t \ + man/TIFFswab.3t \ + man/TIFFtile.3t \ + html/Makefile.in \ + html/bugs.html \ + html/build.html \ + html/contrib.html \ + html/document.html \ + html/images.html \ + html/index.html \ + html/internals.html \ + html/intro.html \ + html/libtiff.html \ + html/misc.html \ + html/support.html \ + html/tools.html \ + html/v3.4beta036.html \ + html/v3.4beta035.html \ + html/v3.4beta034.html \ + html/v3.4beta033.html \ + html/v3.4beta032.html \ + html/v3.4beta031.html \ + html/v3.4beta029.html \ + html/v3.4beta028.html \ + html/v3.4beta024.html \ + html/v3.4beta018.html \ + html/v3.4beta016.html \ + html/v3.4beta007.html \ + ${NULL} +OTHERFILES=\ + html/images/back.gif \ + html/images/bali.jpg \ + html/images/cat.gif \ + html/images/cover.jpg \ + html/images/cramps.gif \ + html/images/dave.gif \ + html/images/info.gif \ + html/images/jello.jpg \ + html/images/jim.gif \ + html/images/note.gif \ + html/images/oxford.gif \ + html/images/quad.jpg \ + html/images/ring.gif \ + html/images/smallliz.jpg \ + html/images/strike.gif \ + html/images/warning.gif \ + ${NULL} +CONTRIBFILES=\ + contrib/dbs/README \ + contrib/dbs/Imakefile \ + contrib/dbs/tiff-bi.c \ + contrib/dbs/tiff-grayscale.c \ + contrib/dbs/tiff-palette.c \ + contrib/dbs/tiff-rgb.c \ + contrib/dbs/xtiff/README \ + contrib/dbs/xtiff/Imakefile \ + contrib/dbs/xtiff/patchlevel.h \ + contrib/dbs/xtiff/xtiff.c \ + contrib/dbs/xtiff/xtifficon.h \ + contrib/ras/README \ + contrib/ras/ras2tif.c \ + contrib/ras/tif2ras.c \ + contrib/vms/libtiff/makevms.com \ + contrib/vms/libtiff/tiff.opt \ + contrib/vms/libtiff/tiffshraxp.opt \ + contrib/vms/libtiff/tiffshrvax.opt \ + contrib/vms/libtiff/tiffvec.mar \ + contrib/vms/tools/makevms.com \ + contrib/tags/README \ + contrib/tags/Makefile.gcc \ + contrib/tags/Makefile.mpw \ + contrib/tags/listtif.c \ + contrib/tags/maketif.c \ + contrib/tags/xtif_dir.c \ + contrib/tags/xtiffio.h \ + contrib/tags/xtiffiop.h \ + contrib/mac-mpw/README \ + contrib/mac-mpw/BUILD.mpw \ + contrib/mac-mpw/libtiff.make \ + contrib/mac-mpw/mactrans.c \ + contrib/mac-mpw/port.make \ + contrib/mac-mpw/tools.make \ + contrib/mac-mpw/top.make \ + contrib/acorn/ReadMe \ + contrib/acorn/Makefile \ + contrib/acorn/SetVars \ + contrib/acorn/cleanlib \ + contrib/acorn/convert \ + contrib/acorn/install \ + contrib/win32/README \ + contrib/win32/dllshell.c \ + contrib/win32/libtiff.def \ + contrib/win95/README \ + contrib/win95/Makefile.w95 \ + contrib/win95/tiff2dib.c \ + contrib/winnt/README \ + contrib/winnt/README.console \ + contrib/winnt/fax3sm.c \ + contrib/winnt/libtiff.def \ + contrib/winnt/libtiff.mak \ + contrib/winnt/libtiff.vcp \ + contrib/winnt/version.h \ + contrib/mac-cw/README \ + contrib/mac-cw/Makefile.script \ + contrib/mac-cw/mac_main.c \ + contrib/mac-cw/mac_main.h \ + contrib/mac-cw/metrowerks.note \ + contrib/mac-cw/mkg3_main.c \ + contrib/mac-cw/version.h \ + contrib/dosdjgpp/README \ + contrib/dosdjgpp/Makefile.lib \ + contrib/dosdjgpp/Makefile.tools \ + contrib/dosdjgpp/Makefile.top \ + contrib/dosdjgpp/conf.bat \ + contrib/dosdjgpp/port.h \ + contrib/mfs/README \ + contrib/mfs/mfs_file.c \ + contrib/pds/README \ + contrib/pds/tif_imageiter.c \ + contrib/pds/tif_imageiter.h \ + contrib/pds/tif_pdsdirread.c \ + contrib/pds/tif_pdsdirwrite.c \ + ${NULL} +DISTFILES=\ + ${TIFFFILES} \ + dist/tiff.alpha \ + dist/tiff.version \ + ${OTHERFILES} \ + ${CONTRIBFILES} \ + ${NULL} + +CONFIG=\ + -with-CC=cc \ + -with-GCOPTS=" " \ + -with-JPEG=yes \ + -with-DIR_JPEG=../src/jpeg-5a \ + -with-ZIP=yes \ + -with-DIR_LIBGZ=../src/zlib \ + ${NULL} + +rcsclean: + rcsclean ${TIFFFILES} && co ${TIFFFILES} + +alpha: + (cd ${SRCDIR}/dist; sh newversion) + -${MAKE} clean + ${MAKE} alpha.stamp + ${SRCDIR}/configure ${CONFIG} + ${MAKE} product + ${MAKE} alpha.tar + +# stamp relevant files according to current alpha +alpha.stamp: + VERSION="Alpha037"; \ + NOW=`date`; \ + for i in ${TIFFFILES}; do \ + REV=`rlog -h -d"$$NOW" ${SRCDIR}/$$i|fgrep 'head:'|awk '{print $$2}'`;\ + rcs "-N$$VERSION:$$REV" "-sExp:$$REV" ${SRCDIR}/$$i && co -sExp ${SRCDIR}/$$i; \ + done + +purge-old-alphas: + VERSIONS=`awk 'BEGIN { \ + for (i=1; i<=037; i++) printf " -nAlpha%03d",i;\ + exit \ + }'`; \ + for i in ${TIFFFILES}; do \ + echo rcs $$VERSIONS ${SRCDIR}/$$i; \ + rcs $$VERSIONS ${SRCDIR}/$$i && co ${SRCDIR}/$$i; \ + done + +alphadiff: + -@for i in ${TIFFFILES}; do \ + rcsdiff -r${ALPHA} ${SRCDIR}/$$i; \ + done + +# create alpha distribution archive +alpha.tar: + VERSION="v3.4beta037"; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; \ + ln -s ${SRCDIR} tiff-$$VERSION; \ + (for i in ${DISTFILES}; do \ + echo $$i; \ + done) | sed "s;.*;tiff-$$VERSION/&;" >$$VERSION; \ + tar cvf $$VERSION-tar `cat $$VERSION`; \ + rm -f tiff-$$VERSION-tar.${ZIPSUF}; \ + cat $$VERSION-tar | ${COMPRESS} >tiff-$$VERSION-tar.${ZIPSUF}; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; + +release: + (cd ${SRCDIR}/dist; sh newversion) + -${MAKE} clean + ${MAKE} release.stamp + ${SRCDIR}/configure ${CONFIG} + ${MAKE} product + ${MAKE} release.tar + +release.stamp: + NOW=`date`; \ + for i in ${TIFFFILES}; do \ + REV=`rlog -h -d"$$NOW" ${SRCDIR}/$$i|fgrep 'head:'|awk '{print $$2}'`;\ + rcs "-NRelease3_4_beta:$$REV" "-sRel:$$REV" ${SRCDIR}/$$i && co -sRel ${SRCDIR}/$$i; \ + done + +# create release distribution archive +release.tar: + VERSION="v3.4beta037"; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; \ + ln -s ${SRCDIR} tiff-$$VERSION; \ + (for i in ${DISTFILES}; do \ + echo $$i; \ + done) | sed "s;.*;tiff-$$VERSION/&;" >$$VERSION; \ + tar cvf $$VERSION-tar `cat $$VERSION`; \ + rm -f tiff-$$VERSION-tar.${ZIPSUF}; \ + cat $$VERSION-tar | ${COMPRESS} >tiff-$$VERSION-tar.${ZIPSUF}; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; + +# +# Create a package of the test images. +# + +PICS=\ + pics/README \ + pics/cramps.tif \ + pics/cramps-tile.tif \ + pics/fax2d.tif \ + pics/g3test.tif \ + pics/jello.tif \ + pics/jim___cg.tif \ + pics/jim___dg.tif \ + pics/jim___gg.tif \ + pics/jim___ah.tif \ + pics/strike.tif \ + pics/oxford.tif \ + pics/quad-lzw.tif \ + pics/quad-tile.tif \ + pics/text.tif \ + pics/ycbcr-cat.tif \ + pics/smallliz.tif \ + pics/zackthecat.tif \ + pics/fax2d.g3 \ + pics/g3test.g3 \ + ${NULL} + +pics.tar: + tar cvf - ${PICS} | ${COMPRESS} > tiffpics.tar.${ZIPSUF} diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..48c3d9fa --- /dev/null +++ b/Makefile.in @@ -0,0 +1,505 @@ +#! smake +# $Header: /cvs/maptools/cvsroot/libtiff/Makefile.in,v 1.1 1999-07-27 21:50:26 mike Exp $ +# +# @WARNING@ +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +SRCDIR = @SRCDIR@ + +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# CCOMPILER: @CCOMPILER@ +# +@SETMAKE@ +SHELL = @SCRIPT_SH@ +NULL = +ECHO = echo +GENDIST = ${TOOLROOT}/usr/sbin/gendist +INSTALL = @INSTALL@ + +all default: + @if [ "@PORT@" = yes ]; then \ + ${ECHO} "= "port; cd port; ${MAKE}; \ + else \ + true; \ + fi + @${ECHO} "= "libtiff; cd libtiff; ${MAKE} + @${ECHO} "= "tools; cd tools; ${MAKE} + @${ECHO} "= "man; cd man; ${MAKE} + +install: + @${ECHO} "= "libtiff; cd libtiff; ${MAKE} install + @${ECHO} "= "tools; cd tools; ${MAKE} install + @${ECHO} "= "man; cd man; ${MAKE} install + @if [ "@HTML@" = yes ]; then \ + ${ECHO} "= "html; cd html; ${MAKE} install; \ + else \ + true; \ + fi + +clean: + @if [ "@PORT@" = yes ]; then \ + ${ECHO} "= "port; cd port; ${MAKE} clean; \ + else \ + true; \ + fi + @${ECHO} "= "libtiff; cd libtiff; ${MAKE} clean + @${ECHO} "= "tools; cd tools; ${MAKE} clean + @${ECHO} "= "man; cd man; ${MAKE} clean +# -cd contrib/dbs; ${MAKE} clean +# -cd contrib/dbs/xtiff; ${MAKE} clean + +clobber distclean: clean + rm -f Makefile libtiff/port.h config.log + rm -f libtiff/Makefile + rm -f tools/Makefile + rm -f man/Makefile + rm -f port/Makefile port/install.sh + rm -f html/Makefile + +# +# The folllowing rule creates a binary distribution for IRIX. +# +installLink:: + if [ @DIR_LIB@ != /usr/lib ]; then \ + ${INSTALL} -idb tiff.sw.tools -F /usr/lib \ + -lns @DIR_LIB@/libtiff.@DSOSUF@ -O libtiff.@DSOSUF@; \ + else \ + true; \ + fi +product:: + test -d dist || mkdir dist + rm -f dist/rawidb + SRC=`pwd` RAWIDB=`pwd`/dist/rawidb ${MAKE} install installLink + rm -f dist/idb + sort -u +4 dist/rawidb > dist/idb + ${GENDIST} -v -dist dist -idb dist/idb \ + -sbase `pwd` -spec ${SRCDIR}/dist/tiff.spec + +# +# These rules are used to create the source distribution images +# + +HOST = sgi +COMPRESS= gzip +ZIPSUF = gz + +TIFFFILES=\ + configure \ + config.guess \ + config.sub \ + config.site \ + Makefile.in \ + README \ + VERSION \ + COPYRIGHT \ + TODO \ + dist/tiff.spec \ + dist/newalpha \ + dist/newversion \ + libtiff/Makefile.in \ + libtiff/Makefile.lcc \ + libtiff/t4.h \ + libtiff/tiff.h \ + libtiff/tiffcomp.h \ + libtiff/tiffconf.h \ + libtiff/tiffio.h \ + libtiff/tiffiop.h \ + libtiff/uvcode.h \ + libtiff/mkg3states.c \ + libtiff/mkspans.c \ + libtiff/mkversion.c \ + libtiff/tif_acorn.c \ + libtiff/tif_apple.c \ + libtiff/tif_atari.c \ + libtiff/tif_aux.c \ + libtiff/tif_close.c \ + libtiff/tif_codec.c \ + libtiff/tif_compress.c \ + libtiff/tif_dir.h \ + libtiff/tif_dir.c \ + libtiff/tif_dirinfo.c \ + libtiff/tif_dirread.c \ + libtiff/tif_dirwrite.c \ + libtiff/tif_dumpmode.c \ + libtiff/tif_error.c \ + libtiff/tif_fax3.c \ + libtiff/tif_fax3.h \ + libtiff/tif_flush.c \ + libtiff/tif_getimage.c \ + libtiff/tif_jpeg.c \ + libtiff/tif_luv.c \ + libtiff/tif_lzw.c \ + libtiff/tif_msdos.c \ + libtiff/tif_next.c \ + libtiff/tif_open.c \ + libtiff/tif_packbits.c \ + libtiff/tif_pixarlog.c \ + libtiff/tif_predict.h \ + libtiff/tif_predict.c \ + libtiff/tif_print.c \ + libtiff/tif_read.c \ + libtiff/tif_strip.c \ + libtiff/tif_swab.c \ + libtiff/tif_thunder.c \ + libtiff/tif_tile.c \ + libtiff/tif_unix.c \ + libtiff/tif_version.c \ + libtiff/tif_vms.c \ + libtiff/tif_warning.c \ + libtiff/tif_win3.c \ + libtiff/tif_win32.c \ + libtiff/tif_write.c \ + libtiff/tif_zip.c \ + port/Makefile.in \ + port/getopt.c \ + port/install.sh.in \ + port/irix/so_locations \ + port/strcasecmp.c \ + port/strtoul.c \ + tools/Makefile.in \ + tools/Makefile.lcc \ + tools/fax2tiff.c \ + tools/fax2ps.c \ + tools/gif2tiff.c \ + tools/pal2rgb.c \ + tools/ppm2tiff.c \ + tools/ras2tiff.c \ + tools/rasterfile.h \ + tools/rgb2ycbcr.c \ + tools/sgi2tiff.c \ + tools/sgigt.c \ + tools/sgisv.c \ + tools/thumbnail.c \ + tools/tiff2bw.c \ + tools/tiff2ps.c \ + tools/tiffcmp.c \ + tools/tiffcp.c \ + tools/tiffdither.c \ + tools/tiffdump.c \ + tools/tiffinfo.c \ + tools/tiffmedian.c \ + tools/tiffsplit.c \ + tools/ycbcr.c \ + man/Makefile.in \ + man/fax2tiff.1 \ + man/fax2ps.1 \ + man/gif2tiff.1 \ + man/pal2rgb.1 \ + man/ppm2tiff.1 \ + man/ras2tiff.1 \ + man/rgb2ycbcr.1 \ + man/sgi2tiff.1 \ + man/thumbnail.1 \ + man/tiff2bw.1 \ + man/tiff2ps.1 \ + man/tiffcmp.1 \ + man/tiffcp.1 \ + man/tiffdither.1 \ + man/tiffdump.1 \ + man/tiffgt.1 \ + man/tiffinfo.1 \ + man/tiffmedian.1 \ + man/tiffsplit.1 \ + man/tiffsv.1 \ + man/TIFFClose.3t \ + man/TIFFError.3t \ + man/TIFFFlush.3t \ + man/TIFFGetField.3t \ + man/TIFFOpen.3t \ + man/TIFFPrintDirectory.3t \ + man/TIFFReadDirectory.3t \ + man/TIFFReadEncodedStrip.3t \ + man/TIFFReadEncodedTile.3t \ + man/TIFFReadRGBAImage.3t \ + man/TIFFReadRawStrip.3t \ + man/TIFFReadRawTile.3t \ + man/TIFFReadScanline.3t \ + man/TIFFReadTile.3t \ + man/TIFFRGBAImage.3t \ + man/TIFFSetDirectory.3t \ + man/TIFFSetField.3t \ + man/TIFFWarning.3t \ + man/TIFFWriteDirectory.3t \ + man/TIFFWriteEncodedStrip.3t \ + man/TIFFWriteEncodedTile.3t \ + man/TIFFWriteRawStrip.3t \ + man/TIFFWriteRawTile.3t \ + man/TIFFWriteScanline.3t \ + man/libtiff.3t \ + man/TIFFbuffer.3t \ + man/TIFFcodec.3t \ + man/TIFFmemory.3t \ + man/TIFFquery.3t \ + man/TIFFsize.3t \ + man/TIFFstrip.3t \ + man/TIFFswab.3t \ + man/TIFFtile.3t \ + html/Makefile.in \ + html/bugs.html \ + html/build.html \ + html/contrib.html \ + html/document.html \ + html/images.html \ + html/index.html \ + html/internals.html \ + html/intro.html \ + html/libtiff.html \ + html/misc.html \ + html/support.html \ + html/tools.html \ + html/v3.4beta036.html \ + html/v3.4beta035.html \ + html/v3.4beta034.html \ + html/v3.4beta033.html \ + html/v3.4beta032.html \ + html/v3.4beta031.html \ + html/v3.4beta029.html \ + html/v3.4beta028.html \ + html/v3.4beta024.html \ + html/v3.4beta018.html \ + html/v3.4beta016.html \ + html/v3.4beta007.html \ + ${NULL} +OTHERFILES=\ + html/images/back.gif \ + html/images/bali.jpg \ + html/images/cat.gif \ + html/images/cover.jpg \ + html/images/cramps.gif \ + html/images/dave.gif \ + html/images/info.gif \ + html/images/jello.jpg \ + html/images/jim.gif \ + html/images/note.gif \ + html/images/oxford.gif \ + html/images/quad.jpg \ + html/images/ring.gif \ + html/images/smallliz.jpg \ + html/images/strike.gif \ + html/images/warning.gif \ + ${NULL} +CONTRIBFILES=\ + contrib/dbs/README \ + contrib/dbs/Imakefile \ + contrib/dbs/tiff-bi.c \ + contrib/dbs/tiff-grayscale.c \ + contrib/dbs/tiff-palette.c \ + contrib/dbs/tiff-rgb.c \ + contrib/dbs/xtiff/README \ + contrib/dbs/xtiff/Imakefile \ + contrib/dbs/xtiff/patchlevel.h \ + contrib/dbs/xtiff/xtiff.c \ + contrib/dbs/xtiff/xtifficon.h \ + contrib/ras/README \ + contrib/ras/ras2tif.c \ + contrib/ras/tif2ras.c \ + contrib/vms/libtiff/makevms.com \ + contrib/vms/libtiff/tiff.opt \ + contrib/vms/libtiff/tiffshraxp.opt \ + contrib/vms/libtiff/tiffshrvax.opt \ + contrib/vms/libtiff/tiffvec.mar \ + contrib/vms/tools/makevms.com \ + contrib/tags/README \ + contrib/tags/Makefile.gcc \ + contrib/tags/Makefile.mpw \ + contrib/tags/listtif.c \ + contrib/tags/maketif.c \ + contrib/tags/xtif_dir.c \ + contrib/tags/xtiffio.h \ + contrib/tags/xtiffiop.h \ + contrib/mac-mpw/README \ + contrib/mac-mpw/BUILD.mpw \ + contrib/mac-mpw/libtiff.make \ + contrib/mac-mpw/mactrans.c \ + contrib/mac-mpw/port.make \ + contrib/mac-mpw/tools.make \ + contrib/mac-mpw/top.make \ + contrib/acorn/ReadMe \ + contrib/acorn/Makefile \ + contrib/acorn/SetVars \ + contrib/acorn/cleanlib \ + contrib/acorn/convert \ + contrib/acorn/install \ + contrib/win32/README \ + contrib/win32/dllshell.c \ + contrib/win32/libtiff.def \ + contrib/win95/README \ + contrib/win95/Makefile.w95 \ + contrib/win95/tiff2dib.c \ + contrib/winnt/README \ + contrib/winnt/README.console \ + contrib/winnt/fax3sm.c \ + contrib/winnt/libtiff.def \ + contrib/winnt/libtiff.mak \ + contrib/winnt/libtiff.vcp \ + contrib/winnt/version.h \ + contrib/mac-cw/README \ + contrib/mac-cw/Makefile.script \ + contrib/mac-cw/mac_main.c \ + contrib/mac-cw/mac_main.h \ + contrib/mac-cw/metrowerks.note \ + contrib/mac-cw/mkg3_main.c \ + contrib/mac-cw/version.h \ + contrib/dosdjgpp/README \ + contrib/dosdjgpp/Makefile.lib \ + contrib/dosdjgpp/Makefile.tools \ + contrib/dosdjgpp/Makefile.top \ + contrib/dosdjgpp/conf.bat \ + contrib/dosdjgpp/port.h \ + contrib/mfs/README \ + contrib/mfs/mfs_file.c \ + contrib/pds/README \ + contrib/pds/tif_imageiter.c \ + contrib/pds/tif_imageiter.h \ + contrib/pds/tif_pdsdirread.c \ + contrib/pds/tif_pdsdirwrite.c \ + ${NULL} +DISTFILES=\ + ${TIFFFILES} \ + dist/tiff.alpha \ + dist/tiff.version \ + ${OTHERFILES} \ + ${CONTRIBFILES} \ + ${NULL} + +CONFIG=\ + -with-CC=cc \ + -with-GCOPTS=" " \ + -with-JPEG=yes \ + -with-DIR_JPEG=../src/jpeg-5a \ + -with-ZIP=yes \ + -with-DIR_LIBGZ=../src/zlib \ + ${NULL} + +rcsclean: + rcsclean ${TIFFFILES} && co ${TIFFFILES} + +alpha: + (cd ${SRCDIR}/dist; sh newversion) + -${MAKE} clean + ${MAKE} alpha.stamp + ${SRCDIR}/configure ${CONFIG} + ${MAKE} product + ${MAKE} alpha.tar + +# stamp relevant files according to current alpha +alpha.stamp: + VERSION="Alpha@DIST_ALPHA@"; \ + NOW=`date`; \ + for i in ${TIFFFILES}; do \ + REV=`rlog -h -d"$$NOW" ${SRCDIR}/$$i|fgrep 'head:'|awk '{print $$2}'`;\ + rcs "-N$$VERSION:$$REV" "-sExp:$$REV" ${SRCDIR}/$$i && co -sExp ${SRCDIR}/$$i; \ + done + +purge-old-alphas: + VERSIONS=`awk 'BEGIN { \ + for (i=1; i<=@DIST_ALPHA@; i++) printf " -nAlpha%03d",i;\ + exit \ + }'`; \ + for i in ${TIFFFILES}; do \ + echo rcs $$VERSIONS ${SRCDIR}/$$i; \ + rcs $$VERSIONS ${SRCDIR}/$$i && co ${SRCDIR}/$$i; \ + done + +alphadiff: + -@for i in ${TIFFFILES}; do \ + rcsdiff -r${ALPHA} ${SRCDIR}/$$i; \ + done + +# create alpha distribution archive +alpha.tar: + VERSION="@VERSION@"; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; \ + ln -s ${SRCDIR} tiff-$$VERSION; \ + (for i in ${DISTFILES}; do \ + echo $$i; \ + done) | sed "s;.*;tiff-$$VERSION/&;" >$$VERSION; \ + tar cvf $$VERSION-tar `cat $$VERSION`; \ + rm -f tiff-$$VERSION-tar.${ZIPSUF}; \ + cat $$VERSION-tar | ${COMPRESS} >tiff-$$VERSION-tar.${ZIPSUF}; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; + +release: + (cd ${SRCDIR}/dist; sh newversion) + -${MAKE} clean + ${MAKE} release.stamp + ${SRCDIR}/configure ${CONFIG} + ${MAKE} product + ${MAKE} release.tar + +release.stamp: + NOW=`date`; \ + for i in ${TIFFFILES}; do \ + REV=`rlog -h -d"$$NOW" ${SRCDIR}/$$i|fgrep 'head:'|awk '{print $$2}'`;\ + rcs "-NRelease@DIST_MAJOR@_@DIST_MINOR@_@DIST_TYPE@:$$REV" "-sRel:$$REV" ${SRCDIR}/$$i && co -sRel ${SRCDIR}/$$i; \ + done + +# create release distribution archive +release.tar: + VERSION="@VERSION@"; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; \ + ln -s ${SRCDIR} tiff-$$VERSION; \ + (for i in ${DISTFILES}; do \ + echo $$i; \ + done) | sed "s;.*;tiff-$$VERSION/&;" >$$VERSION; \ + tar cvf $$VERSION-tar `cat $$VERSION`; \ + rm -f tiff-$$VERSION-tar.${ZIPSUF}; \ + cat $$VERSION-tar | ${COMPRESS} >tiff-$$VERSION-tar.${ZIPSUF}; \ + rm -f tiff-$$VERSION $$VERSION $$VERSION-tar; + +# +# Create a package of the test images. +# + +PICS=\ + pics/README \ + pics/cramps.tif \ + pics/cramps-tile.tif \ + pics/fax2d.tif \ + pics/g3test.tif \ + pics/jello.tif \ + pics/jim___cg.tif \ + pics/jim___dg.tif \ + pics/jim___gg.tif \ + pics/jim___ah.tif \ + pics/strike.tif \ + pics/oxford.tif \ + pics/quad-lzw.tif \ + pics/quad-tile.tif \ + pics/text.tif \ + pics/ycbcr-cat.tif \ + pics/smallliz.tif \ + pics/zackthecat.tif \ + pics/fax2d.g3 \ + pics/g3test.g3 \ + ${NULL} + +pics.tar: + tar cvf - ${PICS} | ${COMPRESS} > tiffpics.tar.${ZIPSUF} diff --git a/README b/README new file mode 100644 index 00000000..14b103e2 --- /dev/null +++ b/README @@ -0,0 +1,60 @@ +$Header: /cvs/maptools/cvsroot/libtiff/README,v 1.1 1999-07-27 21:50:26 mike Exp $ + +TIFF Software Distribution +-------------------------- +This file is just a placeholder; all the documentation is now in +HTML in the html directory. To view the documentation point your +favorite WWW viewer at html/index.html; e.g. + + netscape html/index.html + +If you don't have an HTML viewer then you can read the HTML source +or fetch a PostScript version of this documentation from the directory + + ftp://ftp.sgi.com/graphics/tiff/doc + +If you can't hack either of these options then basically what you +want to do is: + + % ./configure + % make + % su + # make install + +If that doesn't do what you want, or something isn't clear then +sorry, but you're SOL. + + Sam Leffler (sam@engr.sgi.com) + + +Use and Copyright +----------------- +Silicon Graphics has seen fit to allow me to give this work away. It +is free. There is no support or guarantee of any sort as to its +operations, correctness, or whatever. If you do anything useful with +all or parts of it you need to honor the copyright notices. I would +also be interested in knowing about it and, hopefully, be acknowledged. + +The legal way of saying that is: + +Copyright (c) 1988-1997 Sam Leffler +Copyright (c) 1991-1997 Silicon Graphics, Inc. + +Permission to use, copy, modify, distribute, and sell this software and +its documentation for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Sam Leffler and Silicon Graphics may not be used in any advertising or +publicity relating to the software without the specific, prior written +permission of Sam Leffler and Silicon Graphics. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. diff --git a/README-IPTC b/README-IPTC new file mode 100644 index 00000000..c70f5ff5 --- /dev/null +++ b/README-IPTC @@ -0,0 +1,41 @@ +To: sam@engr.sgi.com +cc: adam@onshore.com +cc: billr@corbis.com +cc: magick@wizards.dupont.com +Subject: libtiff fork +X-Mailer: VM 6.63 under Emacs 20.3.2 +--text follows this line-- + +I've finished merging a forked libtiff that was being shipped with +ImageMagick (that added IPTC newsphoto support) with the last libtiff +release (tiff-v3.4beta037). I'm going to make this available at +ftp://ftp.onshore.com/pub/libtiff (as tiff-v3.4beta037-IPTC). + +I'm very reluctant to fork code, and I woud refrain, but for the following: + + 1. Repeated mail to you about the patches has gone unanswered. + + 2. I keep getting mail from people strugging to get IPTC newphoto support + to work properly with ImageMagick. + + 3. The NT source distibution was already shipping with a forked version. + +In order for the situation to be less confusing, I'm going to make an +archive of the forked version available. + +I very much would like for there not to be a fork. Are you still +maintaining libtiff? If not, is there a current maintainer? + +I'm willing to adopt it if there isn't. I'd hate to see such an +important library fragment. It's extremely likely that onShore +(http://onshore.com/), will donate web space, bandwidth, and listserv +services if so. + + + +------------------------------------------------------ +M. L. Welles mike@onShore.com + http://fifth.net/ +------------------------------------------------------- + + diff --git a/README-v3.5 b/README-v3.5 new file mode 100644 index 00000000..533c6bc7 --- /dev/null +++ b/README-v3.5 @@ -0,0 +1,8 @@ +Release 3.5 is merely a renaming of v3.4-beta037-IPTC to bump the +version number so that the maintainer switch is clear and folks will +know which problems I caused. See README-IPTC forchages between v3.5 +and the last version that Sam released. + + +--Mike Welles (mike@onshore.com) + diff --git a/TODO b/TODO new file mode 100644 index 00000000..741d9c86 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/TODO,v 1.1 1999-07-27 21:50:26 mike Exp $ + +o tiffcmp read data by strip/tile instead of scanline +o YCbCr sampling support +o extracate colorspace conversion support +o look at isolating all codecs from TIFF library +o JPEG colormode order dependency problem diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..9e4de5cc --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.4beta diff --git a/config.guess b/config.guess new file mode 100755 index 00000000..75907e0d --- /dev/null +++ b/config.guess @@ -0,0 +1,473 @@ +#!/bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:V*:*) + # After 1.2, OSF1 uses "V1.3" for uname -r. + echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'` + exit 0 ;; + alpha:OSF1:*:*) + # 1.2 uses "1.2" for uname -r. + echo alpha-dec-osf${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + Pyramid*:OSx*:*:*) + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + sun4*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + mips:*:5*:RISCos) + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix${UNAME_RELEASE} + exit 0 ;; + i[34]86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if grep bos410 /usr/include/stdio.h >/dev/null 2>&1; then + IBM_REV=4.1 + elif grep bos411 /usr/include/stdio.h >/dev/null 2>&1; then + IBM_REV=4.1.1 + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?7 ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?7:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:UNICOS:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:UNICOS:*:*) + echo ymp-cray-unicos + exit 0 ;; + CRAY-2:UNICOS:*:*) + echo cray2-cray-unicos + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + i[34]86:BSD/386:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i[34]86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i[34]86:*:3.2:*) + if test -d /etc/conf/cf.d -a -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-unknown-sysv32 + fi + exit 0 ;; + Intel:Mach:3*:*) + echo i386-unknown-mach3 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M680[234]0:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3 && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m680[234]0:LynxOS:2.2*:*) + echo m68k-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i[34]86:LynxOS:2.2*:*) + echo i386-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.2*:*) + echo sparc-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.2*:*) + echo rs6000-lynx-lynxos${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c </dev/null`; + printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-unknown-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.site b/config.site new file mode 100644 index 00000000..1c2959ff --- /dev/null +++ b/config.site @@ -0,0 +1,160 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/Attic/config.site,v 1.1 1999-07-27 21:50:26 mike Exp $ +# +# TIFF Software +# +# Copyright (c) 1990-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# +# This file holds site-specific configuration parameters. +# +# Nothing is defined in here by default, the definitions +# commented out below serve as documentation for what you +# can set in this file or a config.local file. +# +# Note that you do not need to set anything here unless you +# want to override the auto-configuration behaviour and/or +# interactive prompting done by the configure script. +# + +# +# Package controls. +# +#DSO="auto" # auto|IRIX|IRIX52 enable DSO support for system +#JPEG="no" # yes|no configure JPEG support (see below) +#ZIP="no" # yes|no configure Deflate support (see below) +#LIBGL="auto" # yes|no|auto configure IRIS GL-based tools +#LIBIMAGE="auto" # yes|no|auto configure SGI RGB image tools +#HTML="no" # yes|no install HTML documentation + +# +# Directory parameters. +# +#DIR_BIN="/usr/local/bin" # directory for tools +#DIR_LIB="/usr/local/lib" # directory for libraries +#DIR_INC="/usr/local/include" # directory for include files +#DIR_MAN="/usr/local/man" # directory for manual pages +#DIR_HTML="/var/httpd/htdocs/tiff" # directory for HTML documentation + +# +# Configuring supporting libraries. +# +# The TIFF software makes use of two ancillary packages: the IJG +# distribution to support the JPEG codec and the zlib distribution +# to support the Deflate codec. To setup use of these packages you +# need to specify where each package's include files are located and +# where the pre-built library (static archive or DSO) is located. +# These may be different or the same (as when the package is compiled +# and referenced directly from the place where the software was +# loaded and compiled). +# +# DIRS_LIBINC is a space-separated list of directories to use for +# locating include files in these packages. Note that it should not +# include -I options as might be passed to the C preprocessor; these +# are automatically added by the configure script when the Makefiles +# are generated. +# +# DIR_LIB is the pathname of the directory where 's +# pre-built library may be found; this is used when building a TIFF +# DSO (on systems where support is present) and when building the +# programs in the tools directory. By default the configure script +# will load the associated library using +# +# -L${DIR_LIB} -l +# +# e.g. -L${DIR_JPEGLIB} -ljpeg. If this is wrong for your system +# (e.g. your compiler/loader does not support the -L option), then +# the LIB parameter can be set explicitly to specify the +# library to use. +# + +# +# JPEG-specific parameters; used when JPEG support is enabled (see above). +# +# JPEG support requires release 5 or later of the IJG code, +# which you can find on the Internet at ftp.uu.net:/graphics/jpeg/. +# +#DIRS_LIBINC="$DIRS_LIBINC ../src/jpeg-5a" # directory for jpeg include files +#DIR_JPEGLIB=../src/jpeg-5a # directory for libjpeg + +# +# Deflate-specific parameters; used when Deflate support is enabled (see above). +# +# NB: Deflate support requires version 0.92 or later of the zlib +# library written by Jean-loup Gailly and Mark Adler. Starting +# with about 0.95 the library is called libz.a (previously it was +# libgz.a). The library was last found at +# +# ftp://ftp.uu.net/graphics/png/code/zlib-0.93.tar.gz +# +# Look for it also at ftp://ftp.uu.net/pub/archiving/zip/zlib. +# +#DIRS_LIBINC="$DIRS_LIBINC ../zlib" # directory for zlib include files +#DIR_GZLIB="../zlib" # directory for libz + +# +# Miscellaneous parameters. +# +#FILLORDER="MS2LSB" # bit order of cpu (MSB2LSB/LSB2MSB) +#MANSCHEME="sysv-source-cat-strip" # manual page installation scheme + +# +# Parameters used when building the software. +# +# Note that configure has several ENVOPTS built into it that are +# set according to the target. This is done to help naive folks. +# +# Beware of changing the INSTALL definition; you *must* have an +# install script that emulates the Silicon Graphics install program! +# +#AR="/bin/ar" # pathname of suitable ar program +#AROPTS="rc" # options to ar for creating archive +#CC="gcc" # name/pathname of C compiler +#ENVOPTS="-Aa" # options for getting ANSI C +#GCOPTS="-g" # options to pass C compiler +#LIBPORT='${PORT}/libport.a' # library with emulation code +#MACHDEPLIBS="" # extra libraries for linking +#PORTFUNCS="" # non-standard functions to emulate +#RANLIB=":" # pathname of suitable ranlib program +#DSOSUF="so" # DSO filename suffix +#LIBCOPTS="-K PIC" # compiler options for building library + +# +# Makefile construction parameters. +# +# These should not normally be set; configure will +# deduce the appropriate syntax to use for includes. +# +#SETMAKE='MAKE = ${MAKE}' # define if make does not setup $MAKE + +# +# General system stuff used by the distribution. +# +#CHMOD="/etc/chmod" # pathname of suitable chmod program +#INSTALL='${SHELL} ${PORT}/install.sh' # SGI install program/emulator +#LN="/bin/ln" # pathname of suitable ln program +#LN_S="-s" # option to ${LN} to create symlink +#MV_F="-f" # option to ${MV} to force operation +#SED="/bin/sed" # pathname of suitable sed program +#SCRIPT_SH="/bin/sh" # pathname of suitable shell +#STRIP="/bin/strip" # strip program used by install.sh diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..bf932cb9 --- /dev/null +++ b/config.sub @@ -0,0 +1,793 @@ +#!/bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS (if any). +basic_machine=`echo $1 | sed 's/-[^-]*$//'` +if [ $basic_machine != $1 ] +then os=`echo $1 | sed 's/.*-/-/'` +else os=; fi + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp ) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` + ;; + -lynx) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | pyramid \ + | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ + | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \ + | powerpc | sparc64 | 1750a | dsp16xx | mips64 | mipsel \ + | pdp11 | mips64el | mips64orion | mips64orionel ) + basic_machine=$basic_machine-unknown + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \ + | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ + | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ + | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ + | pdp11-* | sh-* | powerpc-* | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* ) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigados) + basic_machine=m68k-cbm + os=-amigados + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[345]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv32 + ;; + i[345]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv4 + ;; + i[345]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-sysv + ;; + i[345]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium-*) + # We will change tis to say i586 once there has been + # time for various packages to start to recognize that. + basic_machine=i486-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + ps2) + basic_machine=i386-ibm + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + basic_machine=mips-mips + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative must end in a *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \ + | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ + | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -winnt*) + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigados + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-masscomp) + os=-rtu + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -lynxos*) + vendor=lynx + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100755 index 00000000..5a62b626 --- /dev/null +++ b/configure @@ -0,0 +1,1831 @@ +#!/bin/sh +# $Header: /cvs/maptools/cvsroot/libtiff/configure,v 1.1 1999-07-27 21:50:26 mike Exp $ +# +# Tag Image File Format (TIFF) Software +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# Configuration script for the TIFF Software + +# +# Shell script to setup machine-dependent files in +# preparation for building TIFF source. +# + +POSIXLY_CORRECT=1; export POSIXLY_CORRECT # disable GNU extensions + +QUIET=no # suppress messages to tty +NONINTERACTIVE=no # control prompting of config params +SITE= # dir where config.site is located +TARGET= # target system identity +SRCDIR= # dir where source is located + +# +# Setup general configuration parameters. +# +DIR_BIN=/usr/local/bin # destination for applications +DIR_LIB=/usr/local/lib # destination for library +DIR_INC=/usr/local/include # destination for include files +DIR_HTML=/var/httpd/htdocs/tiff # destination for HTML files +DIRS_LIBINC= # dirs to search for ancillary includes +DIR_JPEGLIB= # dir for IJG -ljpeg +DIR_GZLIB= # dir for zlib -lgz +DSO=auto # auto-enable DSO support +LIBCOPTS= # library-specific C-compiler options +JPEG=no # configure JPEG support +ZIP=no # configure ZIP/Deflate support +PORT=auto # enable portability emulations +HTML=no # install HTML documentation +LIBGL=auto # auto-enable build of SGI -lgl apps +LIBIMAGE=auto # auto-enable build of SGI -limage apps +MACHDEPLIBS=-lm # machine-dependent libraries for apps +: ${CC=} # name of C compiler to use +: ${CCOMPILER=} # full pathname of C compiler +: ${ENVOPTS=} # CC opts for ANSI C compilation +: ${MAKE=make} # make to use + +# screws up the test of `-f -' +: ${MAKEFLAGS=} # unset MAKEFLAGS +RM="rm -f" + +# +# Error diagnostics that should go to the terminal are +# done with this interface (or cat). +# +bitch() +{ + echo "configure: $@" 1>&2 +} + +# +# This is the preferred interface for +# configure to terminate abnormally. +# +boom() +{ + bitch "" + bitch "Unrecoverable error! Once you've corrected the problem rerun this script." + kill -1 $$ # use kill so trap handler is called +} + +usage() +{ + cat<<'EOF' +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] + --help print this message + --quiet do not print `Using ...' messages + --verbose opposite of --quiet + --noninteractive don't ask any questions + --version print the version of autoconf that created configure + --target=TARGET configure for TARGET [TARGET=HOST] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --with-PARAM[=ARG] set configuration PARAM [ARG=yes] +EOF +} + +# +# Crack command line arguments. We purposely +# use syntax and options that are compatible +# with GNU autoconf. +# +ac_prev= +for ac_option +do + if [ -n "$ac_prev" ]; then # assign the argument to previous option + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + case "$ac_option" in # collect optional argument + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'`;; + *) ac_optarg=;; + esac + case "$ac_option" in + -with-*|--with-*) + ac_with=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if [ -n "`echo $ac_with| sed 's/[-_a-zA-Z0-9]//g'`" ]; then + bitch "configure: $ac_with: invalid parameter name." + kill -1 $$ + fi + ac_with=`echo $ac_with| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes;; + esac + eval "${ac_with}='$ac_optarg'" + ;; + -quiet|--quiet) QUIET=yes;; + -verbose|--verbose) QUIET=no;; + -noninteractive|--noninteractive) NONINTERACTIVE=yes;; + -site|--site) ac_prev=SITE;; + -site=*|--site=*) SITE="$ac_optarg";; + -srcdir|--srcdir) ac_prev=SRCDIR;; + -srcdir=*|--srcdir=*) SRCDIR="$ac_optarg";; + -target|--target) ac_prev=TARGET;; + -target=*|--target=*) TARGET="$ac_optarg" ;; + -version|--version) + echo "This is TIFF configure $Revision: 1.1 $" + exit 0 + ;; + -help|--help) usage; exit 0;; + -*) + bitch "configure: $ac_option: invalid option; use -help for usage." + kill -1 $$ + ;; + *) + if [ x"$TARGET" != x ]; then + bitch "configure: Can only configure for one target at a time." + kill -1 $$ + fi + TARGET="$ac_option" + ;; + esac +done + +if [ -n "$ac_prev" ]; then + bitch "configure: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" + kill -1 $$ +fi + +# +# Locate source directory by looking for the VERSION file. +# The directory must either be specified through the +# environment or be located in the current directory or a +# parent of the current directory. +# +test "$SRCDIR" || { + configure=$0 + # NB: don't use dirname since it may not exist + SRCDIR=`echo $configure | sed 's;/[^/][^/]*$;;'` + if [ @"$SRCDIR" = @"$configure" ]; then + SRCDIR=. + fi + while [ ! -r $SRCDIR/VERSION ]; do + # strip last directory from pathname + newdir=`echo $SRCDIR | sed 's;/[^/]*$;;'` + if [ -z "$newdir" ] || [ "$newdir" = $SRCDIR ]; then + break; + fi + SRCDIR=$newdir + done +} +if [ ! -r $SRCDIR/VERSION ]; then + bitch "Cannot locate sources in $SRCDIR." + kill -1 $$ +fi +SRCDIR=`echo "$SRCDIR" | sed 's;\([^/]\)/*$;\1;'` + +if [ -r ${SRCDIR}/tif_version.c ] ; then + SRCDIR_IS_LIBTIFF=yes + PORTDOTH=port.h +else + SRCDIR_IS_LIBTIFF=no + PORTDOTH=libtiff/port.h +fi + +# +# Descriptor usage: +# 1: ??? +# 2: errors that should be seen even if we're in the background. +# 3: [stdout from test runs] +# 4: verbose-style messages (Using ...) +# 5: compiler stderr when running tests +# +if [ $QUIET = yes ]; then + exec 4>/dev/null # chuck messages +else + exec 4>&1 # messages got to stdout +fi +exec 5>./config.log # compiler messages and the like + +capture() +{ + (eval "set -x; $*") >&5 2>&1 + return +} +captureX() +{ + (eval "set -x; $*") 2>&5 + return +} + +date >&5 +echo Running "$0" with arguments: "$@" >&5 + +cat 1>&5 <<'EOF' + +This file contains information that is captured from running the configure +script. Lines that begin with a "+" are command lines echoed by the +shell. Other lines are the output of commands; usually the contents of +test case files or the output from compilers. If configure does the +wrong thing, you can use the information captured here to aid in debugging. + +EOF + +if [ -r $SRCDIR/tiff.alpha ] ; then + VERSIONFILE=$SRCDIR/VERSION + ALPHAFILE=$SRCDIR/tiff.alpha +else + VERSIONFILE=$SRCDIR/VERSION + ALPHAFILE=$SRCDIR/dist/tiff.alpha +fi +DATE=`date` + +eval `cat $VERSIONFILE | sed 's/\([0-9][0-9]*\)\.\([0-9][0-9]*\)\(.*\)/DIST_MAJOR=\1; DIST_MINOR=\2; DIST_TYPE=\3/'` +DIST_ALPHA=`awk '{print $3}' $ALPHAFILE` +VERSION="v${DIST_MAJOR}.${DIST_MINOR}${DIST_TYPE}" +if [ $DIST_TYPE = beta ]; then + VERSION="${VERSION}${DIST_ALPHA}" +fi + +Note() +{ + echo "$@" 1>&4 +} + +Note "" +if [ $SRCDIR_IS_LIBTIFF = yes ] ; then + Note "Configuring TIFF Software (library only) $VERSION." +else + Note "Configuring TIFF Software $VERSION." +fi + +Note "" +Note "If configure does the wrong thing, check the file config.log for" +Note "information that may help you understand what went wrong." +Note "" + +# +# Read site and local configuration parameters. +# +if [ -f $SITE/config.site ]; then + Note "Reading site-wide parameters from $SITE/config.site." + . $SITE/config.site + capture . $SITE/config.site +elif [ -f $SRCDIR/config.site ]; then + Note "Reading site-wide parameters from $SRCDIR/config.site." + . $SRCDIR/config.site + capture . $SRCDIR/config.site +fi +if [ -f config.local ]; then + Note "Reading local parameters from config.local." + . ./config.local + capture . ./config.local +elif [ -f $SRCDIR/config.local ]; then + Note "Reading local parameters from $SRCDIR/config.local." + . $SRCDIR/config.local + capture . $SRCDIR/config.local +fi + +# +# Emulate old-style settups... +# +test -z "${DIR_JPEG-}" || { + DIRS_LIBINC="${DIRS_LIBINC} ${DIR_JPEG}" + DIR_JPEGLIB="${DIR_JPEG}" +} +test -z "${DIR_LIBGZ-}" || { + DIRS_LIBINC="${DIRS_LIBINC} ${DIR_LIBGZ}" + DIR_GZLIB="${DIR_LIBGZ}" +} + +identifyTarget() +{ + random=`date | awk '{print $4}' | sed -e 's/.*://'` 2>/dev/null + case "$random" in + *0) Note "Wow, you've got a $1 system!";; + *1) Note "Hmm, looks like a $1 system.";; + *2) Note "Oh no, not another $1 system...";; + *3) Note "Well I'll be, a $1 system.";; + *4) Note "Fee, fie, foe, this smells like a $1 system.";; + *5) Note "Gosh, aren't you lucky to have a $1 system!";; + *6) Note "YOW!! Did something bad happen or am I on a $1 system?";; + *7) Note "Do they really still make $1 systems?!";; + *8) Note "I'm always happy to encounter another $1 system.";; + *9) Note "Here we are again, this time on a $1 system.";; +esac +} + +# +# If no target is specified, try to deduce the system. +# We use the GNU scripts for guessing and canonicalizing +# the system identification, if available. +# +if [ -z "$TARGET" ]; then + test -f $SRCDIR/config.guess && TARGET=`sh $SRCDIR/config.guess` 2>/dev/null + if [ -z "$TARGET" ]; then + bitch "Sorry, no target specified on the command line and I don't seem" + bitch "to have the GNU config.guess script that is used to deduce your" + bitch "system type." + kill -1 $$ + fi + identifyTarget $TARGET +elif [ -f $SRCDIR/config.sub ]; then + TARGET=`sh $SRCDIR/config.sub "$TARGET"` +else + Note "Warning, I don't seem to have the GNU config.sub script to canonicalize" + Note "your target specification; this may cause problems later on..." +fi +if [ -z "${FILLORDER-}" ]; then + # + # Host bit order within a word. + # + case $TARGET in + mips-dec-*) FILLORDER=LSB2MSB;; + i[345]86-*) FILLORDER=LSB2MSB;; + *) FILLORDER=MSB2LSB;; + esac +fi + +# +# Find the full pathname of a file +# using the specified test operation. +# +findThing() +{ + t="$1"; app="$2"; path="$3"; + case "$app" in + /*) eval "$t" "$app" && { echo "$app"; return; };; + esac + (IFS=: + for i in $path; do + eval "$t" "$i/$app" && { echo "$i/$app"; return 0; } + done + return 1 + ) +} + +# +# Find the full pathname of a plain file. +# +findFile() +{ + findThing "test -f" "$1" "$2" +} + +# +# Find the full pathname of an executable. +# +findApp() +{ + findThing "test -x" $1 $2 +} + +# +# Find the full pathname of an executable; +# supply a default if nothing is found. +# +findAppDef() +{ + app=$1; path=$2; def=$3 + case $app in + /*) test -x $app && { echo $app; return; };; + esac + IFS=: + for i in $path; do + test -x $i/$app && { echo $i/$app; return; } + done + echo $def +} + +# +# Find the full pathname of a header file; in search-path $DIRS_LIBINC +# +findHeader() +{ + case "$1" in + /*) echo "$1"; return ;; + esac + for i in ${DIRS_LIBINC} /usr/include; do + test -r $i/$1 && { + case "$i" in + /*) echo "$i/$1"; return ;; + esac + if [ $SRCDIR_IS_LIBTIFF = yes ]; then + echo "$i/$1"; + else + echo "../$i/$1"; + fi + return; + } + done +} + +# +# Locate a C compiler that satisfies our needs (using assorted heuristics). +# +JUNK=" + a.out + confsed + conftestmmap + confx confy + confMakefile + core + dummy + dummy.a + dummy.c + dummy.o + foo + so_locations + t.c + t.o + t + xMakedepend + xdefs + xgnu.c + xmakeinc + xport.h +" +trap "$RM \$JUNK; exit 1" 1 2 15 + +$RM $JUNK + +cat>xgnu.c<&5 | egrep yes)" +} + +# +# NB: use ANSI C prototype to weed out non-ANSI compilers. +# +cat>dummy.c< + +If command line options are required for ANSI C compilation, set the +ENVOPTS parameter to these options in a similar way (either through +an environment variable or config.local/config.site) and then rerun +this script. +EOF + boom +fi +Note "Using $CCOMPILER for a C compiler (use -with-CC=compilername to override)." + +test "$ENVOPTS" && { + Note "Using $ENVOPTS to get the appropriate compilation environment." +} + +if [ ${ISGCC} = yes ] ; then + GCCversion="`${CCOMPILER} -v 2>&1 | \ + sed -n -e '/version/s/.* \([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\1.\2.\3/p'`" +fi + + +CheckForGandO() +{ + f=$1 + if test -s $f; then + capture grep -i \(error\|warning\) $f || return 1 + fi + return 0 +} + +if [ -z "${GCOPTS-}" ]; then + if capture $CCOMPILER $ENVOPTS -g -c dummy.c; then + Note "Looks like $CCOMPILER supports the -g option." + # NB: cannot use captureX here 'cuz we lose stderr + if $CCOMPILER $ENVOPTS -c -g -O dummy.c >t 2>&1 && CheckForGandO t; then + GCOPTS="-g" + else + Note "... but not together with the -O option, not using it." + GCOPTS= + fi + else + GCOPTS= + fi +fi +if [ ! -z "${GCOPTS}" ]; then + Note "Using \"$GCOPTS\" for C compiler options." +fi + +# +# Verify that $MAKE is accessible +# +PATHMAKE=`findApp ${MAKE} $PATH` +if [ "$PATHMAKE" ]; then + Note "Using $PATHMAKE to configure the software." + (echo 'all:') | ${MAKE} -f - all >/dev/null 2>&5 || { + cat< /dev/null ; then + SETMAKE= + else + Note "Looks like $MAKE does not setup MAKE in Makefiles, will compensate." + SETMAKE="MAKE = ${MAKE}" + fi +fi + +test -z "${AR-}" && AR=`findApp ar $PATH` +if [ -z "$AR" ]; then + Note "*** Warning, could not locate a suitable ar command; using a default." + AR=ar +fi +test -z "${AROPTS-}" && AROPTS=rc +test -z "${RANLIB-}" && RANLIB=`findApp ranlib $PATH` +if [ -z "$RANLIB" ]; then + Note "Warning, no ranlib, assuming it's not needed." + RANLIB=":" + $RM dummy.a + if $AR rcs dummy.a >/dev/null 2>&1; then + AROPTS=crs + Note "Looks like ar has an s option to build symbol tables." + fi +fi + +# +# runMake target rules ... +# +runMakeX() +{ + target="$1"; shift + $RM $target + (echo SRCDIR=. + for i in "$@"; do + echo "$i"; + done + )>confMakefile + captureX ${MAKE} -f confMakefile $target + return +} +runMake() +{ + runMakeX "$@" >&5 + return +} + +# +# Look for a library using a known (unique) function. +# +CheckForLibrary() +{ + f=$1; shift + libs="$@"; + cat>t.c<t.c + runMake t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" +} + +# +# Figure out if certain system-specific interfaces are +# supported. We craft a port.h file that has external +# declarations for missing routines that are required by +# the system and modify defs to reflect which optional +# interfaces are supported. +# + +EmitCPlusPlusPrologue() +{ + echo '/*' + echo ' * Warning, this file was automatically created by the TIFF configure script' + echo ' * VERSION: ' $VERSION + echo ' * DATE: ' $DATE + echo ' * TARGET: ' $TARGET + if [ $ISGCC = yes ]; then + echo ' * CCOMPILER: ' ${CCOMPILER}-${GCCversion} + else + echo ' * CCOMPILER: ' $CCOMPILER + fi + echo ' */' + echo "#ifndef $1" + echo "#define $1 1" + echo '#ifdef __cplusplus' + echo 'extern "C" {' + echo '#endif' +} + +EmitCPlusPlusEpilogue() +{ + echo '#ifdef __cplusplus' + echo '}' + echo '#endif' + echo '#endif' +} + +# +# Look for a function in one of the standard libraries +# or one of the machine-dependent libraries selected above. +# +CheckForFunc() +{ + echo "extern int $1(); main(){$1();exit(0);}" >t.c + runMake t "t:; ${CCOMPILER} ${ENVOPTS} t.c ${MACHDEPLIBS}" +} + +# +# Look for a function declaration in system include files. +# +AddFuncDecl() +{ + echo "$2"; + Note "... add function prototype for $1" +} +CheckForFuncDecl() +{ + f=$1; shift + (for i do + echo "#include \"$i\"" + done)>t.c + capture cat t.c + runMakeX t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" |\ + awk '{while($0~/[,(][ \t]*$/){printf"%s",$0;getline}print}' |\ + grep "$f[ ]*(.*)" >&5 + return +} +CheckFuncDecl() +{ + f=$1; shift + decl=$1; shift + CheckForFuncDecl "$f" "$@" || AddFuncDecl "$f" "$decl" +} + +# +# Look for a variable declaration in system include files. +# +CheckForVarDecl() +{ + v="$1"; shift + (for i do + echo "#include \"$i\"" + done)>t.c + capture cat t.c + runMakeX t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" | grep "$v" >&5 + return +} +CheckVarDecl() +{ + v="$1"; shift + decl="$1"; shift + CheckForVarDecl "$v" "$@" || \ + (echo "$decl"; Note "... add declaration $decl") +} + +# +# Look for a #define in system include files. +# +AddDefine() +{ + echo '#ifndef' $1 + echo '#define' "$2" + echo '#endif' + Note '... add #define for' "$1" +} +CheckForDefine() +{ + def=$1; shift + (for i do + echo "#include \"$i\"" + done + echo "#ifdef $def" + echo "FOUND();" + echo "#endif" + )>t.c + capture cat t.c + runMakeX t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" | grep FOUND >&5 +} +CheckDefine() +{ + def=$1; shift + decl=$1; shift + CheckForDefine "$def" "$@" || AddDefine "$def" "$decl" +} + +CheckForMMAP() +{ + if CheckForFunc getpagesize; then + cat>t.c<<'EOF' +/* this was lifted from GNU autoconf */ +/* Thanks to Mike Haertel and Jim Avera for this test. */ +#include +#include +#include +EOF + else + cat>t.c<<'EOF' +/* this was lifted from GNU autoconf */ +/* Thanks to Mike Haertel and Jim Avera for this test. */ +#include +#include +#include + +#ifdef BSD +# ifndef BSD4_1 +# define HAVE_GETPAGESIZE +# endif +#endif + +#ifndef HAVE_GETPAGESIZE +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif +# else +# ifdef NBPC +# define getpagesize() NBPC +# else +# define getpagesize() PAGESIZE /* SVR4 */ +# endif +# endif +# endif +#endif +EOF + fi +cat>>t.c<<'EOF' +#if defined(__osf__) || defined(_AIX) +# define valloc malloc +#endif +char *valloc(), *malloc(); + +int +main() +{ + char *buf1, *buf2, *buf3; + int i = getpagesize(), j; + int i2 = getpagesize()*2; + int fd; + + buf1 = (char *)valloc(i2); + buf2 = (char *)valloc(i); + buf3 = (char *)malloc(i2); + for (j = 0; j < i2; ++j) + *(buf1 + j) = rand(); + fd = open("conftestmmap", O_CREAT | O_RDWR, 0666); + write(fd, buf1, i2); + mmap(buf2, i, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, 0); + for (j = 0; j < i; ++j) + if (*(buf1 + j) != *(buf2 + j)) + exit(1); + lseek(fd, (long)i, 0); + read(fd, buf2, i); /* read into mapped memory -- file should not change */ + /* (it does in i386 SVR4.0 - Jim Avera, jima@netcom.com) */ + lseek(fd, (long)0, 0); + read(fd, buf3, i2); + for (j = 0; j < i2; ++j) + if (*(buf1 + j) != *(buf3 + j)) + exit(1); + exit(0); +} +EOF + capture cat t.c + runMake t "t:; ${CCOMPILER} ${ENVOPTS} t.c ${MACHDEPLIBS}" && ./a.out +} + +CheckForBigEndian() +{ + echo 'main() { int one = 1; char* cp = (char*)&one; exit(*cp!=0); }'>t.c + capture cat t.c + runMake t "t:; ${CCOMPILER} ${ENVOPTS} t.c" && ./a.out +} + +# +# Check an existing port.h to see if it was created +# for the target and compiler we are using. +# +CheckPortDotH() +{ + getConfigTag() + { + param=`grep "$1:" $2 | sed -e 's/.*:[ ]*\([^ ]*\).*/\1/'` + } + getConfigTag TARGET $PORTDOTH; target="$param" + getConfigTag CCOMPILER $PORTDOTH; ccompiler="$param" + CCOMP=$CCOMPILER + if [ $ISGCC = yes ]; then + CCOMP="${CCOMP}-${GCCversion}" + fi + test "$target" = "$TARGET" && test "$ccompiler" = "$CCOMP" +} + +# +# Built port.h based on the system and compiler setup. +# +BuildPortDotH() +{ + Note "" + Note "Creating $PORTDOTH with necessary definitions." + + (EmitCPlusPlusPrologue _PORT_ + + CheckForIncludeFile sys/types.h && echo '#include ' + CheckVarDecl off_t 'typedef long off_t;' sys/types.h stdlib.h + CheckVarDecl size_t 'typedef unsigned size_t;' sys/types.h stdlib.h + CheckVarDecl u_char 'typedef unsigned char u_char;' sys/types.h + CheckVarDecl u_short 'typedef unsigned short u_short;' sys/types.h + CheckVarDecl u_int 'typedef unsigned int u_int;' sys/types.h + CheckVarDecl u_long 'typedef unsigned long u_long;' sys/types.h + + echo "#define HOST_FILLORDER FILLORDER_${FILLORDER}" + CPU=`echo $TARGET | sed 's/-.*//'` + Note "... using $FILLORDER bit order for your $CPU cpu" + if CheckForBigEndian; then + echo "#define HOST_BIGENDIAN 1" + Note "... using big-endian byte order for your $CPU cpu" + else + echo "#define HOST_BIGENDIAN 0" + Note "... using little-endian byte order for your $CPU cpu" + fi + + CheckForMMAP && { + echo '#define HAVE_MMAP 1' + Note "... configure use of mmap for memory-mapped files" + CheckFuncDecl mmap \ + 'extern void* mmap(void*, size_t, int, int, int, off_t);' sys/mman.h + } + + CheckForIncludeFile stdio.h && echo '#include ' + CheckForIncludeFile unistd.h && echo '#include ' + CheckForIncludeFile string.h && echo '#include ' + CheckForIncludeFile stdlib.h && echo '#include ' + if CheckForDefine O_RDONLY fcntl.h; then + echo '#include ' + Note "... O_RDONLY is in " + elif CheckForDefine O_RDONLY sys/file.h; then + echo '#include ' + Note "... O_RDONLY is in " + else + AddDefine O_RDONLY "O_RDONLY 0" + AddDefine O_WRONLY "O_WRONLY 1" + AddDefine O_RDWR "O_RDWR 2" + fi + + echo 'typedef double dblparam_t;' + Note "... using double for promoted floating point parameters" + + if [ -z "${INLINE-}" ]; then + if [ $ISGCC = yes ]; then + echo '#ifdef __STRICT_ANSI__' + echo '#define INLINE __inline__' + echo '#else' + echo '#define INLINE inline' + echo '#endif' + Note "... enabling use of inline functions" + else + echo '#define INLINE' + Note "... disabling use of inline functions" + fi + else + echo "#define INLINE $INLINE" + Note "... using \"$INLINE\" to control inline function usage" + fi + + echo '#define GLOBALDATA(TYPE,NAME) extern TYPE NAME' + + CheckFuncDecl memset 'extern void* memset(void*, int, size_t);' string.h + CheckFuncDecl floor 'extern double floor(double);' math.h + CheckFuncDecl ceil 'extern double ceil(double);' math.h + CheckFuncDecl exp 'extern double exp(double);' math.h + CheckFuncDecl pow 'extern double pow(double, double);' math.h + CheckFuncDecl read 'extern int read(int, const void*, unsigned int);' unistd.h + CheckFuncDecl malloc 'extern void* malloc(size_t);' stdlib.h + CheckFuncDecl realloc 'extern void* realloc(void*, size_t);' stdlib.h + CheckFuncDecl free 'extern void free(void*);' stdlib.h + EmitCPlusPlusEpilogue + )>xport.h + if [ $SRCDIR_IS_LIBTIFF = no -a ! -d libtiff ]; then + Note "Creating libtiff directory" + mkdir libtiff + fi + mv xport.h $PORTDOTH; chmod 444 $PORTDOTH + Note "Done creating $PORTDOTH." +} + +if [ "$PORT" != no ] && test -f $PORTDOTH && CheckPortDotH; then + Note "" + Note "Using previously created $PORTDOTH." +else + $RM xport.h t.c a.out $PORTDOTH + BuildPortDotH +fi + +if [ "$PORT" = auto ]; then + Note "" + Note "Checking system libraries for functionality to emulate." + + FUNCS=" + strcasecmp + strtoul + getopt + " + + for i in $FUNCS; do + CheckForFunc $i || { + Note "... emulate $i" + PORTFUNCS="${PORTFUNCS-} $i.c" + } + done + if [ "${PORTFUNCS-}" ]; then + LIBPORT='../port/libport.a' + PORT=yes + else + PORT=no + fi +fi +if [ $PORT != yes ] ; then + LIBPORT= + PORTFUNCS= +fi +Note "Done checking system libraries." + +Note "" +Note "Checking for Dynamic Shared Object (DSO) support." +if [ "$DSO" = auto ]; then + DSO=no + DSOSUF_VERSION= + DSOLD='${LD}' + TIFFLIBREF= + case $TARGET-$CC-$ISGCC in + *-irix5.2*) + if (findApp rld /lib:/usr/lib:$PATH) >/dev/null 2>&1; then + DSOSUF=so + DSOOPTS='-elf -shared -no_unresolved -all' + DSO=IRIX52 + TIFFLIBREF='-L${DEPTH}/libtiff -rpath '${DIR_LIB}' -ltiff' + fi + ;; + *-irix*) + if (findApp rld /lib:/usr/lib:$PATH) >/dev/null 2>&1; then + DSOSUF=so + DSOLD="${CCOMPILER} ${ENVOPTS}" + DSOOPTS='-shared -rdata_shared -check_registry ${SRCDIR}/port/irix/so_locations -quickstart_info' + DSO=IRIX + TIFFLIBREF='-L${DEPTH}/libtiff -rpath '${DIR_LIB}' -ltiff' + fi + ;; + *-aix*) + DSOSUF=a + DSOOPTS='-r' + LIBCOPTS="-bM\:SRE" + DSO=AIX + ;; + *-hpux*yes) + DSOSUF=sl + DSOLD=gcc + DSOOPTS='-fpic -shared' + LIBCOPTS=-fpic + DSO=HPUX + TIFFLIBREF="-Wl,+s,+b${DIR_LIB}"' -L${DEPTH}/libtiff -ltiff' + ;; + *-hpux*) + DSOSUF=sl + DSOOPTS='-b' + LIBCOPTS="+Z" + DSO=HPUX + TIFFLIBREF="-Wl,+s,+b${DIR_LIB}"' -L${DEPTH}/libtiff -ltiff' + ;; + *-solaris*) + DSOSUF=so + DSOOPTS='-G' + if [ $ISGCC = yes ]; then + LIBCOPTS="-fpic" + else + LIBCOPTS="-K PIC" + fi + DSO=SOLARIS + TIFFLIBREF='-L${DEPTH}/libtiff -R'${DIR_LIB}' -ltiff' + ;; + *-netbsd*) + DSOSUF=so.${DIST_MAJOR}.0 + LIBCOPTS='-fPIC' + DSO=NETBSD + TIFFLIBREF='-L${DEPTH}/libtiff -ltiff' + ;; + *-freebsd*) + DSOSUF=so.${DIST_MAJOR}.0 + LIBCOPTS='-fpic -fPIC' + DSO=FREEBSD + TIFFLIBREF='-L${DEPTH}/libtiff -ltiff' + ;; + *-linux*) + if [ -r /lib/libc.so.5 ]; then + DSOSUF=so.${DIST_MAJOR} + DSOSUF_VERSION=${DSOSUF}.${DIST_MINOR}.${DIST_ALPHA} + LIBCOPTS='-fPIC' + DSOOPTS='-shared' + DSO=LINUX + fi + ;; + *-osf3*) + DSOSUF=so + DSOOPTS='-shared' + DSO=OSF + ;; + esac +fi +if [ "$DSO" != no ]; then + JUNK="$JUNK t.${DSOSUF}" + # + # Check to make sure the compilers process + # the DSO options in the expected way. + # + CheckCCDSO() + { + $RM t.c t.o t.${DSOSUF} + cat>t.c<&4 <t.c + if mv -f t.c t.o; then + Note "Looks like mv supports the -f option to force a move." + MV_F=-f + else + Note "Warning, looks like mv has no -f option to force move operations;" + Note "... this may cause problems during installation." + MV_F= + fi +fi + +# +# Check if ln -s creates a symbolic link. +# +if [ -z "${LN_S-}" ]; then + $RM t.c; $LN -s foo t.c && LN_S=-s +fi +if [ -n "$LN_S" ]; then + Note "Looks like $LN supports the -s option to create a symbolic link." +else + Note "Warning, looks like $LN has no -s option to create symbolic links;" + Note "... this may cause problems during installation." +fi + +# +# Pick install mechanism. +# +if [ -z "${INSTALL-}" ]; then + case $TARGET in + *-irix*) INSTALL=`findApp install /sbin:$PATH`;; + *) INSTALL='${SHELL} ../port/install.sh';; + esac +fi + +Note "Done selecting programs." + +# +# User-changable configuration parameters section. +# Anything selected here is presented to the user +# and may be interactively changed. +# + +Note "" +Note "Selecting default TIFF configuration parameters." +Note "" + +# +# Fill in any other configuration parameters not +# setup in the site and local files. +# + +bitchExecutable() +{ + echo "" + echo "Warning, $1 does not seem to be an executable program;" + echo "you'll need to correct this before starting up the fax server." + echo "" +} + +# +# Setup manual page-related stuff. +# +# Manual pages are processed according to: +# 1. Section organization (BSD or System V) +# 2. Pre-formatted (w/ nroff) or source. +# 3. Compressed (compress, gzip, pack) or uncompressed. +# 4. Whether or not the FlexFAX ``F'' suffix must be +# stripped for pages to be found (only for 4F pages). +# +if [ -z "${DIR_MAN-}" ]; then + MANPATH=" + $MANPATH + /usr/local/man + /usr/contrib/man + /usr/catman/local + " + DIR_MAN= + for i in $MANPATH; do + test -d $i && { DIR_MAN=$i; break; } + done + test -z "$DIR_MAN" && DIR_MAN=/usr/local/man +fi +Note "Looks like manual pages go in $DIR_MAN." +if [ -z "${MANSCHEME-}" ]; then + case $TARGET in + *-bsdi*|*-netbsd*) MANSCHEME=bsd-nroff-gzip-0.gz;; + *-freebsd*) MANSCHEME=bsd-source-cat;; + *-linux*) MANSCHEME=bsd-source-cat;; + *-ultrix*) MANSCHEME=bsd-source-cat;; + *-sunos*) MANSCHEME=bsd-source-cat-strip;; + *-sysv[234]*) MANSCHEME=sysv-source-cat-strip;; + *-hpux*) MANSCHEME=sysv-source-cat-strip;; + *-solaris*) MANSCHEME=sysv-source-cat-strip;; + *-aix*) MANSCHEME=sysv-source-strip;; + *-isc*|*-sco*) MANSCHEME=sysv-source-cat;; + *-irix*) MANSCHEME=sysv-nroff-compress-Z;; + *) + # + # Try to deduce the setup from existing manual pages. + # XXX needs more work XXX + # + MANSCHEME=sysv-source-cat + if [ -d /usr/share/man ]; then + if [ -d /usr/share/man/u_man ]; then + MANSCHEME=sysv-source-cat + elif [ -d /usr/share/man/man8 ]; then + MANSCHEME=bsd-source-cat + fi + elif [ -d /usr/share/catman ]; then + if [ -d /usr/share/catman/u_man ]; then + MANSCHEME=sysv-nroff-cat + elif [ -d /usr/share/catman/man8 ]; then + MANSCHEME=bsd-nroff-cat + fi + fi + ;; + esac +fi +Note "Looks like manual pages should be installed with $MANSCHEME." + +# +# Figure out which brand of echo we have and define +# prompt and print shell functions accordingly. +# +if [ `echo foo\\\c`@ = "foo@" ]; then + prompt() + { + echo "$* \\c" + } +elif [ "`echo -n foo`@" = "foo@" ]; then + prompt() + { + echo -n "$* " + } +else + prompt() + { + echo "$*" + } +fi + +# +# Prompt the user for a string that can not be null. +# +promptForNonNullStringParameter() +{ + x="" val="$1" desc="$2" + while [ -z "$x" ]; do + prompt "$desc [$val]?"; read x + if [ "$x" ]; then + # strip leading and trailing white space + x=`echo "$x" | sed -e 's/^[ ]*//' -e 's/[ ]*$//'` + else + x="$val" + fi + done + param="$x" +} + +promptForManPageScheme() +{ + x="" + while [ -z "$x" ]; do + prompt "Manual page installation scheme [$MANSCHEME]?"; read x + if [ "$x" ]; then + # strip leading and trailing white space + x=`echo "$x" | sed -e 's/^[ ]*//' -e 's/[ ]*$//'` + # XXX do a better job of validating... + case "$x" in + bsd-nroff-cat*|sysv-nroff-cat*) ;; + bsd-nroff-gzip*|sysv-nroff-gzip*) ;; + bsd-nroff-comp*|sysv-nroff-comp*) ;; + bsd-nroff-pack*|sysv-nroff-pack*) ;; + bsd-source-cat*|sysv-source-cat*) ;; + bsd-source-gzip*|sysv-source-gzip*) ;; + bsd-source-comp*|sysv-source-comp*) ;; + bsd-source-pack*|sysv-source-pack*) ;; + *) +cat <--[-] + +where: + + is either "bsd" for BSD-style section organization (e.g. + file formats in section 5) or "sysv" for System V-style + organization (e.g. file formats in section 4). + + is either "nroff" to force installation of formatted + materials (using nroff) or "source" to get the nroff + source installed. + + is either the name of a program to compress the manual + pages (gipz, compress, pack) or "cat" for uncompressed data. + + is either the file suffix to convert installed pages to + (e.g. 0.gz for gzip-compressed pages under BSD) or "strip" + to force the normal ".4f" suffix to be converted to ".4" + (or ".5" if using the BSD organization). If no - + is specified then filenames are not converted when they + are installed. + +Common schemes are: + +bsd-nroff-gzip-0.gz compressed formatted pages for BSD +bsd-source-cat nroff source w/ BSD organization +sysv-source-cat-strip nroff source for SysV w/o .4f suffix +sysv-source-cat nroff source for SysV as-is + +EOF + x="";; + esac + else + x="$MANSCHEME" + fi + done + MANSCHEME="$x" +} + +printConfig() +{ + cat< accepts the displayed parameters." + echo "A number lets you change the numbered parameter." + echo "" + ;; + esac + ok=skip + done + checkJPEG + checkZIP +else + checkJPEG + checkZIP +fi + +case $MANSCHEME in +*-source-*) MANAPPS=man1 MANLIB=man3;; +*-nroff-*) MANAPPS=cat1 MANLIB=cat3;; +esac +case $MANSCHEME in +*-strip) MANSEDLOCAL="-e s/3T/3/g";; +*) MANSEDLOCAL="";; +esac +case $MANSCHEME in +*-source-*) MANCVT='${MANSED} $? >$@';; +*-nroff-gzip-*) MANCVT='${MANSED} $? | nroff -man | gzip > $@';; +*-nroff-pack-*) MANCVT='${MANSED} $? | nroff -man | pack > $@';; +*-nroff-com*-*) MANCVT='${MANSED} $? | nroff -man | compress > $@';; +*-nroff-cat-*) MANCVT='${MANSED} $? | nroff -man > $@';; +esac +case $MANSCHEME in +*-0|*-0.gz|*-0.Z|*-gz|*-Z|*-z) + suf=`echo $MANSCHEME | sed 's/.*-/./'` + A='`echo $$i | sed' B='`' # workaround shell bugs + MANAPPNAME="$A s/\\\\.1\$\$/$suf/$B" + MANLIBNAME="$A s/\\\\.3t\$\$/$suf/$B" + ;; +*-strip) + MANAPPNAME='$$i' + MANLIBNAME='`echo $$i | sed s/\\.3t$$/.3/`' + ;; +*) + MANAPPNAME='$$i' MANLIBNAME='$$i' + ;; +esac + +if [ "${JPEG}" = yes ]; then + test -z "${CONF_JPEG-}" && CONF_JPEG="-DJPEG_SUPPORT" + if test -z "${LIBJPEG-}" ; then + LIBJPEG="-ljpeg" + test -z "${DIR_JPEGLIB-}" || LIBJPEG="-L${DIR_JPEGLIB} ${LIBJPEG}" + fi +else + CONF_JPEG= + LIBJPEG= +fi +if [ "${ZIP}" = yes ]; then + test -z "${CONF_ZIP-}" && CONF_ZIP="-DZIP_SUPPORT" + if test -z "${LIBGZ-}" ; then + LIBGZ="-lz" + test -z "${DIR_GZLIB-}" || LIBGZ="-L${DIR_GZLIB} ${LIBGZ}" + fi +else + CONF_ZIP= + LIBGZ= +fi + +Note "" + +# +# Fixup a list of potentially relative pathnames so +# that they work when used in a subdirectory. The +# string sent to stdout has no extraneous spaces so +# it can be used, for example, in building pathnames. +# +# NB: There's an extra echo done here so we get a +# \n-terminated string passed to sed. +# +relativize() +{ + echo `if [ $SRCDIR_IS_LIBTIFF = no ]; then + (for i do + case "$i" in + /*|-l*) echo "$i" ;; + -[LR]) ;; # XXX??? + -[LR]/*) echo "$i" ;; + -L*) echo "$i" | sed 's;^-L;-L../;' ;; + -R*) echo "$i" | sed 's;^-R;-R../;' ;; + *) echo "../$i" ;; + esac + done) | tr '\012' ' ' + else + echo "$@" + fi` | sed -e 's;[ ][ ]*$;;' -e 's;/[.]$;;' +} +# +# Generate a list of compiler include options, +# prepending ``../'' to any relative pathnames. +# +makeIncArgs() +{ + (for i do + case "$i" in + /*) echo "-I$i" ;; + *) + if [ $SRCDIR_IS_LIBTIFF = yes ]; then + echo "-I$i" + else + echo "-I../$i" + fi ;; + esac + done) | tr '\012' ' ' +} + +# +# Setup parameters needed below. +# +if [ $SRCDIR_IS_LIBTIFF = yes ]; then + CONFIGDIR="." + LIBSRCDIR="${SRCDIR}" +else + CONFIGDIR=".." + LIBSRCDIR=`relativize ${SRCDIR}`/libtiff +fi + +# NB: these should be sorted alphabetically +cat>>confsed< $F.new + $RM confx; $SED '/DATE:/d' $F.new >confx + $RM confy; $SED '/DATE:/d' $F >confy 2>/dev/null + if cmp -s confx confy >/dev/null 2>&1; then + $RM $F.new + else + Note "Creating $F from $SRCDIR/$F.in" + $RM $F; mv $F.new $F; $CHMOD 444 $F + fi + else + Note "Creating $F from $SRCDIR/$F.in" + if $SED -f confsed $SRCDIR/$F.in >$F.new; then + $RM $F; mv $F.new $F; $CHMOD 444 $F + else + cat 1>&2 <$F.new + +failed. Aborting without cleaning up files so you can take a look... +EOF + exit 1 + fi + fi + done +} + +# +# port/install.sh is the SGI install program emulator script. +# +CONF_FILES="Makefile" +if [ $SRCDIR_IS_LIBTIFF != yes ] ; then + CONF_FILES="$CONF_FILES + libtiff/Makefile + man/Makefile + tools/Makefile + port/install.sh + " + test $HTML = yes && CONF_FILES="$CONF_FILES html/Makefile" + test $PORT = yes && CONF_FILES="$CONF_FILES port/Makefile" +fi +SedConfigFiles $CONF_FILES + +Note "Done." + +$RM $JUNK +exit 0 diff --git a/contrib/acorn/Makefile b/contrib/acorn/Makefile new file mode 100644 index 00000000..8f014778 --- /dev/null +++ b/contrib/acorn/Makefile @@ -0,0 +1,165 @@ +# Project: LibTIFF + + +# Toolflags: +CCflags = -c -zo -ffah -depend !Depend -IC: +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +DrLinkflags = -nounused -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -o $@ +Squeezeflags = -o $@ + + +# Final targets: +@.o.LIBTIFF: \ + @.o.tif_acorn \ + @.o.tif_aux \ + @.o.tif_close \ + @.o.tif_codec \ + @.o.tif_compress \ + @.o.tif_dir \ + @.o.tif_dirinfo \ + @.o.tif_dirread \ + @.o.tif_dirwrite \ + @.o.tif_dumpmode \ + @.o.tif_error \ + @.o.tif_fax3 \ + @.o.tif_flush \ + @.o.tif_getimage \ + @.o.tif_jpeg \ + @.o.tif_lzw \ + @.o.tif_next \ + @.o.tif_open \ + @.o.tif_packbits \ + @.o.tif_predict \ + @.o.tif_print \ + @.o.tif_read \ + @.o.tif_strip \ + @.o.tif_swab \ + @.o.tif_thunder \ + @.o.tif_tile \ + @.o.tif_version \ + @.o.tif_warning \ + @.o.tif_write \ + @.o.tif_zip \ + @.o.tif_fax3sm \ + @.h.version + LibFile $(LibFileflags) \ + @.o.tif_acorn \ + @.o.tif_aux \ + @.o.tif_close \ + @.o.tif_codec \ + @.o.tif_compress \ + @.o.tif_dir \ + @.o.tif_dirinfo \ + @.o.tif_dirread \ + @.o.tif_dirwrite \ + @.o.tif_dumpmode \ + @.o.tif_error \ + @.o.tif_fax3 \ + @.o.tif_flush \ + @.o.tif_getimage \ + @.o.tif_jpeg \ + @.o.tif_lzw \ + @.o.tif_next \ + @.o.tif_open \ + @.o.tif_packbits \ + @.o.tif_predict \ + @.o.tif_print \ + @.o.tif_read \ + @.o.tif_strip \ + @.o.tif_swab \ + @.o.tif_thunder \ + @.o.tif_tile \ + @.o.tif_version \ + @.o.tif_warning \ + @.o.tif_write \ + @.o.tif_zip \ + @.o.tif_fax3sm + + +# User-editable dependencies: +@.mkversion: @.o.mkversion C:o.Stubs + Link $(linkflags) @.o.mkversion C:o.Stubs +@.h.version: @.VERSION @.mkversion + .mkversion -v @.VERSION -a @.tiff/alpha @.h.version +@.mkg3states: @.o.mkg3states @.o.getopt C:o.Stubs + link $(linkflags) @.o.mkg3states C:o.Stubs @.o.getopt +@.c.tif_fax3sm: @.mkg3states + .mkg3states -c const @.c.tif_fax3sm + +# Static dependencies: +@.o.tif_acorn: @.c.tif_acorn + cc $(ccflags) -o @.o.tif_acorn @.c.tif_acorn +@.o.tif_aux: @.c.tif_aux + cc $(ccflags) -o @.o.tif_aux @.c.tif_aux +@.o.tif_close: @.c.tif_close + cc $(ccflags) -o @.o.tif_close @.c.tif_close +@.o.tif_codec: @.c.tif_codec + cc $(ccflags) -o @.o.tif_codec @.c.tif_codec +@.o.tif_compress: @.c.tif_compress + cc $(ccflags) -o @.o.tif_compress @.c.tif_compress +@.o.tif_dir: @.c.tif_dir + cc $(ccflags) -o @.o.tif_dir @.c.tif_dir +@.o.tif_dirinfo: @.c.tif_dirinfo + cc $(ccflags) -o @.o.tif_dirinfo @.c.tif_dirinfo +@.o.tif_dirread: @.c.tif_dirread + cc $(ccflags) -o @.o.tif_dirread @.c.tif_dirread +@.o.tif_dirwrite: @.c.tif_dirwrite + cc $(ccflags) -o @.o.tif_dirwrite @.c.tif_dirwrite +@.o.tif_dumpmode: @.c.tif_dumpmode + cc $(ccflags) -o @.o.tif_dumpmode @.c.tif_dumpmode +@.o.tif_error: @.c.tif_error + cc $(ccflags) -o @.o.tif_error @.c.tif_error +@.o.tif_fax3: @.c.tif_fax3 + cc $(ccflags) -o @.o.tif_fax3 @.c.tif_fax3 +@.o.tif_flush: @.c.tif_flush + cc $(ccflags) -o @.o.tif_flush @.c.tif_flush +@.o.tif_getimage: @.c.tif_getimage + cc $(ccflags) -o @.o.tif_getimage @.c.tif_getimage +@.o.tif_jpeg: @.c.tif_jpeg + cc $(ccflags) -o @.o.tif_jpeg @.c.tif_jpeg +@.o.tif_lzw: @.c.tif_lzw + cc $(ccflags) -o @.o.tif_lzw @.c.tif_lzw +@.o.tif_next: @.c.tif_next + cc $(ccflags) -o @.o.tif_next @.c.tif_next +@.o.tif_open: @.c.tif_open + cc $(ccflags) -o @.o.tif_open @.c.tif_open +@.o.tif_packbits: @.c.tif_packbits + cc $(ccflags) -o @.o.tif_packbits @.c.tif_packbits +@.o.tif_predict: @.c.tif_predict + cc $(ccflags) -o @.o.tif_predict @.c.tif_predict +@.o.tif_print: @.c.tif_print + cc $(ccflags) -o @.o.tif_print @.c.tif_print +@.o.tif_read: @.c.tif_read + cc $(ccflags) -o @.o.tif_read @.c.tif_read +@.o.tif_strip: @.c.tif_strip + cc $(ccflags) -o @.o.tif_strip @.c.tif_strip +@.o.tif_swab: @.c.tif_swab + cc $(ccflags) -o @.o.tif_swab @.c.tif_swab +@.o.tif_thunder: @.c.tif_thunder + cc $(ccflags) -o @.o.tif_thunder @.c.tif_thunder +@.o.tif_tile: @.c.tif_tile + cc $(ccflags) -o @.o.tif_tile @.c.tif_tile +@.o.tif_version: @.c.tif_version + cc $(ccflags) -o @.o.tif_version @.c.tif_version +@.o.tif_warning: @.c.tif_warning + cc $(ccflags) -o @.o.tif_warning @.c.tif_warning +@.o.tif_write: @.c.tif_write + cc $(ccflags) -o @.o.tif_write @.c.tif_write +@.o.tif_zip: @.c.tif_zip + cc $(ccflags) -o @.o.tif_zip @.c.tif_zip +@.o.mkg3states: @.c.mkg3states + cc $(ccflags) -o @.o.mkg3states @.c.mkg3states +@.o.getopt: @.c.getopt + cc $(ccflags) -o @.o.getopt @.c.getopt +@.o.mkspans: @.c.mkspans + cc $(ccflags) -o @.o.mkspans @.c.mkspans +@.o.tif_fax3sm: @.c.tif_fax3sm + cc $(ccflags) -o @.o.tif_fax3sm @.c.tif_fax3sm +@.o.mkversion: @.c.mkversion + cc $(ccflags) -o @.o.mkversion @.c.mkversion + +# Dynamic dependencies: diff --git a/contrib/acorn/ReadMe b/contrib/acorn/ReadMe new file mode 100644 index 00000000..dc16a79d --- /dev/null +++ b/contrib/acorn/ReadMe @@ -0,0 +1,79 @@ +Building the Software on an Acorn RISC OS system + +The directory contrib/acorn contains support for compiling the library under +Acorn C/C++ under Acorn's RISC OS 3.10 or above. Subsequent pathnames will +use the Acorn format: The full-stop or period character is a pathname +delimeter, and the slash character is not interpreted; the reverse position +from Unix. Thus "libtiff/tif_acorn.c" becomes "libtiff.tif_acorn/c". + +This support was contributed by Peter Greenham. +(peterg@angmulti.demon.co.uk). + +Installing LibTIFF: + +LIBTIFF uses several files which have names longer than the normal RISC OS +maximum of ten characters. This complicates matters. Maybe one day Acorn will +address the problem and implement long filenames properly. Until then this +gets messy, especially as I'm trying to do this with obeyfiles and not have +to include binaries in this distribution. + +First of all, ensure you have Truncate configured on (type *Configure +Truncate On) Although it is, of course, preferable to have long filenames, +LIBTIFF can be installed with short filenames, and it will compile and link +without problems. However, getting it there is more problematic. +contrib.acorn.install is an installation obeyfile which will create a normal +Acorn-style library from the source (ie: with c, h and o folders etc.), but +needs the distribution library to have been unpacked into a location which is +capable of supporting long filenames, even if only temporarily. + +My recommendation, until Acorn address this problem properly, is to use Jason +Tribbeck's LongFilenames , or any other working system that gives you long +filenames, like a nearby NFS server for instance. + +If you are using Longfilenames, even if only temporarily to install LIBTIFF, +unpack the TAR into a RAMDisc which has been longfilenamed (ie: *addlongfs +ram) and then install from there to the hard disk. Unfortunately +Longfilenames seems a bit unhappy about copying a bunch of long-named files +across the same filing system, but is happy going between systems. You'll +need to create a ramdisk of about 2Mb. + +Now you can run the installation script I've supplied (in contrib.acorn), +which will automate the process of installing LIBTIFF as an Acorn-style +library. The syntax is as follows: + +install + +Install will then create and put the library in there. For +example, having used LongFilenames on the RAMDisk and unpacked the library +into there, you can then type: + +Obey RAM::RamDisc0.$.contrib.acorn.install RAM::RamDisc0.$ ADFS::4.$.LIBTIFF + +It doesn't matter if the destination location can cope with long filenames or +not. The filenames will be truncated if necessary (*Configure Truncate On if +you get errors) and all will be well. + +Compiling LibTIFF: + +Once the LibTIFF folder has been created and the files put inside, making the +library should be just a matter of running 'SetVars' to set the appropriate +system variables, then running 'Makefile'. + +OSLib + +OSLib is a comprehensive API for RISC OS machines, written by Jonathan +Coxhead of Acorn Computers (although OSLib is not an official Acorn product). +Using the OSLib SWI veneers produces code which is more compact and more +efficient than code written using _kernel_swi or _swi. The Acorn port of +LibTIFF can take advantage of this if present. Edit the Makefile and go to +the Static dependencies section. The first entry is: + +# Static dependencies: +@.o.tif_acorn: @.c.tif_acorn + cc $(ccflags) -o @.o.tif_acorn @.c.tif_acorn +Change the cc line to: + + cc $(ccflags) -DINCLUDE_OSLIB -o @.o.tif_acorn @.c.tif_acorn + +Remember, however, that OSLib is only recommended for efficiency's sake. It +is not required. diff --git a/contrib/acorn/SetVars b/contrib/acorn/SetVars new file mode 100755 index 00000000..ea12d71d --- /dev/null +++ b/contrib/acorn/SetVars @@ -0,0 +1,3 @@ +Set LibTIFF$Dir +Set LibTIFF$Path . +Set C$Path ,LibTIFF: diff --git a/contrib/acorn/cleanlib b/contrib/acorn/cleanlib new file mode 100755 index 00000000..78a2d034 --- /dev/null +++ b/contrib/acorn/cleanlib @@ -0,0 +1,5 @@ +IfThere LibTIFF:o.* THEN Wipe LibTIFF:o.* ~CFR~V +IfThere LibTIFF:c.tif_fax3sm THEN Delete LibTIFF:c.tif_fax3sm +IfThere LibTIFF:mkg3states THEN Delete LibTIFF:mkg3states +IfThere LibTIFF:h.version THEN Delete LibTIFF:h.version +IfThere LibTIFF:mkversion THEN Delete LibTIFF:mkversion diff --git a/contrib/acorn/convert b/contrib/acorn/convert new file mode 100644 index 00000000..1f64ed20 --- /dev/null +++ b/contrib/acorn/convert @@ -0,0 +1,175 @@ +RISC OS Conversion log +====================== + +mkversion.c +~~~~~~~~~~~ +The RISC OS command-line does not allow the direct creation of the version.h +file in the proper manner. To remedy this in such a way that the version +header is made at compiletime, I wrote this small program. It is fully +portable, so should work quite happily for any other platform that might need +it. + +msg3states.c +~~~~~~~~~~~~ +Needed getopt.c from the port folder, then compiled and worked fine. + + +tiff.h +~~~~~~ + +====1==== + +The symbol _MIPS_SZLONG, if not defined, causes a compiler error. Fixed by +ensuring it does exist. This looks to me like this wouldn't be an +Acorn-specific problem. The new code fragment is as follows: + +#ifndef _MIPS_SZLONG +#define _MIPS_SZLONG 32 +#endif +#if defined(__alpha) || _MIPS_SZLONG == 64 + + + +tiffcomp.h +~~~~~~~~~~ + +====1==== + +#if !defined(__MWERKS__) && !defined(THINK_C) +#include +#endif + +Acorn also doesn't have this header so: + +#if !defined(__MWERKS__) && !defined(THINK_C) && !defined(__acorn) +#include +#endif + +====2==== + +#ifdef VMS +#include +#include +#else +#include +#endif + +This seems to indicate that fcntl.h is included on all systems except +VMS. Odd, because I've never heard of it before. Sure it's in the ANSI +definition? Anyway, following change: + +#ifdef VMS +#include +#include +#else +#ifndef __acorn +#include +#endif +#endif + +This will probably change when I find out what it wants from fcntl.h! + +====3==== + +#if defined(__MWERKS__) || defined(THINK_C) || defined(applec) +#include +#define BSDTYPES +#endif + +Added RISC OS to above thus: + +#if defined(__MWERKS__) || defined(THINK_C) || defined(applec) || defined(__acorn) +#include +#define BSDTYPES +#endif + +====4==== + +/* + * The library uses the ANSI C/POSIX SEEK_* + * definitions that should be defined in unistd.h + * (except on VMS where they are in stdio.h and + * there is no unistd.h). + */ +#ifndef SEEK_SET +#if !defined(VMS) && !defined (applec) && !defined(THINK_C) && !defined(__MWERKS__) +#include +#endif + +RISC OS is like VMS and Mac in this regard. So changed to: + +/* + * The library uses the ANSI C/POSIX SEEK_* + * definitions that should be defined in unistd.h + * (except on VMS or the Mac or RISC OS, where they are in stdio.h and + * there is no unistd.h). + */ +#ifndef SEEK_SET +#if !defined(VMS) && !defined (applec) && !defined(THINK_C) && !defined(__MWERKS__) && !defined(__acorn) +#include +#endif +#endif + +====5==== + +NB: HAVE_IEEEFP is defined in tiffconf.h, not tiffcomp.h as mentioned +in libtiff.README. (Note written on original port from 3.4beta004) + +Acorn C/C++ claims to accord with IEEE 754, so no change (yet) to +tiffconf.h. + +====6==== + +Unsure about whether this compiler supports inline functions. Will +leave it on for the time being and see if it works! (Likely if +everything else does.) + +... Seems to be OK ... + +====7==== + +Added to the end: + +/* + * osfcn.h is part of C++Lib on Acorn C/C++, and as such can't be used + * on C alone. For that reason, the relevant functions have been + * implemented by myself in tif_acorn.c, and the elements from the header + * included here. + */ + +#ifdef __acorn +#ifdef __cplusplus +#include +#else +#include "kernel.h" +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define O_APPEND 8 +#define O_CREAT 0x200 +#define O_TRUNC 0x400 +typedef long off_t; +extern int open(const char *name, int flags, int mode); +extern int close(int fd); +extern int write(int fd, const char *buf, int nbytes); +extern int read(int fd, char *buf, int nbytes); +extern off_t lseek(int fd, off_t offset, int whence); +#endif +#endif + + +=============================================================================== + +tif_acorn.c +~~~~~~~~~~~ + +Created file tif_acorn.c, copied initially from tif_unix.c + +Documented internally where necessary. + +Note that I have implemented the low-level file-handling functions normally +found in osfcn.h in here, and put the header info at the bottom of +tiffcomp.h. This is further documented from a RISC OS perspective inside the +file. + +=============================================================================== diff --git a/contrib/acorn/install b/contrib/acorn/install new file mode 100755 index 00000000..fa49d1ba --- /dev/null +++ b/contrib/acorn/install @@ -0,0 +1,128 @@ +If "%0" = "" Then Error Syntax: install | | +If "%1" = "" Then Error Syntax: install | | +Set LibTiffInstall$Dir %0 +Set LibTiff$Dir %1 +Set Alias$CPY Copy .%%0 .%%1 ~C~DF~NRV +CDir +CDir .c +CDir .h +CDir .o +CPY COPYRIGHT COPYRIGHT +CPY README README +CPY VERSION VERSION +CPY dist.tiff/alpha tiff/alpha +CPY contrib.acorn.SetVars SetVars +CPY contrib.acorn.Makefile Makefile +CPY contrib.acorn.cleanlib cleanlib +CPY port.getopt/c c.getopt +CPY libtiff.mkg3states/c c.mkg3states +CPY libtiff.mkspans/c c.mkspans +CPY libtiff.mkversion/c c.mkversion +CPY libtiff.tif_acorn/c c.tif_acorn +CPY libtiff.tif_aux/c c.tif_aux +CPY libtiff.tif_close/c c.tif_close +CPY libtiff.tif_codec/c c.tif_codec +CPY libtiff.tif_compress/c c.tif_compre +CPY libtiff.tif_dir/c c.tif_dir +CPY libtiff.tif_dirinfo/c c.tif_dirinf +CPY libtiff.tif_dirread/c c.tif_dirrea +CPY libtiff.tif_dirwrite/c c.tif_dirwri +CPY libtiff.tif_dumpmode/c c.tif_dumpmo +CPY libtiff.tif_error/c c.tif_error +CPY libtiff.tif_fax3/c c.tif_fax3 +CPY libtiff.tif_flush/c c.tif_flush +CPY libtiff.tif_getimage/c c.tif_getima +CPY libtiff.tif_jpeg/c c.tif_jpeg +CPY libtiff.tif_lzw/c c.tif_lzw +CPY libtiff.tif_next/c c.tif_next +CPY libtiff.tif_open/c c.tif_open +CPY libtiff.tif_packbits/c c.tif_packbi +CPY libtiff.tif_predict/c c.tif_predic +CPY libtiff.tif_print/c c.tif_print +CPY libtiff.tif_read/c c.tif_read +CPY libtiff.tif_strip/c c.tif_strip +CPY libtiff.tif_swab/c c.tif_swab +CPY libtiff.tif_thunder/c c.tif_thunde +CPY libtiff.tif_tile/c c.tif_tile +CPY libtiff.tif_version/c c.tif_versio +CPY libtiff.tif_warning/c c.tif_warnin +CPY libtiff.tif_write/c c.tif_write +CPY libtiff.tif_zip/c c.tif_zip +CPY libtiff.t4/h h.t4 +CPY libtiff.tiff/h h.tiff +CPY libtiff.tiffcomp/h h.tiffcomp +CPY libtiff.tiffconf/h h.tiffconf +CPY libtiff.tiffio/h h.tiffio +CPY libtiff.tiffiop/h h.tiffiop +CPY libtiff.tif_dir/h h.tif_dir +CPY libtiff.tif_fax3/h h.tif_fax3 +CPY libtiff.tif_predict/h h.tif_predic +SetType .COPYRIGHT Text +SetType .README Text +SetType .VERSION Text +SetType .tiff/alpha Text +SetType .SetVars Obey +SetType .Makefile fe1 +SetType .cleanlib Obey +SetType .c.getopt Text +SetType .c.mkg3states Text +SetType .c.mkspans Text +SetType .c.mkversion Text +SetType .c.tif_acorn Text +SetType .c.tif_aux Text +SetType .c.tif_close Text +SetType .c.tif_codec Text +SetType .c.tif_compre Text +SetType .c.tif_dir Text +SetType .c.tif_dirinf Text +SetType .c.tif_dirrea Text +SetType .c.tif_dirwri Text +SetType .c.tif_dumpmo Text +SetType .c.tif_error Text +SetType .c.tif_fax3 Text +SetType .c.tif_flush Text +SetType .c.tif_getima Text +SetType .c.tif_jpeg Text +SetType .c.tif_lzw Text +SetType .c.tif_next Text +SetType .c.tif_open Text +SetType .c.tif_packbi Text +SetType .c.tif_predic Text +SetType .c.tif_print Text +SetType .c.tif_read Text +SetType .c.tif_strip Text +SetType .c.tif_swab Text +SetType .c.tif_thunde Text +SetType .c.tif_tile Text +SetType .c.tif_versio Text +SetType .c.tif_warnin Text +SetType .c.tif_write Text +SetType .c.tif_zip Text +SetType .h.t4 Text +SetType .h.tiff Text +SetType .h.tiffcomp Text +SetType .h.tiffconf Text +SetType .h.tiffio Text +SetType .h.tiffiop Text +SetType .h.tif_dir Text +SetType .h.tif_fax3 Text +SetType .h.tif_predic Text +Unset Alias$CPY +Unset LibTiffInstall$Dir +| Now attempt to restore longfilename status. If it causes an error, OK. +Set Alias$RN Rename .%%0 .%%1 +Unset LibTiff$Dir +RN c.tif_compre c.tif_compress +RN c.tif_dirinf c.tif_dirinfo +RN c.tif_dirrea c.tif_dirread +RN c.tif_dirwri c.tif_dirwrite +RN c.tif_dumpmo c.tif_dumpmode +RN c.tif_getima c.tif_getimage +RN c.tif_packbi c.tif_packbits +RN c.tif_predic c.tif_predict +RN c.tif_thunde c.tif_thunder +RN c.tif_versio c.tif_version +RN c.tif_warnin c.tif_warning +RN h.tif_predic h.tif_predict +Unset Alias$RN +Echo All done! diff --git a/contrib/dbs/Imakefile b/contrib/dbs/Imakefile new file mode 100644 index 00000000..e9e22667 --- /dev/null +++ b/contrib/dbs/Imakefile @@ -0,0 +1,12 @@ +# +# Imakefile -- to generate a Makefile, do xmkmf +# + TIFF = ../../libtiff + EXTRA_LIBRARIES = $(TIFF)/libtiff.a + EXTRA_INCLUDES = -I$(TIFF) + +AllTarget(bi gray pal rgb) +NormalProgramTarget(bi,tiff-bi.o,,,) +NormalProgramTarget(gray,tiff-grayscale.o,,,-lm) +NormalProgramTarget(pal,tiff-palette.o,,,) +NormalProgramTarget(rgb,tiff-rgb.o,,,-lm) diff --git a/contrib/dbs/README b/contrib/dbs/README new file mode 100644 index 00000000..e05d0a95 --- /dev/null +++ b/contrib/dbs/README @@ -0,0 +1,7 @@ +Wed May 9 09:11:35 PDT 1990 + +This directory contains programs from Dan Sears +(dbs@decwrl.dec.com). Contact him directly if +you have questions/problems. + + Sam diff --git a/contrib/dbs/tiff-bi.c b/contrib/dbs/tiff-bi.c new file mode 100644 index 00000000..584fdfd6 --- /dev/null +++ b/contrib/dbs/tiff-bi.c @@ -0,0 +1,85 @@ +/* + * tiff-bi.c -- create a Class B (bilevel) TIFF file + * + * Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts. + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Digital not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include +#include + +#define WIDTH 512 +#define HEIGHT WIDTH + +typedef unsigned char u_char; + +void +main(argc, argv) + int argc; + char ** argv; +{ + int i; + u_char * scan_line; + TIFF * tif; + + if (argc != 2) { + fprintf(stderr, "Usage: %s tiff-image\n", argv[0]); + exit(0); + } + + if ((tif = TIFFOpen(argv[1], "w")) == NULL) { + fprintf(stderr, "can't open %s as a TIFF file\n", argv[1]); + exit(0); + } + + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 1); + TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE); + + scan_line = (u_char *) malloc(WIDTH / 8); + + for (i = 0; i < (WIDTH / 8) / 2; i++) + scan_line[i] = 0; + + for (i = (WIDTH / 8) / 2; i < (WIDTH / 8); i++) + scan_line[i] = 255; + + for (i = 0; i < HEIGHT / 2; i++) + TIFFWriteScanline(tif, scan_line, i, 0); + + for (i = 0; i < (WIDTH / 8) / 2; i++) + scan_line[i] = 255; + + for (i = (WIDTH / 8) / 2; i < (WIDTH / 8); i++) + scan_line[i] = 0; + + for (i = HEIGHT / 2; i < HEIGHT; i++) + TIFFWriteScanline(tif, scan_line, i, 0); + + free(scan_line); + TIFFClose(tif); + exit(0); +} diff --git a/contrib/dbs/tiff-grayscale.c b/contrib/dbs/tiff-grayscale.c new file mode 100644 index 00000000..f3e94842 --- /dev/null +++ b/contrib/dbs/tiff-grayscale.c @@ -0,0 +1,141 @@ +/* + * tiff-grayscale.c -- create a Class G (grayscale) TIFF file + * with a gray response curve in linear optical density + * + * Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts. + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Digital not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include +#include +#include + +#define WIDTH 512 +#define HEIGHT WIDTH + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned long u_long; + +char * programName; +void Usage(); + +void +main(argc, argv) + int argc; + char ** argv; +{ + int bits_per_pixel, cmsize, i, j, k, + gray_index, chunk_size, nchunks; + u_char * scan_line; + u_short * gray; + u_long refblackwhite[2*1]; + TIFF * tif; + + programName = argv[0]; + + if (argc != 4) + Usage(); + + if (!strcmp(argv[1], "-depth")) + bits_per_pixel = atoi(argv[2]); + else + Usage(); + + switch (bits_per_pixel) { + case 8: + nchunks = 16; + chunk_size = 32; + break; + case 4: + nchunks = 4; + chunk_size = 128; + break; + case 2: + nchunks = 2; + chunk_size = 256; + break; + default: + Usage(); + } + + cmsize = nchunks * nchunks; + gray = (u_short *) malloc(cmsize * sizeof(u_short)); + + gray[0] = 3000; + for (i = 1; i < cmsize; i++) + gray[i] = (u_short) (-log10((double) i / (cmsize - 1)) * 1000); + + refblackwhite[0] = 0; + refblackwhite[0] = (1L< +#include + +#define WIDTH 512 +#define HEIGHT WIDTH +#define SCALE(x) ((x) * 257L) + +typedef unsigned char u_char; +typedef unsigned short u_short; + +char * programName; +void Usage(); + +void +main(argc, argv) + int argc; + char ** argv; +{ + int bits_per_pixel, cmsize, i, j, k, + cmap_index, chunk_size, nchunks; + u_char * scan_line; + u_short *red, *green, *blue; + TIFF * tif; + + programName = argv[0]; + + if (argc != 4) + Usage(); + + if (!strcmp(argv[1], "-depth")) + bits_per_pixel = atoi(argv[2]); + else + Usage(); + + switch (bits_per_pixel) { + case 8: + nchunks = 16; + chunk_size = 32; + break; + case 4: + nchunks = 4; + chunk_size = 128; + break; + case 2: + nchunks = 2; + chunk_size = 256; + break; + case 1: + nchunks = 2; + chunk_size = 256; + break; + default: + Usage(); + } + + if (bits_per_pixel != 1) { + cmsize = nchunks * nchunks; + } else { + cmsize = 2; + } + red = (u_short *) malloc(cmsize * sizeof(u_short)); + green = (u_short *) malloc(cmsize * sizeof(u_short)); + blue = (u_short *) malloc(cmsize * sizeof(u_short)); + + switch (bits_per_pixel) { + case 8: + for (i = 0; i < cmsize; i++) { + if (i < 32) + red[i] = 0; + else if (i < 64) + red[i] = SCALE(36); + else if (i < 96) + red[i] = SCALE(73); + else if (i < 128) + red[i] = SCALE(109); + else if (i < 160) + red[i] = SCALE(146); + else if (i < 192) + red[i] = SCALE(182); + else if (i < 224) + red[i] = SCALE(219); + else if (i < 256) + red[i] = SCALE(255); + + if ((i % 32) < 4) + green[i] = 0; + else if (i < 8) + green[i] = SCALE(36); + else if ((i % 32) < 12) + green[i] = SCALE(73); + else if ((i % 32) < 16) + green[i] = SCALE(109); + else if ((i % 32) < 20) + green[i] = SCALE(146); + else if ((i % 32) < 24) + green[i] = SCALE(182); + else if ((i % 32) < 28) + green[i] = SCALE(219); + else if ((i % 32) < 32) + green[i] = SCALE(255); + + if ((i % 4) == 0) + blue[i] = SCALE(0); + else if ((i % 4) == 1) + blue[i] = SCALE(85); + else if ((i % 4) == 2) + blue[i] = SCALE(170); + else if ((i % 4) == 3) + blue[i] = SCALE(255); + } + break; + case 4: + red[0] = SCALE(255); + green[0] = 0; + blue[0] = 0; + + red[1] = 0; + green[1] = SCALE(255); + blue[1] = 0; + + red[2] = 0; + green[2] = 0; + blue[2] = SCALE(255); + + red[3] = SCALE(255); + green[3] = SCALE(255); + blue[3] = SCALE(255); + + red[4] = 0; + green[4] = SCALE(255); + blue[4] = SCALE(255); + + red[5] = SCALE(255); + green[5] = 0; + blue[5] = SCALE(255); + + red[6] = SCALE(255); + green[6] = SCALE(255); + blue[6] = 0; + + red[7] = 0; + green[7] = 0; + blue[7] = 0; + + red[8] = SCALE(176); + green[8] = SCALE(224); + blue[8] = SCALE(230); + red[9] = SCALE(100); + green[9] = SCALE(149); + blue[9] = SCALE(237); + red[10] = SCALE(46); + green[10] = SCALE(139); + blue[10] = SCALE(87); + red[11] = SCALE(160); + green[11] = SCALE(82); + blue[11] = SCALE(45); + red[12] = SCALE(238); + green[12] = SCALE(130); + blue[12] = SCALE(238); + red[13] = SCALE(176); + green[13] = SCALE(48); + blue[13] = SCALE(96); + red[14] = SCALE(50); + green[14] = SCALE(205); + blue[14] = SCALE(50); + red[15] = SCALE(240); + green[15] = SCALE(152); + blue[15] = SCALE(35); + break; + case 2: + red[0] = SCALE(255); + green[0] = 0; + blue[0] = 0; + + red[1] = 0; + green[1] = SCALE(255); + blue[1] = 0; + + red[2] = 0; + green[2] = 0; + blue[2] = SCALE(255); + red[3] = SCALE(255); + green[3] = SCALE(255); + blue[3] = SCALE(255); + break; + case 1: + red[0] = 0; + green[0] = 0; + blue[0] = 0; + + red[1] = SCALE(255); + green[1] = SCALE(255); + blue[1] = SCALE(255); + break; + } + + if ((tif = TIFFOpen(argv[3], "w")) == NULL) { + fprintf(stderr, "can't open %s as a TIFF file\n", argv[3]); + exit(0); + } + + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_pixel); + TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE); + TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue); + + scan_line = (u_char *) malloc(WIDTH / (8 / bits_per_pixel)); + + for (i = 0; i < HEIGHT; i++) { + for (j = 0, k = 0; j < WIDTH;) { + cmap_index = (j / chunk_size) + ((i / chunk_size) * nchunks); + + switch (bits_per_pixel) { + case 8: + scan_line[k++] = cmap_index; + j++; + break; + case 4: + scan_line[k++] = (cmap_index << 4) + cmap_index; + j += 2; + break; + case 2: + scan_line[k++] = (cmap_index << 6) + (cmap_index << 4) + + (cmap_index << 2) + cmap_index; + j += 4; + break; + case 1: + scan_line[k++] = + ((j / chunk_size) == (i / chunk_size)) ? 0x00 : 0xff; + j += 8; + break; + } + } + TIFFWriteScanline(tif, scan_line, i, 0); + } + + free(scan_line); + TIFFClose(tif); + exit(0); +} + +void +Usage() +{ + fprintf(stderr, "Usage: %s -depth (8 | 4 | 2 | 1) tiff-image\n", programName); + exit(0); +} diff --git a/contrib/dbs/tiff-rgb.c b/contrib/dbs/tiff-rgb.c new file mode 100644 index 00000000..6930e3a6 --- /dev/null +++ b/contrib/dbs/tiff-rgb.c @@ -0,0 +1,196 @@ +/* + * tiff-rgb.c -- create a 24-bit Class R (rgb) TIFF file + * + * Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts. + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Digital not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include +#include +#include + +#define ROUND(x) (u_short) ((x) + 0.5) +#define CMSIZE 256 +#define WIDTH 525 +#define HEIGHT 512 +#define TIFF_GAMMA 2.2 + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned long u_long; + +void Usage(); +char * programName; + +void +main(argc, argv) + int argc; + char ** argv; +{ + char * input_file; + double image_gamma; + int i, j; + TIFF * tif; + u_char * scan_line; + u_short red[CMSIZE], green[CMSIZE], blue[CMSIZE]; + u_long refblackwhite[2*3]; + + programName = argv[0]; + + switch (argc) { + case 2: + image_gamma = TIFF_GAMMA; + input_file = argv[1]; + break; + case 4: + if (!strcmp(argv[1], "-gamma")) { + image_gamma = atof(argv[2]); + input_file = argv[3]; + } else + Usage(); + break; + default: + Usage(); + } + + for (i = 0; i < CMSIZE; i++) { + if (i == 0) + red[i] = green[i] = blue[i] = 0; + else { + red[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0)); + green[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0)); + blue[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0)); + } + } + refblackwhite[0] = 0; refblackwhite[1] = 255; + refblackwhite[2] = 0; refblackwhite[3] = 255; + refblackwhite[4] = 0; refblackwhite[5] = 255; + + if ((tif = TIFFOpen(input_file, "w")) == NULL) { + fprintf(stderr, "can't open %s as a TIFF file\n", input_file); + exit(0); + } + + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE); +#ifdef notdef + TIFFSetField(tif, TIFFTAG_WHITEPOINT, whitex, whitey); + TIFFSetField(tif, TIFFTAG_PRIMARYCHROMATICITIES, primaries); +#endif + TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refblackwhite); + TIFFSetField(tif, TIFFTAG_TRANSFERFUNCTION, red, green, blue); + + scan_line = (u_char *) malloc(WIDTH * 3); + + for (i = 0; i < 255; i++) { + for (j = 0; j < 75; j++) { + scan_line[j * 3] = 255; + scan_line[(j * 3) + 1] = 255 - i; + scan_line[(j * 3) + 2] = 255 - i; + } + for (j = 75; j < 150; j++) { + scan_line[j * 3] = 255 - i; + scan_line[(j * 3) + 1] = 255; + scan_line[(j * 3) + 2] = 255 - i; + } + for (j = 150; j < 225; j++) { + scan_line[j * 3] = 255 - i; + scan_line[(j * 3) + 1] = 255 - i; + scan_line[(j * 3) + 2] = 255; + } + for (j = 225; j < 300; j++) { + scan_line[j * 3] = (i - 1) / 2; + scan_line[(j * 3) + 1] = (i - 1) / 2; + scan_line[(j * 3) + 2] = (i - 1) / 2; + } + for (j = 300; j < 375; j++) { + scan_line[j * 3] = 255 - i; + scan_line[(j * 3) + 1] = 255; + scan_line[(j * 3) + 2] = 255; + } + for (j = 375; j < 450; j++) { + scan_line[j * 3] = 255; + scan_line[(j * 3) + 1] = 255 - i; + scan_line[(j * 3) + 2] = 255; + } + for (j = 450; j < 525; j++) { + scan_line[j * 3] = 255; + scan_line[(j * 3) + 1] = 255; + scan_line[(j * 3) + 2] = 255 - i; + } + TIFFWriteScanline(tif, scan_line, i, 0); + } + for (i = 255; i < 512; i++) { + for (j = 0; j < 75; j++) { + scan_line[j * 3] = i; + scan_line[(j * 3) + 1] = 0; + scan_line[(j * 3) + 2] = 0; + } + for (j = 75; j < 150; j++) { + scan_line[j * 3] = 0; + scan_line[(j * 3) + 1] = i; + scan_line[(j * 3) + 2] = 0; + } + for (j = 150; j < 225; j++) { + scan_line[j * 3] = 0; + scan_line[(j * 3) + 1] = 0; + scan_line[(j * 3) + 2] = i; + } + for (j = 225; j < 300; j++) { + scan_line[j * 3] = (i - 1) / 2; + scan_line[(j * 3) + 1] = (i - 1) / 2; + scan_line[(j * 3) + 2] = (i - 1) / 2; + } + for (j = 300; j < 375; j++) { + scan_line[j * 3] = 0; + scan_line[(j * 3) + 1] = i; + scan_line[(j * 3) + 2] = i; + } + for (j = 375; j < 450; j++) { + scan_line[j * 3] = i; + scan_line[(j * 3) + 1] = 0; + scan_line[(j * 3) + 2] = i; + } + for (j = 450; j < 525; j++) { + scan_line[j * 3] = i; + scan_line[(j * 3) + 1] = i; + scan_line[(j * 3) + 2] = 0; + } + TIFFWriteScanline(tif, scan_line, i, 0); + } + + free(scan_line); + TIFFClose(tif); + exit(0); +} + +void +Usage() +{ + fprintf(stderr, "Usage: %s -gamma gamma tiff-image\n", programName); + exit(0); +} diff --git a/contrib/dbs/xtiff/Imakefile b/contrib/dbs/xtiff/Imakefile new file mode 100644 index 00000000..1aad45a4 --- /dev/null +++ b/contrib/dbs/xtiff/Imakefile @@ -0,0 +1,17 @@ +# +# Imakefile -- to generate a Makefile for xtiff, use: +# /usr/local/X11/mit/config/imake \ +# -I/usr/local/X11/mit/config \ +# -DTOPDIR=/usr/local/X11/mit \ +# -DCURDIR=/usr/local/X11/mit \ +# -DDESTDIR=/usr/local/X11/mit +# + + SYS_LIBRARIES = -lm + LOCAL_LIBRARIES = XawClientLibs + DEPLIBS = XawClientDepLibs + TIFF = ../../../libtiff + EXTRA_LIBRARIES = $(TIFF)/libtiff.so -lm + EXTRA_INCLUDES = -I$(TIFF) + +SimpleProgramTarget(xtiff) diff --git a/contrib/dbs/xtiff/README b/contrib/dbs/xtiff/README new file mode 100644 index 00000000..fa151476 --- /dev/null +++ b/contrib/dbs/xtiff/README @@ -0,0 +1,6 @@ +xtiff 2.0 + +xtiff is a tool for viewing a TIFF file in an X window. It was written to +handle as many different kinds of TIFF files as possible while remaining +simple, portable and efficient. xtiff requires X11 R4, the Athena Widgets +and Sam Leffler's libtiff package (which can be found on ucbvax.berkeley.edu). diff --git a/contrib/dbs/xtiff/patchlevel.h b/contrib/dbs/xtiff/patchlevel.h new file mode 100644 index 00000000..935ec354 --- /dev/null +++ b/contrib/dbs/xtiff/patchlevel.h @@ -0,0 +1 @@ +#define PATCHLEVEL 0 diff --git a/contrib/dbs/xtiff/xtiff.c b/contrib/dbs/xtiff/xtiff.c new file mode 100644 index 00000000..918265ec --- /dev/null +++ b/contrib/dbs/xtiff/xtiff.c @@ -0,0 +1,1275 @@ +/* + * xtiff - view a TIFF file in an X window + * + * Dan Sears + * Chris Sears + * + * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts. + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Digital not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Revision 1.0 90/05/07 + * Initial release. + * Revision 2.0 90/12/20 + * Converted to use the Athena Widgets and the Xt Intrinsics. + * + * Notes: + * + * According to the TIFF 5.0 Specification, it is possible to have + * both a TIFFTAG_COLORMAP and a TIFFTAG_COLORRESPONSECURVE. This + * doesn't make sense since a TIFFTAG_COLORMAP is 16 bits wide and + * a TIFFTAG_COLORRESPONSECURVE is tfBitsPerSample bits wide for each + * channel. This is probably a bug in the specification. + * In this case, TIFFTAG_COLORRESPONSECURVE is ignored. + * This might make sense if TIFFTAG_COLORMAP was 8 bits wide. + * + * TIFFTAG_COLORMAP is often incorrectly written as ranging from + * 0 to 255 rather than from 0 to 65535. CheckAndCorrectColormap() + * takes care of this. + * + * Only ORIENTATION_TOPLEFT is supported correctly. This is the + * default TIFF and X orientation. Other orientations will be + * displayed incorrectly. + * + * There is no support for or use of 3/3/2 DirectColor visuals. + * TIFFTAG_MINSAMPLEVALUE and TIFFTAG_MAXSAMPLEVALUE are not supported. + * + * Only TIFFTAG_BITSPERSAMPLE values that are 1, 2, 4 or 8 are supported. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define XK_MISCELLANY +#include +#include "xtifficon.h" + +#define TIFF_GAMMA "2.2" /* default gamma from the TIFF 5.0 spec */ +#define ROUND(x) (u_short) ((x) + 0.5) +#define SCALE(x, s) (((x) * 65535L) / (s)) +#define MCHECK(m) if (!m) { fprintf(stderr, "malloc failed\n"); exit(0); } +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define VIEWPORT_WIDTH 700 +#define VIEWPORT_HEIGHT 500 +#define KEY_TRANSLATE 20 + +#ifdef __STDC__ +#define PP(args) args +#else +#define PP(args) () +#endif + +void main PP((int argc, char **argv)); +void OpenTIFFFile PP((void)); +void GetTIFFHeader PP((void)); +void SetNameLabel PP((void)); +void CheckAndCorrectColormap PP((void)); +void SimpleGammaCorrection PP((void)); +void GetVisual PP((void)); +Boolean SearchVisualList PP((int image_depth, + int visual_class, Visual **visual)); +void GetTIFFImage PP((void)); +void CreateXImage PP((void)); +XtCallbackProc SelectProc PP((Widget w, caddr_t unused_1, caddr_t unused_2)); +void QuitProc PP((void)); +void NextProc PP((void)); +void PreviousProc PP((void)); +void PageProc PP((int direction)); +void EventProc PP((Widget widget, caddr_t unused, XEvent *event)); +void ResizeProc PP((void)); +int XTiffErrorHandler PP((Display *display, XErrorEvent *error_event)); +void Usage PP((void)); + +int xtVersion = XtSpecificationRelease; /* xtiff depends on R4 or higher */ + +/* + * Xt data structures + */ +Widget shellWidget, formWidget, listWidget, labelWidget, imageWidget; + +enum { ButtonQuit = 0, ButtonPreviousPage = 1, ButtonNextPage = 2 }; + +String buttonStrings[] = { "Quit", "Previous", "Next" }; + +static XrmOptionDescRec shellOptions[] = { + { "-help", "*help", XrmoptionNoArg, (caddr_t) "True" }, + { "-gamma", "*gamma", XrmoptionSepArg, NULL }, + { "-usePixmap", "*usePixmap", XrmoptionSepArg, NULL }, + { "-viewportWidth", "*viewportWidth", XrmoptionSepArg, NULL }, + { "-viewportHeight", "*viewportHeight", XrmoptionSepArg, NULL }, + { "-translate", "*translate", XrmoptionSepArg, NULL }, + { "-verbose", "*verbose", XrmoptionSepArg, NULL } +}; + +typedef struct { + Boolean help; + float gamma; + Boolean usePixmap; + int viewportWidth; + int viewportHeight; + int translate; + Boolean verbose; +} AppData, *AppDataPtr; + +AppData appData; + +XtResource clientResources[] = { + { + "help", XtCBoolean, XtRBoolean, sizeof(Boolean), + XtOffset(AppDataPtr, help), XtRImmediate, (XtPointer) False + }, { + "gamma", "Gamma", XtRFloat, sizeof(float), + XtOffset(AppDataPtr, gamma), XtRString, (XtPointer) TIFF_GAMMA + }, { + "usePixmap", "UsePixmap", XtRBoolean, sizeof(Boolean), + XtOffset(AppDataPtr, usePixmap), XtRImmediate, (XtPointer) True + }, { + "viewportWidth", "ViewportWidth", XtRInt, sizeof(int), + XtOffset(AppDataPtr, viewportWidth), XtRImmediate, + (XtPointer) VIEWPORT_WIDTH + }, { + "viewportHeight", "ViewportHeight", XtRInt, sizeof(int), + XtOffset(AppDataPtr, viewportHeight), XtRImmediate, + (XtPointer) VIEWPORT_HEIGHT + }, { + "translate", "Translate", XtRInt, sizeof(int), + XtOffset(AppDataPtr, translate), XtRImmediate, (XtPointer) KEY_TRANSLATE + }, { + "verbose", "Verbose", XtRBoolean, sizeof(Boolean), + XtOffset(AppDataPtr, verbose), XtRImmediate, (XtPointer) True + } +}; + +Arg formArgs[] = { + { XtNresizable, True } +}; + +Arg listArgs[] = { + { XtNresizable, False }, + { XtNborderWidth, 0 }, + { XtNdefaultColumns, 3 }, + { XtNforceColumns, True }, + { XtNlist, (int) buttonStrings }, + { XtNnumberStrings, XtNumber(buttonStrings) }, + { XtNtop, XtChainTop }, + { XtNleft, XtChainLeft }, + { XtNbottom, XtChainTop }, + { XtNright, XtChainLeft } +}; + +Arg labelArgs[] = { + { XtNresizable, False }, + { XtNwidth, 200 }, + { XtNborderWidth, 0 }, + { XtNjustify, XtJustifyLeft }, + { XtNtop, XtChainTop }, + { XtNleft, XtChainLeft }, + { XtNbottom, XtChainTop }, + { XtNright, XtChainLeft } +}; + +Arg imageArgs[] = { + { XtNresizable, True }, + { XtNborderWidth, 0 }, + { XtNtop, XtChainTop }, + { XtNleft, XtChainLeft }, + { XtNbottom, XtChainTop }, + { XtNright, XtChainLeft } +}; + +XtActionsRec actionsTable[] = { + { "quit", QuitProc }, + { "next", NextProc }, + { "previous", PreviousProc }, + { "notifyresize", ResizeProc } +}; + +char translationsTable[] = "q: quit() \n \ + Q: quit() \n \ + WM_PROTOCOLS: quit()\n \ + p: previous() \n \ + P: previous() \n \ + n: next() \n \ + N: next() \n \ + : notifyresize()"; + +/* + * X data structures + */ +Colormap xColormap; +Display * xDisplay; +Pixmap xImagePixmap; +Visual * xVisual; +XImage * xImage; +GC xWinGc; +int xImageDepth, xScreen, xRedMask, xGreenMask, xBlueMask, + xOffset = 0, yOffset = 0, grabX = -1, grabY = -1; +u_char basePixel = 0; + +/* + * TIFF data structures + */ +TIFF * tfFile = NULL; +u_long tfImageWidth, tfImageHeight; +u_short tfBitsPerSample, tfSamplesPerPixel, tfPlanarConfiguration, + tfPhotometricInterpretation, tfGrayResponseUnit, + tfImageDepth, tfBytesPerRow; +int tfDirectory = 0, tfMultiPage = False; +double tfUnitMap, tfGrayResponseUnitMap[] = { + -1, -10, -100, -1000, -10000, -100000 + }; + +/* + * display data structures + */ +double *dRed, *dGreen, *dBlue; + +/* + * shared data structures + */ +u_short * redMap = NULL, *greenMap = NULL, *blueMap = NULL, + *grayMap = NULL, colormapSize; +u_char * imageMemory; +char * fileName; + +void +main(argc, argv) + int argc; + char ** argv; +{ + XSetWindowAttributes window_attributes; + Widget widget_list[3]; + Arg args[5]; + + setbuf(stdout, NULL); setbuf(stderr, NULL); + + shellWidget = XtInitialize(argv[0], "XTiff", shellOptions, + XtNumber(shellOptions), &argc, argv); + + XSetErrorHandler(XTiffErrorHandler); + + XtGetApplicationResources(shellWidget, &appData, + (XtResourceList) clientResources, (Cardinal) XtNumber(clientResources), + (ArgList) NULL, (Cardinal) 0); + + if ((argc <= 1) || (argc > 2) || appData.help) + Usage(); + + if (appData.verbose == False) { + TIFFSetErrorHandler(0); + TIFFSetWarningHandler(0); + } + + fileName = argv[1]; + + xDisplay = XtDisplay(shellWidget); + xScreen = DefaultScreen(xDisplay); + + OpenTIFFFile(); + GetTIFFHeader(); + SimpleGammaCorrection(); + GetVisual(); + GetTIFFImage(); + + /* + * Send visual, colormap, depth and iconPixmap to shellWidget. + * Sending the visual to the shell is only possible with the advent of R4. + */ + XtSetArg(args[0], XtNvisual, xVisual); + XtSetArg(args[1], XtNcolormap, xColormap); + XtSetArg(args[2], XtNdepth, + xImageDepth == 1 ? DefaultDepth(xDisplay, xScreen) : xImageDepth); + XtSetArg(args[3], XtNiconPixmap, + XCreateBitmapFromData(xDisplay, RootWindow(xDisplay, xScreen), + xtifficon_bits, xtifficon_width, xtifficon_height)); + XtSetArg(args[4], XtNallowShellResize, True); + XtSetValues(shellWidget, args, 5); + + /* + * widget instance hierarchy + */ + formWidget = XtCreateManagedWidget("form", formWidgetClass, + shellWidget, formArgs, XtNumber(formArgs)); + + widget_list[0] = listWidget = XtCreateWidget("list", + listWidgetClass, formWidget, listArgs, XtNumber(listArgs)); + + widget_list[1] = labelWidget = XtCreateWidget("label", + labelWidgetClass, formWidget, labelArgs, XtNumber(labelArgs)); + + widget_list[2] = imageWidget = XtCreateWidget("image", + widgetClass, formWidget, imageArgs, XtNumber(imageArgs)); + + XtManageChildren(widget_list, XtNumber(widget_list)); + + /* + * initial widget sizes - for small images let xtiff size itself + */ + if (tfImageWidth >= appData.viewportWidth) { + XtSetArg(args[0], XtNwidth, appData.viewportWidth); + XtSetValues(shellWidget, args, 1); + } + if (tfImageHeight >= appData.viewportHeight) { + XtSetArg(args[0], XtNheight, appData.viewportHeight); + XtSetValues(shellWidget, args, 1); + } + + XtSetArg(args[0], XtNwidth, tfImageWidth); + XtSetArg(args[1], XtNheight, tfImageHeight); + XtSetValues(imageWidget, args, 2); + + /* + * formWidget uses these constraints but they are stored in the children. + */ + XtSetArg(args[0], XtNfromVert, listWidget); + XtSetValues(imageWidget, args, 1); + XtSetArg(args[0], XtNfromHoriz, listWidget); + XtSetValues(labelWidget, args, 1); + + SetNameLabel(); + + XtAddCallback(listWidget, XtNcallback, (XtCallbackProc) SelectProc, + (XtPointer) NULL); + + XtAddActions(actionsTable, XtNumber(actionsTable)); + XtSetArg(args[0], XtNtranslations, + XtParseTranslationTable(translationsTable)); + XtSetValues(formWidget, &args[0], 1); + XtSetValues(imageWidget, &args[0], 1); + + /* + * This is intended to be a little faster than going through + * the translation manager. + */ + XtAddEventHandler(imageWidget, ExposureMask | ButtonPressMask + | ButtonReleaseMask | Button1MotionMask | KeyPressMask, + False, EventProc, NULL); + + XtRealizeWidget(shellWidget); + + window_attributes.cursor = XCreateFontCursor(xDisplay, XC_fleur); + XChangeWindowAttributes(xDisplay, XtWindow(imageWidget), + CWCursor, &window_attributes); + + CreateXImage(); + + XtMainLoop(); +} + +void +OpenTIFFFile() +{ + if (tfFile != NULL) + TIFFClose(tfFile); + + if ((tfFile = TIFFOpen(fileName, "r")) == NULL) { + fprintf(appData.verbose ? stderr : stdout, + "xtiff: can't open %s as a TIFF file\n", fileName); + exit(0); + } + + tfMultiPage = (TIFFLastDirectory(tfFile) ? False : True); +} + +void +GetTIFFHeader() +{ + register int i; + + if (!TIFFSetDirectory(tfFile, tfDirectory)) { + fprintf(stderr, "xtiff: can't seek to directory %d in %s\n", + tfDirectory, fileName); + exit(0); + } + + TIFFGetField(tfFile, TIFFTAG_IMAGEWIDTH, &tfImageWidth); + TIFFGetField(tfFile, TIFFTAG_IMAGELENGTH, &tfImageHeight); + + /* + * If the following tags aren't present then use the TIFF defaults. + */ + TIFFGetFieldDefaulted(tfFile, TIFFTAG_BITSPERSAMPLE, &tfBitsPerSample); + TIFFGetFieldDefaulted(tfFile, TIFFTAG_SAMPLESPERPIXEL, &tfSamplesPerPixel); + TIFFGetFieldDefaulted(tfFile, TIFFTAG_PLANARCONFIG, &tfPlanarConfiguration); + TIFFGetFieldDefaulted(tfFile, TIFFTAG_GRAYRESPONSEUNIT, &tfGrayResponseUnit); + + tfUnitMap = tfGrayResponseUnitMap[tfGrayResponseUnit]; + colormapSize = 1 << tfBitsPerSample; + tfImageDepth = tfBitsPerSample * tfSamplesPerPixel; + + dRed = (double *) malloc(colormapSize * sizeof(double)); + dGreen = (double *) malloc(colormapSize * sizeof(double)); + dBlue = (double *) malloc(colormapSize * sizeof(double)); + MCHECK(dRed); MCHECK(dGreen); MCHECK(dBlue); + + /* + * If TIFFTAG_PHOTOMETRIC is not present then assign a reasonable default. + * The TIFF 5.0 specification doesn't give a default. + */ + if (!TIFFGetField(tfFile, TIFFTAG_PHOTOMETRIC, + &tfPhotometricInterpretation)) { + if (tfSamplesPerPixel != 1) + tfPhotometricInterpretation = PHOTOMETRIC_RGB; + else if (tfBitsPerSample == 1) + tfPhotometricInterpretation = PHOTOMETRIC_MINISBLACK; + else if (TIFFGetField(tfFile, TIFFTAG_COLORMAP, + &redMap, &greenMap, &blueMap)) { + tfPhotometricInterpretation = PHOTOMETRIC_PALETTE; + redMap = greenMap = blueMap = NULL; + } else + tfPhotometricInterpretation = PHOTOMETRIC_MINISBLACK; + } + + /* + * Given TIFFTAG_PHOTOMETRIC extract or create the response curves. + */ + switch (tfPhotometricInterpretation) { + case PHOTOMETRIC_RGB: + redMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + greenMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + blueMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap); + for (i = 0; i < colormapSize; i++) + dRed[i] = dGreen[i] = dBlue[i] + = (double) SCALE(i, colormapSize - 1); + break; + case PHOTOMETRIC_PALETTE: + if (!TIFFGetField(tfFile, TIFFTAG_COLORMAP, + &redMap, &greenMap, &blueMap)) { + redMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + greenMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + blueMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap); + for (i = 0; i < colormapSize; i++) + dRed[i] = dGreen[i] = dBlue[i] + = (double) SCALE(i, colormapSize - 1); + } else { + CheckAndCorrectColormap(); + for (i = 0; i < colormapSize; i++) { + dRed[i] = (double) redMap[i]; + dGreen[i] = (double) greenMap[i]; + dBlue[i] = (double) blueMap[i]; + } + } + break; + case PHOTOMETRIC_MINISWHITE: + redMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + greenMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + blueMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap); + for (i = 0; i < colormapSize; i++) + dRed[i] = dGreen[i] = dBlue[i] = (double) + SCALE(colormapSize-1-i, colormapSize-1); + break; + case PHOTOMETRIC_MINISBLACK: + redMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + greenMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + blueMap = (u_short *) malloc(colormapSize * sizeof(u_short)); + MCHECK(redMap); MCHECK(greenMap); MCHECK(blueMap); + for (i = 0; i < colormapSize; i++) + dRed[i] = dGreen[i] = dBlue[i] = (double) SCALE(i, colormapSize-1); + break; + default: + fprintf(stderr, + "xtiff: can't display photometric interpretation type %d\n", + tfPhotometricInterpretation); + exit(0); + } +} + +void +SetNameLabel() +{ + char buffer[BUFSIZ]; + Arg args[1]; + + if (tfMultiPage) + sprintf(buffer, "%s - page %d", fileName, tfDirectory); + else + strcpy(buffer, fileName); + XtSetArg(args[0], XtNlabel, buffer); + XtSetValues(labelWidget, args, 1); +} + +/* + * Many programs get TIFF colormaps wrong. They use 8-bit colormaps instead of + * 16-bit colormaps. This function is a heuristic to detect and correct this. + */ +void +CheckAndCorrectColormap() +{ + register int i; + + for (i = 0; i < colormapSize; i++) + if ((redMap[i] > 255) || (greenMap[i] > 255) || (blueMap[i] > 255)) + return; + + for (i = 0; i < colormapSize; i++) { + redMap[i] = SCALE(redMap[i], 255); + greenMap[i] = SCALE(greenMap[i], 255); + blueMap[i] = SCALE(blueMap[i], 255); + } + TIFFWarning(fileName, "Assuming 8-bit colormap"); +} + +void +SimpleGammaCorrection() +{ + register int i; + register double i_gamma = 1.0 / appData.gamma; + + for (i = 0; i < colormapSize; i++) { + if (((tfPhotometricInterpretation == PHOTOMETRIC_MINISWHITE) + && (i == colormapSize - 1)) + || ((tfPhotometricInterpretation == PHOTOMETRIC_MINISBLACK) + && (i == 0))) + redMap[i] = greenMap[i] = blueMap[i] = 0; + else { + redMap[i] = ROUND((pow(dRed[i] / 65535.0, i_gamma) * 65535.0)); + greenMap[i] = ROUND((pow(dGreen[i] / 65535.0, i_gamma) * 65535.0)); + blueMap[i] = ROUND((pow(dBlue[i] / 65535.0, i_gamma) * 65535.0)); + } + } + + free(dRed); free(dGreen); free(dBlue); +} + +static char* classNames[] = { + "StaticGray", + "GrayScale", + "StaticColor", + "PseudoColor", + "TrueColor", + "DirectColor" +}; + +/* + * Current limitation: the visual is set initially by the first file. + * It cannot be changed. + */ +void +GetVisual() +{ + register XColor *colors = NULL; + register u_long *pixels = NULL; + register int i; + + switch (tfImageDepth) { + /* + * X really wants a 32-bit image with the fourth channel unused, + * but the visual structure thinks it's 24-bit. bitmap_unit is 32. + */ + case 32: + case 24: + if (SearchVisualList(24, DirectColor, &xVisual) == False) { + fprintf(stderr, "xtiff: 24-bit DirectColor visual not available\n"); + exit(0); + } + + colors = (XColor *) malloc(3 * colormapSize * sizeof(XColor)); + MCHECK(colors); + + for (i = 0; i < colormapSize; i++) { + colors[i].pixel = (u_long) (i << 16) + (i << 8) + i; + colors[i].red = redMap[i]; + colors[i].green = greenMap[i]; + colors[i].blue = blueMap[i]; + colors[i].flags = DoRed | DoGreen | DoBlue; + } + + xColormap = XCreateColormap(xDisplay, RootWindow(xDisplay, xScreen), + xVisual, AllocAll); + XStoreColors(xDisplay, xColormap, colors, colormapSize); + break; + case 8: + case 4: + case 2: + /* + * We assume that systems with 24-bit visuals also have 8-bit visuals. + * We don't promote from 8-bit PseudoColor to 24/32 bit DirectColor. + */ + switch (tfPhotometricInterpretation) { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (SearchVisualList((int) tfImageDepth, GrayScale, &xVisual) == True) + break; + case PHOTOMETRIC_PALETTE: + if (SearchVisualList((int) tfImageDepth, PseudoColor, &xVisual) == True) + break; + default: + fprintf(stderr, "xtiff: Unsupported TIFF/X configuration\n"); + exit(0); + } + + colors = (XColor *) malloc(colormapSize * sizeof(XColor)); + MCHECK(colors); + + for (i = 0; i < colormapSize; i++) { + colors[i].pixel = (u_long) i; + colors[i].red = redMap[i]; + colors[i].green = greenMap[i]; + colors[i].blue = blueMap[i]; + colors[i].flags = DoRed | DoGreen | DoBlue; + } + + /* + * xtiff's colormap allocation is private. It does not attempt + * to detect whether any existing colormap entries are suitable + * for its use. This will cause colormap flashing. Furthermore, + * background and foreground are taken from the environment. + * For example, the foreground color may be red when the visual + * is GrayScale. If the colormap is completely populated, + * Xt will not be able to allocate fg and bg. + */ + if (tfImageDepth == 8) + xColormap = XCreateColormap(xDisplay, RootWindow(xDisplay, xScreen), + xVisual, AllocAll); + else { + xColormap = XCreateColormap(xDisplay, RootWindow(xDisplay, xScreen), + xVisual, AllocNone); + pixels = (u_long *) malloc(colormapSize * sizeof(u_long)); + MCHECK(pixels); + (void) XAllocColorCells(xDisplay, xColormap, True, + NULL, 0, pixels, colormapSize); + basePixel = (u_char) pixels[0]; + free(pixels); + } + XStoreColors(xDisplay, xColormap, colors, colormapSize); + break; + case 1: + xImageDepth = 1; + xVisual = DefaultVisual(xDisplay, xScreen); + xColormap = DefaultColormap(xDisplay, xScreen); + break; + default: + fprintf(stderr, "xtiff: unsupported image depth %d\n", tfImageDepth); + exit(0); + } + + if (appData.verbose == True) + fprintf(stderr, "%s: Using %d-bit %s visual.\n", + fileName, xImageDepth, classNames[xVisual->class]); + + if (colors != NULL) + free(colors); + if (grayMap != NULL) + free(grayMap); + if (redMap != NULL) + free(redMap); + if (greenMap != NULL) + free(greenMap); + if (blueMap != NULL) + free(blueMap); + + colors = NULL; grayMap = redMap = greenMap = blueMap = NULL; +} + +/* + * Search for an appropriate visual. Promote where necessary. + * Check to make sure that ENOUGH colormap entries are writeable. + * basePixel was determined when XAllocColorCells() contiguously + * allocated enough entries. basePixel is used below in GetTIFFImage. + */ +Boolean +SearchVisualList(image_depth, visual_class, visual) + int image_depth, visual_class; + Visual **visual; +{ + XVisualInfo template_visual, *visual_list, *vl; + int i, n_visuals; + + template_visual.screen = xScreen; + vl = visual_list = XGetVisualInfo(xDisplay, VisualScreenMask, + &template_visual, &n_visuals); + + if (n_visuals == 0) { + fprintf(stderr, "xtiff: visual list not available\n"); + exit(0); + } + + for (i = 0; i < n_visuals; vl++, i++) { + if ((vl->class == visual_class) && (vl->depth >= image_depth) + && (vl->visual->map_entries >= (1 << vl->depth))) { + *visual = vl->visual; + xImageDepth = vl->depth; + xRedMask = vl->red_mask; + xGreenMask = vl->green_mask; + xBlueMask = vl->blue_mask; + XFree((char *) visual_list); + return True; + } + } + + XFree((char *) visual_list); + return False; +} + +void +GetTIFFImage() +{ + int pixel_map[3], red_shift, green_shift, blue_shift; + register u_char *scan_line, *output_p, *input_p; + register int i, j, s; + + scan_line = (u_char *) malloc(tfBytesPerRow = TIFFScanlineSize(tfFile)); + MCHECK(scan_line); + + if ((tfImageDepth == 32) || (tfImageDepth == 24)) { + output_p = imageMemory = (u_char *) + malloc(tfImageWidth * tfImageHeight * 4); + MCHECK(imageMemory); + + /* + * Handle different color masks for different frame buffers. + */ + if (ImageByteOrder(xDisplay) == LSBFirst) { /* DECstation 5000 */ + red_shift = pixel_map[0] = xRedMask == 0xFF000000 ? 3 + : (xRedMask == 0xFF0000 ? 2 : (xRedMask == 0xFF00 ? 1 : 0)); + green_shift = pixel_map[1] = xGreenMask == 0xFF000000 ? 3 + : (xGreenMask == 0xFF0000 ? 2 : (xGreenMask == 0xFF00 ? 1 : 0)); + blue_shift = pixel_map[2] = xBlueMask == 0xFF000000 ? 3 + : (xBlueMask == 0xFF0000 ? 2 : (xBlueMask == 0xFF00 ? 1 : 0)); + } else { /* Ardent */ + red_shift = pixel_map[0] = xRedMask == 0xFF000000 ? 0 + : (xRedMask == 0xFF0000 ? 1 : (xRedMask == 0xFF00 ? 2 : 3)); + green_shift = pixel_map[0] = xGreenMask == 0xFF000000 ? 0 + : (xGreenMask == 0xFF0000 ? 1 : (xGreenMask == 0xFF00 ? 2 : 3)); + blue_shift = pixel_map[0] = xBlueMask == 0xFF000000 ? 0 + : (xBlueMask == 0xFF0000 ? 1 : (xBlueMask == 0xFF00 ? 2 : 3)); + } + + if (tfPlanarConfiguration == PLANARCONFIG_CONTIG) { + for (i = 0; i < tfImageHeight; i++) { + if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0) + break; + for (input_p = scan_line, j = 0; j < tfImageWidth; j++) { + *(output_p + red_shift) = *input_p++; + *(output_p + green_shift) = *input_p++; + *(output_p + blue_shift) = *input_p++; + output_p += 4; + if (tfSamplesPerPixel == 4) /* skip the fourth channel */ + input_p++; + } + } + } else { + for (s = 0; s < tfSamplesPerPixel; s++) { + if (s == 3) /* skip the fourth channel */ + continue; + for (i = 0; i < tfImageHeight; i++) { + if (TIFFReadScanline(tfFile, scan_line, i, s) < 0) + break; + input_p = scan_line; + output_p = imageMemory + (i*tfImageWidth*4) + pixel_map[s]; + for (j = 0; j < tfImageWidth; j++, output_p += 4) + *output_p = *input_p++; + } + } + } + } else { + if (xImageDepth == tfImageDepth) { + output_p = imageMemory = (u_char *) + malloc(tfBytesPerRow * tfImageHeight); + MCHECK(imageMemory); + + for (i = 0; i < tfImageHeight; i++, output_p += tfBytesPerRow) + if (TIFFReadScanline(tfFile, output_p, i, 0) < 0) + break; + } else if ((xImageDepth == 8) && (tfImageDepth == 4)) { + output_p = imageMemory = (u_char *) + malloc(tfBytesPerRow * 2 * tfImageHeight + 2); + MCHECK(imageMemory); + + /* + * If a scanline is of odd size the inner loop below will overshoot. + * This is handled very simply by recalculating the start point at + * each scanline and padding imageMemory a little at the end. + */ + for (i = 0; i < tfImageHeight; i++) { + if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0) + break; + output_p = &imageMemory[i * tfImageWidth]; + input_p = scan_line; + for (j = 0; j < tfImageWidth; j += 2, input_p++) { + *output_p++ = (*input_p >> 4) + basePixel; + *output_p++ = (*input_p & 0xf) + basePixel; + } + } + } else if ((xImageDepth == 8) && (tfImageDepth == 2)) { + output_p = imageMemory = (u_char *) + malloc(tfBytesPerRow * 4 * tfImageHeight + 4); + MCHECK(imageMemory); + + for (i = 0; i < tfImageHeight; i++) { + if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0) + break; + output_p = &imageMemory[i * tfImageWidth]; + input_p = scan_line; + for (j = 0; j < tfImageWidth; j += 4, input_p++) { + *output_p++ = (*input_p >> 6) + basePixel; + *output_p++ = ((*input_p >> 4) & 3) + basePixel; + *output_p++ = ((*input_p >> 2) & 3) + basePixel; + *output_p++ = (*input_p & 3) + basePixel; + } + } + } else if ((xImageDepth == 4) && (tfImageDepth == 2)) { + output_p = imageMemory = (u_char *) + malloc(tfBytesPerRow * 2 * tfImageHeight + 2); + MCHECK(imageMemory); + + for (i = 0; i < tfImageHeight; i++) { + if (TIFFReadScanline(tfFile, scan_line, i, 0) < 0) + break; + output_p = &imageMemory[i * tfBytesPerRow * 2]; + input_p = scan_line; + for (j = 0; j < tfImageWidth; j += 4, input_p++) { + *output_p++ = (((*input_p>>6) << 4) + | ((*input_p >> 4) & 3)) + basePixel; + *output_p++ = ((((*input_p>>2) & 3) << 4) + | (*input_p & 3)) + basePixel; + } + } + } else { + fprintf(stderr, + "xtiff: can't handle %d-bit TIFF file on an %d-bit display\n", + tfImageDepth, xImageDepth); + exit(0); + } + } + + free(scan_line); +} + +void +CreateXImage() +{ + XGCValues gc_values; + GC bitmap_gc; + + xOffset = yOffset = 0; + grabX = grabY = -1; + + xImage = XCreateImage(xDisplay, xVisual, xImageDepth, + xImageDepth == 1 ? XYBitmap : ZPixmap, /* offset */ 0, + (char *) imageMemory, tfImageWidth, tfImageHeight, + /* bitmap_pad */ 8, /* bytes_per_line */ 0); + + /* + * libtiff converts LSB data into MSB but doesn't change the FillOrder tag. + */ + if (xImageDepth == 1) + xImage->bitmap_bit_order = MSBFirst; + if (xImageDepth <= 8) + xImage->byte_order = MSBFirst; + + /* + * create an appropriate GC + */ + gc_values.function = GXcopy; + gc_values.plane_mask = AllPlanes; + if (tfPhotometricInterpretation == PHOTOMETRIC_MINISBLACK) { + gc_values.foreground = XWhitePixel(xDisplay, xScreen); + gc_values.background = XBlackPixel(xDisplay, xScreen); + } else { + gc_values.foreground = XBlackPixel(xDisplay, xScreen); + gc_values.background = XWhitePixel(xDisplay, xScreen); + } + xWinGc = XCreateGC(xDisplay, XtWindow(shellWidget), + GCFunction | GCPlaneMask | GCForeground | GCBackground, &gc_values); + + /* + * create the pixmap and load the image + */ + if (appData.usePixmap == True) { + xImagePixmap = XCreatePixmap(xDisplay, RootWindow(xDisplay, xScreen), + xImage->width, xImage->height, xImageDepth); + + /* + * According to the O'Reilly X Protocol Reference Manual, page 53, + * "A pixmap depth of one is always supported and listed, but windows + * of depth one might not be supported." Therefore we create a pixmap + * of depth one and use XCopyPlane(). This is idiomatic. + */ + if (xImageDepth == 1) { /* just pass the bits through */ + gc_values.foreground = 1; /* foreground describes set bits */ + gc_values.background = 0; /* background describes clear bits */ + bitmap_gc = XCreateGC(xDisplay, xImagePixmap, + GCForeground | GCBackground, &gc_values); + XPutImage(xDisplay, xImagePixmap, bitmap_gc, xImage, + 0, 0, 0, 0, xImage->width, xImage->height); + } else + XPutImage(xDisplay, xImagePixmap, xWinGc, xImage, + 0, 0, 0, 0, xImage->width, xImage->height); + XDestroyImage(xImage); + free(imageMemory); + } +} + +XtCallbackProc +SelectProc(w, unused_1, unused_2) + Widget w; + caddr_t unused_1; + caddr_t unused_2; +{ + XawListReturnStruct *list_return; + + list_return = XawListShowCurrent(w); + + switch (list_return->list_index) { + case ButtonQuit: + QuitProc(); + break; + case ButtonPreviousPage: + PreviousProc(); + break; + case ButtonNextPage: + NextProc(); + break; + default: + fprintf(stderr, "error in SelectProc\n"); + exit(0); + } + XawListUnhighlight(w); +} + +void +QuitProc(void) +{ + exit(0); +} + +void +NextProc() +{ + PageProc(ButtonNextPage); +} + +void +PreviousProc() +{ + PageProc(ButtonPreviousPage); +} + +void +PageProc(direction) + int direction; +{ + XEvent fake_event; + Arg args[4]; + + switch (direction) { + case ButtonPreviousPage: + if (tfDirectory > 0) + TIFFSetDirectory(tfFile, --tfDirectory); + else + return; + break; + case ButtonNextPage: + if (TIFFReadDirectory(tfFile) == True) + tfDirectory++; + else + return; + break; + default: + fprintf(stderr, "error in PageProc\n"); + exit(0); + } + + xOffset = yOffset = 0; + grabX = grabY = -1; + + GetTIFFHeader(); + SetNameLabel(); + GetTIFFImage(); + + if (appData.usePixmap == True) + XFreePixmap(xDisplay, xImagePixmap); + else + XDestroyImage(xImage); + + CreateXImage(); + + /* + * Using XtSetValues() to set the widget size causes a resize. + * This resize gets propagated up to the parent shell. + * In order to disable this visually disconcerting effect, + * shell resizing is temporarily disabled. + */ + XtSetArg(args[0], XtNallowShellResize, False); + XtSetValues(shellWidget, args, 1); + + XtSetArg(args[0], XtNwidth, tfImageWidth); + XtSetArg(args[1], XtNheight, tfImageHeight); + XtSetValues(imageWidget, args, 2); + + XtSetArg(args[0], XtNallowShellResize, True); + XtSetValues(shellWidget, args, 1); + + XClearWindow(xDisplay, XtWindow(imageWidget)); + + fake_event.type = Expose; + fake_event.xexpose.x = fake_event.xexpose.y = 0; + fake_event.xexpose.width = tfImageWidth; /* the window will clip */ + fake_event.xexpose.height = tfImageHeight; + EventProc(imageWidget, NULL, &fake_event); +} + +void +EventProc(widget, unused, event) + Widget widget; + caddr_t unused; + XEvent *event; +{ + int ih, iw, ww, wh, sx, sy, w, h, dx, dy; + Dimension w_width, w_height; + XEvent next_event; + Arg args[2]; + + if (event->type == MappingNotify) { + XRefreshKeyboardMapping((XMappingEvent *) event); + return; + } + + if (!XtIsRealized(widget)) + return; + + if ((event->type == ButtonPress) || (event->type == ButtonRelease)) + if (event->xbutton.button != Button1) + return; + + iw = tfImageWidth; /* avoid sign problems */ + ih = tfImageHeight; + + /* + * The grabX and grabY variables record where the user grabbed the image. + * They also record whether the mouse button is down or not. + */ + if (event->type == ButtonPress) { + grabX = event->xbutton.x; + grabY = event->xbutton.y; + return; + } + + /* + * imageWidget is a Core widget and doesn't get resized. + * So we calculate the size of its viewport here. + */ + XtSetArg(args[0], XtNwidth, &w_width); + XtSetArg(args[1], XtNheight, &w_height); + XtGetValues(shellWidget, args, 2); + ww = w_width; + wh = w_height; + XtGetValues(listWidget, args, 2); + wh -= w_height; + + switch (event->type) { + case Expose: + dx = event->xexpose.x; + dy = event->xexpose.y; + sx = dx + xOffset; + sy = dy + yOffset; + w = MIN(event->xexpose.width, iw); + h = MIN(event->xexpose.height, ih); + break; + case KeyPress: + if ((grabX >= 0) || (grabY >= 0)) /* Mouse button is still down */ + return; + switch (XLookupKeysym((XKeyEvent *) event, /* KeySyms index */ 0)) { + case XK_Up: + if (ih < wh) /* Don't scroll if the window fits the image. */ + return; + sy = yOffset + appData.translate; + sy = MIN(ih - wh, sy); + if (sy == yOffset) /* Filter redundant stationary refreshes. */ + return; + yOffset = sy; + sx = xOffset; + dx = dy = 0; + w = ww; h = wh; + break; + case XK_Down: + if (ih < wh) + return; + sy = yOffset - appData.translate; + sy = MAX(sy, 0); + if (sy == yOffset) + return; + yOffset = sy; + sx = xOffset; + dx = dy = 0; + w = ww; h = wh; + break; + case XK_Left: + if (iw < ww) + return; + sx = xOffset + appData.translate; + sx = MIN(iw - ww, sx); + if (sx == xOffset) + return; + xOffset = sx; + sy = yOffset; + dx = dy = 0; + w = ww; h = wh; + break; + case XK_Right: + if (iw < ww) + return; + sx = xOffset - appData.translate; + sx = MAX(sx, 0); + if (sx == xOffset) + return; + xOffset = sx; + sy = yOffset; + dx = dy = 0; + w = ww; h = wh; + break; + default: + return; + } + break; + case MotionNotify: + /* + * MotionEvent compression. Ignore multiple motion events. + * Ignore motion events if the mouse button is up. + */ + if (XPending(xDisplay)) /* Xlib doesn't flush the output buffer */ + if (XtPeekEvent(&next_event)) + if (next_event.type == MotionNotify) + return; + if ((grabX < 0) || (grabY < 0)) + return; + sx = xOffset + grabX - (int) event->xmotion.x; + if (sx >= (iw - ww)) /* clamp x motion but allow y motion */ + sx = iw - ww; + sx = MAX(sx, 0); + sy = yOffset + grabY - (int) event->xmotion.y; + if (sy >= (ih - wh)) /* clamp y motion but allow x motion */ + sy = ih - wh; + sy = MAX(sy, 0); + if ((sx == xOffset) && (sy == yOffset)) + return; + dx = dy = 0; + w = ww; h = wh; + break; + case ButtonRelease: + xOffset = xOffset + grabX - (int) event->xbutton.x; + xOffset = MIN(iw - ww, xOffset); + xOffset = MAX(xOffset, 0); + yOffset = yOffset + grabY - (int) event->xbutton.y; + yOffset = MIN(ih - wh, yOffset); + yOffset = MAX(yOffset, 0); + grabX = grabY = -1; + default: + return; + } + + if (appData.usePixmap == True) { + if (xImageDepth == 1) + XCopyPlane(xDisplay, xImagePixmap, XtWindow(widget), + xWinGc, sx, sy, w, h, dx, dy, 1); + else + XCopyArea(xDisplay, xImagePixmap, XtWindow(widget), + xWinGc, sx, sy, w, h, dx, dy); + } else + XPutImage(xDisplay, XtWindow(widget), xWinGc, xImage, + sx, sy, dx, dy, w, h); +} + +void +ResizeProc() +{ + Dimension w_width, w_height; + int xo, yo, ww, wh; + XEvent fake_event; + Arg args[2]; + + if ((xOffset == 0) && (yOffset == 0)) + return; + + XtSetArg(args[0], XtNwidth, &w_width); + XtSetArg(args[1], XtNheight, &w_height); + XtGetValues(shellWidget, args, 2); + ww = w_width; + wh = w_height; + XtGetValues(listWidget, args, 2); + wh -= w_height; + + xo = xOffset; yo = yOffset; + + if ((xOffset + ww) >= tfImageWidth) + xOffset = MAX((int) tfImageWidth - ww, 0); + if ((yOffset + wh) >= tfImageHeight) + yOffset = MAX((int) tfImageHeight - wh, 0); + + /* + * Send an ExposeEvent if the origin changed. + * We have to do this because of the use and semantics of bit gravity. + */ + if ((xo != xOffset) || (yo != yOffset)) { + fake_event.type = Expose; + fake_event.xexpose.x = fake_event.xexpose.y = 0; + fake_event.xexpose.width = tfImageWidth; + fake_event.xexpose.height = tfImageHeight; + EventProc(imageWidget, NULL, &fake_event); + } +} + +int +XTiffErrorHandler(display, error_event) + Display *display; + XErrorEvent *error_event; +{ + char message[80]; + + /* + * Some X servers limit the size of pixmaps. + */ + if ((error_event->error_code == BadAlloc) + && (error_event->request_code == X_CreatePixmap)) + fprintf(stderr, "xtiff: requested pixmap too big for display\n"); + else { + XGetErrorText(display, error_event->error_code, message, 80); + fprintf(stderr, "xtiff: error code %s\n", message); + } + + exit(0); +} + +void +Usage() +{ + fprintf(stderr, "Usage xtiff: [options] tiff-file\n"); + fprintf(stderr, "\tstandard Xt options\n"); + fprintf(stderr, "\t[-help]\n"); + fprintf(stderr, "\t[-gamma gamma]\n"); + fprintf(stderr, "\t[-usePixmap (True | False)]\n"); + fprintf(stderr, "\t[-viewportWidth pixels]\n"); + fprintf(stderr, "\t[-viewportHeight pixels]\n"); + fprintf(stderr, "\t[-translate pixels]\n"); + fprintf(stderr, "\t[-verbose (True | False)]\n"); + exit(0); +} diff --git a/contrib/dbs/xtiff/xtifficon.h b/contrib/dbs/xtiff/xtifficon.h new file mode 100644 index 00000000..8ee16674 --- /dev/null +++ b/contrib/dbs/xtiff/xtifficon.h @@ -0,0 +1,14 @@ +#define xtifficon_width 32 +#define xtifficon_height 32 +static char xtifficon_bits[] = { + 0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x7e, 0xc0, 0xfc, 0x03, 0x7e, 0x60, + 0xf8, 0x07, 0x06, 0x30, 0xf8, 0x07, 0x1e, 0x18, 0xf0, 0x0f, 0x1e, 0x0c, + 0xe0, 0x1f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x06, 0xc0, 0x3f, 0x06, 0x03, + 0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61, 0x00, + 0x00, 0xfe, 0x31, 0x7e, 0x7e, 0xfc, 0x33, 0x7e, 0x7e, 0xf8, 0x1b, 0x06, + 0x18, 0xf0, 0x0d, 0x1e, 0x18, 0xf0, 0x0e, 0x1e, 0x18, 0x60, 0x1f, 0x06, + 0x18, 0xb0, 0x3f, 0x06, 0x18, 0x98, 0x7f, 0x06, 0x18, 0x98, 0x7f, 0x00, + 0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x63, 0xfc, 0x03, + 0x80, 0x61, 0xfc, 0x03, 0xc0, 0x60, 0xf8, 0x07, 0xc0, 0x60, 0xf0, 0x0f, + 0x60, 0x60, 0xe0, 0x1f, 0x30, 0x60, 0xe0, 0x1f, 0x18, 0x60, 0xc0, 0x3f, + 0x0c, 0x60, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff}; diff --git a/contrib/dosdjgpp/Makefile.lib b/contrib/dosdjgpp/Makefile.lib new file mode 100644 index 00000000..28c7506d --- /dev/null +++ b/contrib/dosdjgpp/Makefile.lib @@ -0,0 +1,247 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/contrib/dosdjgpp/Attic/Makefile.lib,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# manually derived from Makefile.in for DJGPP v2.x (GNU C for DOS/386). +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1996 Sam Leffler +# Copyright (c) 1991-1996 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +SRCDIR = . + +NULL = +CC = gcc +AR = ar +AROPTS = rc +RANLIB = ranlib + +# +# If JPEG support is to be included and the Independent JPEG +# Software distribution is not installed then DIR_JPEG must +# refer to the directory where the include files reside. +# +# Similarly, if the libgz distribution is not installed, then +# DIR_LIBGZ must refer to the directory where the include files +# are located. Note that recent versions +# +IPATH = -I. -I${SRCDIR} +# @COPT_LIBINC@ +# +# To enable JPEG support include -DJPEG_SUPPORT here. +# To enable Deflate support add a -DZIP_SUPPORT here. +# Note that where the configure script is used these defines +# are automatically setup when JPEG/ZIP is set to "yes". +# +# Otherwise, consult tiffconf.h for information on controlling +# the configuration of optional library support. +# +CONF_LIBRARY=#@CONF_JPEG@ @CONF_ZIP@ +COPTS = +OPTIMIZER=-O +CFLAGS = ${COPTS} ${OPTIMIZER} ${IPATH} ${CONF_LIBRARY} +# +SRCS = \ + tif_aux.c \ + tif_close.c \ + tif_codec.c \ + tif_compress.c \ + tif_dir.c \ + tif_dirinfo.c \ + tif_dirread.c \ + tif_dirwrite.c \ + tif_dumpmode.c \ + tif_error.c \ + tif_fax3.c \ + tif_fx3s.c \ + tif_getimage.c \ + tif_jpeg.c \ + tif_flush.c \ + tif_lzw.c \ + tif_next.c \ + tif_open.c \ + tif_packbits.c \ + tif_predict.c \ + tif_print.c \ + tif_read.c \ + tif_swab.c \ + tif_strip.c \ + tif_thunder.c \ + tif_tile.c \ + tif_msdos.c \ + tif_version.c \ + tif_warning.c \ + tif_write.c \ + tif_zip.c \ + ${NULL} +OBJS = \ + tif_aux.o \ + tif_close.o \ + tif_codec.o \ + tif_compress.o \ + tif_dir.o \ + tif_dirinfo.o \ + tif_dirread.o \ + tif_dirwrite.o \ + tif_dumpmode.o \ + tif_error.o \ + tif_fax3.o \ + tif_fx3s.o \ + tif_getimage.o \ + tif_jpeg.o \ + tif_flush.o \ + tif_lzw.o \ + tif_next.o \ + tif_open.o \ + tif_packbits.o \ + tif_predict.o \ + tif_print.o \ + tif_read.o \ + tif_swab.o \ + tif_strip.o \ + tif_thunder.o \ + tif_tile.o \ + tif_msdos.o \ + tif_version.o \ + tif_warning.o \ + tif_write.o \ + tif_zip.o \ + ${NULL} +TARGETS = libtiff.a + +all: ${TARGETS} + +libtiff.a: ${OBJS} + ${AR} ${AROPTS} libtiff.a $? + ${RANLIB} libtiff.a + +${OBJS}: ${SRCDIR}/tiffio.h ${SRCDIR}/tiff.h ${SRCDIR}/tif_dir.h +${OBJS}: ${SRCDIR}/tiffcomp.h ${SRCDIR}/tiffiop.h ${SRCDIR}/tiffconf.h + +ALPHA = ../dist/tiff.alpha +VERSION = ../VERSION + +version.h: ${VERSION} ${ALPHA} ${SRCDIR}/mkversion.c + ${CC} -o mkversion ${CFLAGS} ${SRCDIR}/mkversion.c + del version.h + mkversion -v ${VERSION} -a ${ALPHA} version.h + +tif_version.o: version.h + +# +# The finite state machine tables used by the G3/G4 decoders +# are generated by the mkg3states program. On systems without +# make these rules have to be manually carried out. +# +# The file is called tif_fax3sm.c is the normal (unix) Makefile, but this +# may cause problems when compiling without support for LFN, then the file +# tif_fax3.o is considered the same name as tif_fax3sm.o, since only 8 chars +# are significant. +# +tif_fx3s.c: ${SRCDIR}/mkg3states.c ${SRCDIR}/tif_fax3.h + ${CC} -o mkg3states ${CFLAGS} ${SRCDIR}/mkg3states.c + del tif_fx3s.c + mkg3states -c const tif_fx3s.c + +tif_fx3s.o: tif_fx3s.c + @echo If the following gcc command fails due to lack of virtual memory, try + @echo compiling it in a non-DPMI environment with the cwsdpmi swapfile on a + @echo drive that has plenty of space. + ${CC} -c ${CFLAGS} tif_fx3s.c + +tif_aux.o: ${SRCDIR}/tif_aux.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_aux.c +tif_close.o: ${SRCDIR}/tif_close.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_close.c +tif_codec.o: ${SRCDIR}/tif_codec.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_codec.c +tif_compress.o: ${SRCDIR}/tif_compress.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_compress.c +tif_dir.o: ${SRCDIR}/tif_dir.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dir.c +tif_dirinfo.o: ${SRCDIR}/tif_dirinfo.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirinfo.c +tif_dirread.o: ${SRCDIR}/tif_dirread.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirread.c +tif_dirwrite.o: ${SRCDIR}/tif_dirwrite.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirwrite.c +tif_dumpmode.o: ${SRCDIR}/tif_dumpmode.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dumpmode.c +tif_error.o: ${SRCDIR}/tif_error.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_error.c +tif_fax3.o: ${SRCDIR}/tif_fax3.c ${SRCDIR}/t4.h ${SRCDIR}/tif_fax3.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_fax3.c +tif_getimage.o: ${SRCDIR}/tif_getimage.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_getimage.c +tif_jpeg.o: ${SRCDIR}/tif_jpeg.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_jpeg.c +tif_flush.o: ${SRCDIR}/tif_flush.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_flush.c +tif_lzw.o: ${SRCDIR}/tif_lzw.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_lzw.c +tif_next.o: ${SRCDIR}/tif_next.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_next.c +tif_open.o: ${SRCDIR}/tif_open.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_open.c +tif_packbits.o: ${SRCDIR}/tif_packbits.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_packbits.c +tif_predict.o: ${SRCDIR}/tif_predict.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_predict.c +tif_print.o: ${SRCDIR}/tif_print.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_print.c +tif_read.o: ${SRCDIR}/tif_read.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_read.c +tif_swab.o: ${SRCDIR}/tif_swab.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_swab.c +tif_strip.o: ${SRCDIR}/tif_strip.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_strip.c +tif_thunder.o: ${SRCDIR}/tif_thunder.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_thunder.c +tif_tile.o: ${SRCDIR}/tif_tile.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_tile.c +tif_unix.o: ${SRCDIR}/tif_unix.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_unix.c +tif_version.o: ${SRCDIR}/tif_version.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_version.c +tif_warning.o: ${SRCDIR}/tif_warning.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_warning.c +tif_write.o: ${SRCDIR}/tif_write.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_write.c +tif_zip.o: ${SRCDIR}/tif_zip.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_zip.c + +tif_apple.o: ${SRCDIR}/tif_apple.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_apple.c +tif_atari.o: ${SRCDIR}/tif_atari.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_atari.c +tif_msdos.o: ${SRCDIR}/tif_msdos.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_msdos.c +tif_vms.o: ${SRCDIR}/tif_vms.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_vms.c +tif_win3.o: ${SRCDIR}/tif_win3.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_win3.c + +INCS = ${SRCDIR}/tiff.h ${SRCDIR}/tiffio.h + +clean: + rm -f ${TARGETS} ${OBJS} mkg3states mkg3states.exe tif_fx3s.c + rm -f version.h libtiff.a mkversion mkversion.exe diff --git a/contrib/dosdjgpp/Makefile.tools b/contrib/dosdjgpp/Makefile.tools new file mode 100644 index 00000000..5a2d5791 --- /dev/null +++ b/contrib/dosdjgpp/Makefile.tools @@ -0,0 +1,217 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/contrib/dosdjgpp/Attic/Makefile.tools,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# manually derived from Makefile.in for DJGPP v2.x (GNU C for DOS/386). +# +# TIFF Library Tools +# +# Copyright (c) 1988-1996 Sam Leffler +# Copyright (c) 1991-1996 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +DEPTH = .. +SRCDIR = . +LIBDIR = ${DEPTH}/libtiff + +NULL = +CC = gcc +# +COPTS = +OPTIMIZER=-O +IPATH = -I. -I${SRCDIR} -I${LIBDIR} +CFLAGS = ${COPTS} ${OPTIMIZER} ${IPATH} +# +LIBTIFF = ${DEPTH}/libtiff/libtiff.a +LIBJPEG = #@LIBJPEG@ +LIBGZ = #@LIBGZ@ +LIBS = ${LIBTIFF} ${LIBJPEG} ${LIBGZ} +# +OBJS= \ + fax2tiff.o \ + fax2ps.o \ + gif2tiff.o \ + pal2rgb.o \ + ppm2tiff.o \ + rgb2ycbcr.o \ + ras2tiff.o \ + thumbnail.o \ + tiff2bw.o \ + tiff2ps.o \ + tiffcmp.o \ + tiffcp.o \ + tiffdither.o \ + tiffdump.o \ + tiffinfo.o \ + tiffmedian.o \ + tiffsplit.o \ + ${NULL} +TARGETS =\ + fax2tiff \ + fax2ps \ + gif2tiff \ + pal2rgb \ + ppm2tiff \ + rgb2ycbcr \ + thumbnail \ + ras2tiff \ + tiff2bw \ + tiff2ps \ + tiffcmp \ + tiffcp \ + tiffdither \ + tiffdump \ + tiffinfo \ + tiffmedian \ + tiffsplit \ + ${NULL} + +all: ${TARGETS} + +clean: + rm -f ${TARGETS} ${addsuffix .exe, ${TARGETS}} ${OBJS} + rm -f sgigt.o tiffgt sgisv.o tiffsv sgi2tiff.o sgi2tiff ycbcr + +# +# System-independent tools +# + +tiffinfo: tiffinfo.o ${LIBTIFF} + ${CC} -o tiffinfo ${CFLAGS} tiffinfo.o ${LIBS} +tiffinfo.o: ${SRCDIR}/tiffinfo.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffinfo.c + +tiffcmp:tiffcmp.o ${LIBTIFF} + ${CC} -o tiffcmp ${CFLAGS} tiffcmp.o ${LIBS} +tiffcmp.o: ${SRCDIR}/tiffcmp.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffcmp.c + +tiffcp: tiffcp.o ${LIBTIFF} + ${CC} -o tiffcp ${CFLAGS} tiffcp.o ${LIBS} +tiffcp.o: ${SRCDIR}/tiffcp.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffcp.c + +tiffdump: tiffdump.o + ${CC} -o tiffdump ${CFLAGS} tiffdump.o ${LIBS} +tiffdump.o: ${SRCDIR}/tiffdump.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffdump.c + +tiffmedian: tiffmedian.o ${LIBTIFF} + ${CC} -o tiffmedian ${CFLAGS} tiffmedian.o ${LIBS} +tiffmedian.o: ${SRCDIR}/tiffmedian.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffmedian.c + +tiffsplit: tiffsplit.o ${LIBTIFF} + ${CC} -o tiffsplit ${CFLAGS} tiffsplit.o ${LIBS} +tiffsplit.o: ${SRCDIR}/tiffsplit.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffsplit.c + +tiff2ps: tiff2ps.o ${LIBTIFF} + ${CC} -o tiff2ps ${CFLAGS} tiff2ps.o ${LIBS} +tiff2ps.o: ${SRCDIR}/tiff2ps.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiff2ps.c + +# +# Junky stuff... programs that are more examples of how +# to use the library than full-blown useful tools. +# + +# convert RGB image to B&W +tiff2bw: tiff2bw.o ${LIBTIFF} + ${CC} -o tiff2bw ${CFLAGS} tiff2bw.o ${LIBS} +tiff2bw.o: ${SRCDIR}/tiff2bw.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiff2bw.c + +# convert B&W image to bilevel w/ FS dithering +tiffdither: tiffdither.o ${LIBTIFF} + ${CC} -o tiffdither ${CFLAGS} tiffdither.o ${LIBS} +tiffdither.o: ${SRCDIR}/tiffdither.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffdither.c + +# simple Sun rasterfile converter +ras2tiff: ras2tiff.o ${LIBTIFF} + ${CC} -o ras2tiff ${CFLAGS} ras2tiff.o ${LIBS} +ras2tiff.o: ${SRCDIR}/ras2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/ras2tiff.c + +# simple GIF converter +gif2tiff: gif2tiff.o ${LIBTIFF} + ${CC} -o gif2tiff ${CFLAGS} gif2tiff.o ${LIBS} +gif2tiff.o: ${SRCDIR}/gif2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/gif2tiff.c + +# very limited PBM converter +ppm2tiff: ppm2tiff.o ${LIBTIFF} + ${CC} -o ppm2tiff ${CFLAGS} ppm2tiff.o ${LIBS} +ppm2tiff.o: ${SRCDIR}/ppm2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/ppm2tiff.c + +# Group 3/4 FAX file converter +fax2tiff: fax2tiff.o ${LIBTIFF} + ${CC} -o fax2tiff ${CFLAGS} fax2tiff.o ${LIBS} +fax2tiff.o: ${SRCDIR}/fax2tiff.c + ${CC} -c -I${LIBDIR} -I${DEPTH}/libtiff ${CFLAGS} ${SRCDIR}/fax2tiff.c + +# Group 3/4 FAX to encoded PS converter +fax2ps: fax2ps.o ${LIBTIFF} + ${CC} -o fax2ps ${CFLAGS} fax2ps.o ${LIBS} +fax2ps.o: ${SRCDIR}/fax2ps.c + ${CC} -c ${CFLAGS} ${SRCDIR}/fax2ps.c + +# convert Palette image to RGB +pal2rgb: pal2rgb.o ${LIBTIFF} + ${CC} -o pal2rgb ${CFLAGS} pal2rgb.o ${LIBS} +pal2rgb.o: ${SRCDIR}/pal2rgb.c + ${CC} -c ${CFLAGS} ${SRCDIR}/pal2rgb.c + +# convert RGB image to YCbCr +rgb2ycbcr: rgb2ycbcr.o ${LIBTIFF} + ${CC} -o rgb2ycbcr ${CFLAGS} rgb2ycbcr.o ${LIBS} +rgb2ycbcr.o: ${SRCDIR}/rgb2ycbcr.c + ${CC} -c ${CFLAGS} ${SRCDIR}/rgb2ycbcr.c + +# generate thumbnail images from fax (example of SubIFD usage) +thumbnail: thumbnail.o ${LIBTIFF} + ${CC} -o thumbnail ${CFLAGS} thumbnail.o ${LIBS} +thumbnail.o: ${SRCDIR}/thumbnail.c + ${CC} -c ${CFLAGS} ${SRCDIR}/thumbnail.c + +# +# System-specific tools. +# + +# +# sgi2tiff converts SGI RGB images to TIFF; it requires +# the SGI image library -limage. +# +sgi2tiff: sgi2tiff.o ${LIBTIFF} + ${CC} -o sgi2tiff ${CFLAGS} sgi2tiff.o -limage ${LIBS} +sgi2tiff.o: ${SRCDIR}/sgi2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgi2tiff.c + +# SGI versions of tiffgt & tiffsv that require -lgl +tiffgt: sgigt.o ${LIBTIFF} + ${CC} -o tiffgt ${CFLAGS} sgigt.o ${LIBS} -lgutil -lgl_s +sgigt.o: ${SRCDIR}/sgigt.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgigt.c + +tiffsv: sgisv.o ${LIBTIFF} + ${CC} -o tiffsv ${CFLAGS} sgisv.o ${LIBS} -lgutil -lgl_s +sgisv.o: ${SRCDIR}/sgisv.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgisv.c diff --git a/contrib/dosdjgpp/Makefile.top b/contrib/dosdjgpp/Makefile.top new file mode 100644 index 00000000..25b3d846 --- /dev/null +++ b/contrib/dosdjgpp/Makefile.top @@ -0,0 +1,54 @@ +#! smake +# $Header: /cvs/maptools/cvsroot/libtiff/contrib/dosdjgpp/Attic/Makefile.top,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# manually derived from Makefile.in (though basically nothing remains) +# for DJGPP v2.x (GNU C for DOS/386). +# +# A warning about the filename structure: +# +# Some of the filenames used in the Makefiles are longer than 8 characters +# this will work with the normal 8.3 file system since all files are unique +# in the first 8 chars. To compile under the long filename support in Win95 +# you can either extract the files with a program that truncates filenames +# (e.g. the DOS pkunzip) and disable LFN support with set LFN=n or with a +# program that supports long filenames (e.g. WinZip 6.0) and set LFN=y. +# The default environment in djgpp 2 is supposed to have LFN disabled, but +# due to a bug in the init code it doesn't work properly. Setting the LFN +# variable explicitly should fix that. +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1996 Sam Leffler +# Copyright (c) 1991-1996 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +SRCDIR = . + +all default: + @${MAKE} -C libtiff + @${MAKE} -C tools + +clean: + @${MAKE} -C libtiff clean + @${MAKE} -C tools clean + + diff --git a/contrib/dosdjgpp/README b/contrib/dosdjgpp/README new file mode 100644 index 00000000..e14d1bfc --- /dev/null +++ b/contrib/dosdjgpp/README @@ -0,0 +1,30 @@ + +This directory contains the files necessary to build the free TIFF library +with the DJGPP v2 compiler under MSDOS. Since DJGPP defines the unix flag, +I have created a port.h instead of putting the necessary defines into +tiffcomp.h. Makefiles are included for the top level and the libtiff and +tools directories. + +All you have to do is copy the files into the respective directories and run +make. If you want, you can use the conf.bat to do that for you, make sure that +the file is stored with MSDOS text EOL-convention (CR/LF), otherwise the +command.com will not do anything (if you used unzip, use the -a option, +otherwise edit the file and save it again). + +Note that you probably will not be able to built the library with the v1.x +versions of djgpp, due to two problems. First, the top makefile calls a +sub-make for each directory and you are likely to run out of memory, since +each recursive invocation of a djgpp v1.x program requires about 130k, to +avoid that, you can enter the directories manually and call make (well, there +are only two dirs). The 2nd problem is that djgpp 1.x doesn't call the +coff2exe (stubify) program when creating an executable. This means that all +programs compiled are not converted to exe and consequently are not available +for calling directly. For the tools directory, you can just call coff2exe for +each program after make finishes, but in the libtiff directory, a few programs +are created during the make process that have to be called for make to +continue (e.g. mkg3states). Make will probably report an error at each +such stage. To fix that, either add a coff2exe call before each program is +called or call coff2exe manually and rerun make (there 2-3 such programs). + +Alexander Lehmann + diff --git a/contrib/dosdjgpp/conf.bat b/contrib/dosdjgpp/conf.bat new file mode 100644 index 00000000..f28e12d3 --- /dev/null +++ b/contrib/dosdjgpp/conf.bat @@ -0,0 +1,11 @@ +@echo off +rem copy the Makefiles for libtiff for DJGPP2 into proper locations +rem we assume to be in $(top)/contrib/dosdjgpp/ + +copy Makefile.top ..\..\Makefile +copy Makefile.lib ..\..\libtiff\Makefile +copy port.h ..\..\libtiff\port.h +copy Makefile.too* ..\..\tools\Makefile + +echo all set for building the library. Now just do make +cd ..\.. diff --git a/contrib/dosdjgpp/port.h b/contrib/dosdjgpp/port.h new file mode 100644 index 00000000..4299c5e4 --- /dev/null +++ b/contrib/dosdjgpp/port.h @@ -0,0 +1,29 @@ +#ifndef _PORT_ +#define _PORT_ 1 +#ifdef __cplusplus +extern "C" { +#endif +#include +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +#define HOST_FILLORDER FILLORDER_LSB2MSB +#define HOST_BIGENDIAN 0 +#include +#include +#include +#include +#include +typedef double dblparam_t; +#ifdef __STRICT_ANSI__ +#define INLINE __inline__ +#else +#define INLINE inline +#endif +#define GLOBALDATA(TYPE,NAME) extern TYPE NAME +#ifdef __cplusplus +} +#endif +#endif diff --git a/contrib/iptcutil/Makefile b/contrib/iptcutil/Makefile new file mode 100644 index 00000000..e8aacda1 --- /dev/null +++ b/contrib/iptcutil/Makefile @@ -0,0 +1,12 @@ +CC=gcc +CFLAGS= +iptcutil: iptcutil.c + $(CC) $(CFLAGS) -o iptcutil iptcutil.c + +clean: + rm iptcutil *~ + +all: iptcutil + + + diff --git a/contrib/iptcutil/iptcutil.c b/contrib/iptcutil/iptcutil.c new file mode 100644 index 00000000..1ee68bb1 --- /dev/null +++ b/contrib/iptcutil/iptcutil.c @@ -0,0 +1,920 @@ +#include +#include +#include +#ifdef WIN32 +#include +#endif +#include +#include +#include + +#ifdef WIN32 +#define STRNICMP strnicmp +#else +#define STRNICMP strncasecmp +#endif + +typedef struct _tag_spec +{ + short + id; + + char + *name; +} tag_spec; + +static tag_spec tags[] = { + 5,"Image Name", + 7,"Edit Status", + 10,"Priority", + 15,"Category", + 20,"Supplemental Category", + 22,"Fixture Identifier", + 25,"Keyword", + 30,"Release Date", + 35,"Release Time", + 40,"Special Instructions", + 45,"Reference Service", + 47,"Reference Date", + 50,"Reference Number", + 55,"Created Date", + 60,"Created Time", + 65,"Originating Program", + 70,"Program Version", + 75,"Object Cycle", + 80,"Byline", + 85,"Byline Title", + 90,"City", + 95,"Province State", + 100,"Country Code", + 101,"Country", + 103,"Original Transmission Reference", + 105,"Headline", + 110,"Credit", + 115,"Source", + 116,"Copyright String", + 120,"Caption", + 121,"Local Caption", + 122,"Caption Writer", + 200,"Custom Field 1", + 201,"Custom Field 2", + 202,"Custom Field 3", + 203,"Custom Field 4", + 204,"Custom Field 5", + 205,"Custom Field 6", + 206,"Custom Field 7", + 207,"Custom Field 8", + 208,"Custom Field 9", + 209,"Custom Field 10", + 210,"Custom Field 11", + 211,"Custom Field 12", + 212,"Custom Field 13", + 213,"Custom Field 14", + 214,"Custom Field 15", + 215,"Custom Field 16", + 216,"Custom Field 17", + 217,"Custom Field 18", + 218,"Custom Field 19", + 219,"Custom Field 20" +}; + +/* + * We format the output using HTML conventions + * to preserve control characters and such. + */ +void formatString(FILE *ofile, const char *s, int len) +{ + putc('"', ofile); + for (; len > 0; --len, ++s) { + char c = *s; + switch (c) { + case '&': + fputs("&", ofile); + break; +#ifdef HANDLE_GT_LT + case '<': + fputs("<", ofile); + break; + case '>': + fputs(">", ofile); + break; +#endif + case '"': + fputs(""", ofile); + break; + default: + if (iscntrl(c)) + fprintf(ofile, "&#%d;", c); + else + putc(*s, ofile); + break; + } + } + fputs("\"\n", ofile); +} + +typedef struct _html_code +{ + short + len; + const char + *code, + val; +} html_code; + +static html_code html_codes[] = { +#ifdef HANDLE_GT_LT + 4,"<",'<', + 4,">",'>', +#endif + 5,"&",'&', + 6,""",'"' +}; + +/* + * This routine converts HTML escape sequence + * back to the original ASCII representation. + * - returns the number of characters dropped. + */ +int convertHTMLcodes(char *s, int len) +{ + if (len <=0 || s==(char*)NULL || *s=='\0') + return 0; + + if (s[1] == '#') + { + int val, o; + + if (sscanf(s,"&#%d;",&val) == 1) + { + o = 3; + while (s[o] != ';') + { + o++; + if (o > 5) + break; + } + if (o < 5) + strcpy(s+1, s+1+o); + *s = val; + return o; + } + } + else + { + int + i, + codes = sizeof(html_codes) / sizeof(html_code); + + for (i=0; i < codes; i++) + { + if (html_codes[i].len <= len) + if (STRNICMP(s, html_codes[i].code, html_codes[i].len) == 0) + { + strcpy(s+1, s+html_codes[i].len); + *s = html_codes[i].val; + return html_codes[i].len-1; + } + } + } +} + +int formatIPTC(FILE *ifile, FILE *ofile) +{ + unsigned int + foundiptc, + tagsfound; + + unsigned char + recnum, + dataset; + + unsigned char + *readable, + *str; + + long + tagindx, + taglen; + + int + i, + tagcount = sizeof(tags) / sizeof(tag_spec); + + char + c; + + foundiptc = 0; /* found the IPTC-Header */ + tagsfound = 0; /* number of tags found */ + + c = getc(ifile); + while (c != EOF) + { + if (c == 0x1c) + foundiptc = 1; + else + { + if (foundiptc) + return -1; + else + continue; + } + + /* we found the 0x1c tag and now grab the dataset and record number tags */ + dataset = getc(ifile); + if ((char) dataset == EOF) + return -1; + recnum = getc(ifile); + if ((char) recnum == EOF) + return -1; + /* try to match this record to one of the ones in our named table */ + for (i=0; i< tagcount; i++) + { + if (tags[i].id == recnum) + break; + } + if (i < tagcount) + readable = tags[i].name; + else + readable = ""; + + /* then we decode the length of the block that follows - long or short fmt */ + c = getc(ifile); + if (c == EOF) + return 0; + if (c & (unsigned char) 0x80) + { + unsigned char + buffer[4]; + + for (i=0; i<4; i++) + { + c = buffer[i] = getc(ifile); + if (c == EOF) + return -1; + } + taglen = (((long) buffer[ 0 ]) << 24) | + (((long) buffer[ 1 ]) << 16) | + (((long) buffer[ 2 ]) << 8) | + (((long) buffer[ 3 ])); + } + else + { + unsigned char + x = c; + + taglen = ((long) x) << 8; + x = getc(ifile); + if ((char)x == EOF) + return -1; + taglen |= (long) x; + } + /* make a buffer to hold the tag data and snag it from the input stream */ + str=(unsigned char *) malloc((unsigned int) (taglen+1)); + if (str == (unsigned char *) NULL) + { + printf("Memory allocation failed"); + return 0; + } + for (tagindx=0; tagindx 0) + fprintf(ofile, "%d#%d#%s=",(unsigned int)dataset, (unsigned int) recnum, readable); + else + fprintf(ofile, "%d#%d=",(unsigned int)dataset, (unsigned int) recnum); + formatString( ofile, str, taglen ); + free(str); + + tagsfound++; + + c = getc(ifile); + } + return tagsfound; +} + +int tokenizer(unsigned inflag,char *token,int tokmax,char *line, +char *white,char *brkchar,char *quote,char eschar,char *brkused, +int *next,char *quoted); + +char *super_fgets(char *b, int *blen, FILE *file) +{ + int + c, + len; + + unsigned char + *q; + + len=*blen; + for (q=b; ; q++) + { + c=fgetc(file); + if (c == EOF || c == '\n') + break; + if (((int)q - (int)b + 1 ) >= (int) len) + { + int + tlen; + + tlen=(int)q-(int)b; + len<<=1; + b=(unsigned char *) realloc((char *) b,(len+2)); + if ((unsigned char *) b == (unsigned char *) NULL) + break; + q=b+tlen; + } + *q=(unsigned char) c; + } + *blen=0; + if ((unsigned char *)b != (unsigned char *) NULL) + { + int + tlen; + + tlen=(int)q - (int)b; + if (tlen == 0) + return (char *) NULL; + b[tlen] = '\0'; + *blen=++tlen; + } + return b; +} + +#define BUFFER_SZ 4096 + +int main(int argc, char *argv[]) +{ + unsigned int + length; + + unsigned char + *buffer; + + int + i, + mode; /* iptc binary, or iptc text */ + + FILE + *ifile = stdin, + *ofile = stdout; + + char + c, + *usage = "usage: iptcutil -t | -b [-i file] [-o file] output"; + + if( argc < 2 ) + { + printf(usage); + return 1; + } + + mode = 0; + length = -1; + buffer = (unsigned char *)NULL; + + for (i=1; i 0) + { + char + *s = &token[next-1]; + + len -= convertHTMLcodes(s, strlen(s)); + } + } + + fputc(0x1c, ofile); + fputc(dataset, ofile); + fputc(recnum, ofile); + if (len < 0x10000) + { + fputc((len >> 8) & 255, ofile); + fputc(len & 255, ofile); + } + else + { + fputc(((len >> 24) & 255) | 0x80, ofile); + fputc((len >> 16) & 255, ofile); + fputc((len >> 8) & 255, ofile); + fputc(len & 255, ofile); + } + next=0; + while (len--) + fputc(token[next++], ofile); + } + state++; + } + free(token); + token = (char *)NULL; + free(newstr); + newstr = (char *)NULL; + } + free(line); + + fclose( ifile ); + fclose( ofile ); + } + + return 0; +} + +/* + This routine is a generalized, finite state token parser. It allows + you extract tokens one at a time from a string of characters. The + characters used for white space, for break characters, and for quotes + can be specified. Also, characters in the string can be preceded by + a specifiable escape character which removes any special meaning the + character may have. + + There are a lot of formal parameters in this subroutine call, but + once you get familiar with them, this routine is fairly easy to use. + "#define" macros can be used to generate simpler looking calls for + commonly used applications of this routine. + + First, some terminology: + + token: used here, a single unit of information in + the form of a group of characters. + + white space: space that gets ignored (except within quotes + or when escaped), like blanks and tabs. in + addition, white space terminates a non-quoted + token. + + break character: a character that separates non-quoted tokens. + commas are a common break character. the + usage of break characters to signal the end + of a token is the same as that of white space, + except multiple break characters with nothing + or only white space between generate a null + token for each two break characters together. + + for example, if blank is set to be the white + space and comma is set to be the break + character, the line ... + + A, B, C , , DEF + + ... consists of 5 tokens: + + 1) "A" + 2) "B" + 3) "C" + 4) "" (the null string) + 5) "DEF" + + quote character: a character that, when surrounding a group + of other characters, causes the group of + characters to be treated as a single token, + no matter how many white spaces or break + characters exist in the group. also, a + token always terminates after the closing + quote. for example, if ' is the quote + character, blank is white space, and comma + is the break character, the following + string ... + + A, ' B, CD'EF GHI + + ... consists of 4 tokens: + + 1) "A" + 2) " B, CD" (note the blanks & comma) + 3) "EF" + 4) "GHI" + + the quote characters themselves do + not appear in the resultant tokens. the + double quotes are delimiters i use here for + documentation purposes only. + + escape character: a character which itself is ignored but + which causes the next character to be + used as is. ^ and \ are often used as + escape characters. an escape in the last + position of the string gets treated as a + "normal" (i.e., non-quote, non-white, + non-break, and non-escape) character. + for example, assume white space, break + character, and quote are the same as in the + above examples, and further, assume that + ^ is the escape character. then, in the + string ... + + ABC, ' DEF ^' GH' I ^ J K^ L ^ + + ... there are 7 tokens: + + 1) "ABC" + 2) " DEF ' GH" + 3) "I" + 4) " " (a lone blank) + 5) "J" + 6) "K L" + 7) "^" (passed as is at end of line) + + + OK, now that you have this background, here's how to call "tokenizer": + + result=tokenizer(flag,token,maxtok,string,white,break,quote,escape, + brkused,next,quoted) + + result: 0 if we haven't reached EOS (end of string), and + 1 if we have (this is an "int"). + + flag: right now, only the low order 3 bits are used. + 1 => convert non-quoted tokens to upper case + 2 => convert non-quoted tokens to lower case + 0 => do not convert non-quoted tokens + (this is a "char"). + + token: a character string containing the returned next token + (this is a "char[]"). + + maxtok: the maximum size of "token". characters beyond + "maxtok" are truncated (this is an "int"). + + string: the string to be parsed (this is a "char[]"). + + white: a string of the valid white spaces. example: + + char whitesp[]={" \t"}; + + blank and tab will be valid white space (this is + a "char[]"). + + break: a string of the valid break characters. example: + + char breakch[]={";,"}; + + semicolon and comma will be valid break characters + (this is a "char[]"). + + IMPORTANT: do not use the name "break" as a C + variable, as this is a reserved word in C. + + quote: a string of the valid quote characters. an example + would be + + char whitesp[]={"'\""); + + (this causes single and double quotes to be valid) + note that a token starting with one of these characters + needs the same quote character to terminate it. + + for example, + + "ABC ' + + is unterminated, but + + "DEF" and 'GHI' + + are properly terminated. note that different quote + characters can appear on the same line; only for + a given token do the quote characters have to be + the same (this is a "char[]"). + + escape: the escape character (NOT a string ... only one + allowed). use zero if none is desired (this is + a "char"). + + brkused: the break character used to terminate the current + token. if the token was quoted, this will be the + quote used. if the token is the last one on the + line, this will be zero (this is a pointer to a + "char"). + + next: this variable points to the first character of the + next token. it gets reset by "tokenizer" as it steps + through the string. set it to 0 upon initialization, + and leave it alone after that. you can change it + if you want to jump around in the string or re-parse + from the beginning, but be careful (this is a + pointer to an "int"). + + quoted: set to 1 (true) if the token was quoted and 0 (false) + if not. you may need this information (for example: + in C, a string with quotes around it is a character + string, while one without is an identifier). + + (this is a pointer to a "char"). +*/ + +/* states */ + +#define IN_WHITE 0 +#define IN_TOKEN 1 +#define IN_QUOTE 2 +#define IN_OZONE 3 + +int _p_state; /* current state */ +unsigned _p_flag; /* option flag */ +char _p_curquote; /* current quote char */ +int _p_tokpos; /* current token pos */ + +/* routine to find character in string ... used only by "tokenizer" */ + +int sindex(char ch,char *string) +{ + char *cp; + for(cp=string;*cp;++cp) + if(ch==*cp) + return (int)(cp-string); /* return postion of character */ + return -1; /* eol ... no match found */ +} + +/* routine to store a character in a string ... used only by "tokenizer" */ + +void chstore(char *string,int max,char ch) +{ + char c; + if(_p_tokpos>=0&&_p_tokpos=0) /* break */ + { + switch(_p_state) + { + case IN_WHITE: /* these are the same here ... */ + case IN_TOKEN: /* ... just get out */ + case IN_OZONE: /* ditto */ + ++(*next); + *brkused=brkchar[qp]; + goto byebye; + + case IN_QUOTE: /* just keep going */ + chstore(token,tokmax,c); + break; + } + } + else if((qp=sindex(c,quote))>=0) /* quote */ + { + switch(_p_state) + { + case IN_WHITE: /* these are identical, */ + _p_state=IN_QUOTE; /* change states */ + _p_curquote=quote[qp]; /* save quote char */ + *quoted=1; /* set to true as long as something is in quotes */ + break; + + case IN_QUOTE: + if(quote[qp]==_p_curquote) /* same as the beginning quote? */ + { + _p_state=IN_OZONE; + _p_curquote=0; + } + else + chstore(token,tokmax,c); /* treat as regular char */ + break; + + case IN_TOKEN: + case IN_OZONE: + *brkused=c; /* uses quote as break char */ + goto byebye; + } + } + else if((qp=sindex(c,white))>=0) /* white */ + { + switch(_p_state) + { + case IN_WHITE: + case IN_OZONE: + break; /* keep going */ + + case IN_TOKEN: + _p_state=IN_OZONE; + break; + + case IN_QUOTE: + chstore(token,tokmax,c); /* it's valid here */ + break; + } + } + else if(c==eschar) /* escape */ + { + nc=line[(*next)+1]; + if(nc==0) /* end of line */ + { + *brkused=0; + chstore(token,tokmax,c); + ++(*next); + goto byebye; + } + switch(_p_state) + { + case IN_WHITE: + --(*next); + _p_state=IN_TOKEN; + break; + + case IN_TOKEN: + case IN_QUOTE: + ++(*next); + chstore(token,tokmax,nc); + break; + + case IN_OZONE: + goto byebye; + } + } + else /* anything else is just a real character */ + { + switch(_p_state) + { + case IN_WHITE: + _p_state=IN_TOKEN; /* switch states */ + + case IN_TOKEN: /* these 2 are */ + case IN_QUOTE: /* identical here */ + chstore(token,tokmax,c); + break; + + case IN_OZONE: + goto byebye; + } + } + } /* end of main loop */ + +byebye: + token[_p_tokpos]=0; /* make sure token ends with EOS */ + + return 0; +} diff --git a/contrib/iptcutil/test.iptc b/contrib/iptcutil/test.iptc new file mode 100644 index 0000000000000000000000000000000000000000..a2605622ecf1e8eb7906378b3f7ae7196244d538 GIT binary patch literal 1107 zcmdT@&2G~`5Z-L43Plw?a6wwZNL-Le)1*ylQ*m+aBzArr6FV)fDxrv;ZE1Oc+dku=zqT=r5u) zOli3UljnIVC1W+PS)l^9f|<7T^k+}v+A34V>9Hdg1YeiQr#^#grj>Y*T+kXqh*pBI|kI%u4l zR;Syuo&I1ra>w3>i62bQ&OcsULUaG1b@=Y+xUJfGXvZ_A!-u>Ho}#KBbO|m{RgFim zfp$hTw3xVo37hj$vXWr2{<(oRr~a;eVRZ;TddU0|ZJisw?YO;Q>=OJ5Vap_#q3x;b z1RV?fzz8}%!PjWRGL6Oo!Ou|D8xIM7j<$N^v(CgFb=-j9EmS!q_yu~TRnx|kzshN^ z%Cks+H`fXhJU|sn@cVz1>!OYQdZVszz9W2~fPWy|J0Bqy6USn!AanfpmHv+Xv^CbivPQYgw3#EWvxVjoR?uFqxSL+!156^G&1qdGi literal 0 HcmV?d00001 diff --git a/contrib/iptcutil/test.txt b/contrib/iptcutil/test.txt new file mode 100644 index 00000000..d5181004 --- /dev/null +++ b/contrib/iptcutil/test.txt @@ -0,0 +1,32 @@ +2#0="�" +2#120#Caption="Chairman of the US House Judiciary Committee, Henry Hyde,R-IL, makes his opening statement during impeachment hearings 11 December on Capitol Hill in Washington, DC. The committee is debating the articles of impechment and my take a vote on the impeachment of US President BIll Clinton on charges that he obstucted justice, lied and abused the power of his office as early as today. AFP PHOTO Paul J. RICHARDS " +2#122#Caption Writer="kb/lt" +2#100#Country Code="USA" +2#105#Headline="Old fart squeezing two fingers." +2#30#Release Date="19981211" +2#35#Release Time="000000+0000" +2#40#Special Instructions="This is a test. This is only a test. ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890" +2#80#Byline="PAUL J. RICHARDS" +2#85#Byline Title="STF" +2#110#Credit="AFP" +2#65#Originating Program="MacDesk Reporter" +2#115#Source="AFP" +2#5#Image Name="US-HYDE" +2#55#Created Date="19981211" +2#90#City="WASHINGTON" +2#95#Province State="DC" +2#101#Country="UNITED STATES" +2#103#Original Transmission Reference="DCA03" +2#15#Category="POL" +2#20#Supplemental Category="GOVERNMENT" +2#10#Priority="5" +2#25#Keyword="fart" +2#25#Keyword="squeezing" +2#25#Keyword="old" +2#25#Keyword="fingers" +2#75#Object Cycle="a" +2#60#Created Time="000000+0000" +2#70#Program Version="2.0.3" +2#130="3S" +2#135="GB" +2#231="Kaya A. Hoffmann 12/14/98 12:00:44 PM Copy To : Selects - \\KINYANI\Selects������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������" diff --git a/contrib/mac-cw/Makefile.script b/contrib/mac-cw/Makefile.script new file mode 100644 index 00000000..85614c81 --- /dev/null +++ b/contrib/mac-cw/Makefile.script @@ -0,0 +1,72 @@ + +(* You must manually set the top-level PATHNAME here; everything else is automatic *) + +set PATHNAME to "ritter:tiff-v3.4beta028:" +set PRINTING to "NO" + +set MKG3STATES to PATHNAME & "mkg3states.mw" +set LIBTIFF to PATHNAME & "libtiff-68K.mw" +set TIFFINFO to PATHNAME & "tiffinfo.mw" + +with timeout of 60000 seconds + tell application "MW C/C++ 68K 1.2.2" + + activate + + + (* Create tif_fax3sm.c file *) + Create Project {file MKG3STATES} + Add Files {"mkg3states.c", "mkg3_main.c", "getopt.c"} + Add Files {"MacOS.lib"} To Segment 2 + Add Files {"ANSI (4i/8d) C.68K.Lib"} To Segment 3 + Add Files {"SIOUX.68K.Lib"} To Segment 4 + Add Files {"MathLib68K (4i/8d).Lib"} To Segment 5 + + Set Preferences To {Activate CPlusPlus:false, ARM Conformance:false, ANSI Keywords Only:false, Require Function Prototypes:false, Expand Trigraph Sequences:false, Enums Always Ints:false, MPW Pointer Type Rules:false, Prefix File:"mac_main.h"} + Set Preferences To {Illegal Pragmas:false, Empty Declarations:false, Possible Errors:false, Unused Variables:false, Unused Arguments:false, Extra Commas:false, Extended Error Checking:false} + Set Preferences To {Code Model:2, Struct Alignment:0, MC68020 CodeGen:false, MC68881 CodeGen:false, Four Bytes Ints:true, Eight Byte Double:true, Peephole Optimizer:true, CSE Optimizer:true, Optimize For Size:true, Far Data:true, Use Profiler:false, Far Virtual Function Tables:false, Far String Constants:true} + Set Preferences To {MacsBug Symbols:2, Generate SYM File:false, Full Path In Sym Files:true, Generate Link Map:false, Generate A6 Stack Frames:true, The Debugger Aware:false, Link Single Segment:false, Fast Link:true} + Set Preferences To {Project Type:0, File Name:"mkg3states", File Creator:"????", File Type:"APPL"} + + Make Project + Run Project + Remove Binaries + Close Project + + + (* Create LIBTIFF *) + Create Project {file LIBTIFF} + Add Files {"tif_apple.c", "tif_aux.c", "tif_close.c", "tif_codec.c", "tif_compress.c", "tif_dumpmode.c", "tif_error.c", "tif_flush.c", "tif_lzw.c", "tif_next.c", "tif_open.c", "tif_packbits.c"} + Add Files {"tif_fax3.c"} To Segment 2 + Add Files {"tif_dirinfo.c", "tif_dir.c", "tif_dirwrite.c", "tif_dirread.c"} To Segment 3 + Add Files {"tif_predict.c", "tif_print.c", "tif_read.c", "tif_strip.c", "tif_swab.c", "tif_thunder.c", "tif_tile.c", "tif_version.c", "tif_zip.c", "tif_jpeg.c", "tif_warning.c", "tif_write.c"} To Segment 4 + Add Files {"tif_fax3sm.c"} To Segment 5 + Add Files {"tif_getimage.c"} To Segment 6 + + Set Preferences To {Activate CPlusPlus:false, ARM Conformance:false, ANSI Keywords Only:false, Require Function Prototypes:false, Expand Trigraph Sequences:false, Enums Always Ints:false, MPW Pointer Type Rules:false, Prefix File:"MacHeaders68K"} + Set Preferences To {Illegal Pragmas:false, Empty Declarations:false, Possible Errors:false, Unused Variables:false, Unused Arguments:false, Extra Commas:false, Extended Error Checking:false} + Set Preferences To {Code Model:2, Struct Alignment:0, MC68020 CodeGen:false, MC68881 CodeGen:false, Four Bytes Ints:true, Eight Byte Double:true, Peephole Optimizer:true, CSE Optimizer:true, Optimize For Size:true, Far Data:true, Use Profiler:false, Far Virtual Function Tables:false, Far String Constants:true} + Set Preferences To {MacsBug Symbols:2, Generate SYM File:true, Full Path In Sym Files:true, Generate Link Map:false, Generate A6 Stack Frames:true, The Debugger Aware:false, Link Single Segment:false, Fast Link:true} + Set Preferences To {Project Type:2, File Name:"libtiff-68K", File Creator:"????", File Type:"APPL"} + Make Project + Close Project + + Create Project {file TIFFINFO} + Add Files {"tiffinfo.c", "mac_main.c", "getopt.c"} + Add Files {"MacOS.lib"} To Segment 2 + Add Files {"ANSI (4i/8d) C.68K.Lib"} To Segment 3 + Add Files {"SIOUX.68K.Lib"} To Segment 4 + Add Files {"MathLib68K (4i/8d).Lib"} To Segment 5 + Add Files {"libtiff-68K"} To Segment 6 + + Set Preferences To {Activate CPlusPlus:false, ARM Conformance:false, ANSI Keywords Only:false, Require Function Prototypes:false, Expand Trigraph Sequences:false, Enums Always Ints:false, MPW Pointer Type Rules:false, Prefix File:"mac_main.h"} + Set Preferences To {Illegal Pragmas:false, Empty Declarations:false, Possible Errors:false, Unused Variables:false, Unused Arguments:false, Extra Commas:false, Extended Error Checking:false} + Set Preferences To {Code Model:2, Struct Alignment:0, MC68020 CodeGen:false, MC68881 CodeGen:false, Four Bytes Ints:true, Eight Byte Double:true, Peephole Optimizer:true, CSE Optimizer:true, Optimize For Size:true, Far Data:true, Use Profiler:false, Far Virtual Function Tables:false, Far String Constants:true} + Set Preferences To {MacsBug Symbols:2, Generate SYM File:false, Full Path In Sym Files:true, Generate Link Map:false, Generate A6 Stack Frames:true, The Debugger Aware:false, Link Single Segment:false, Fast Link:true} + Set Preferences To {Project Type:0, File Name:"tiffinfo", File Creator:"????", File Type:"APPL"} + + Make Project + Close Project + + end tell +end timeout diff --git a/contrib/mac-cw/README b/contrib/mac-cw/README new file mode 100644 index 00000000..a9734694 --- /dev/null +++ b/contrib/mac-cw/README @@ -0,0 +1,18 @@ +---------------------------------------------------- +Build instructions for LIBTIFF - CodeWarrior (6.1): +---------------------------------------------------- + +In this directory you will find a Makefile.script Applescript +file, which should be run in order to build the libtiff code +using MetroWerks CodeWarrior. + +Refer to the "metrowerks.note" instructions on building the +library for 68k and PowerPC native code, as well as building +some of the libtiff tools, which are rather unix-like, but +at least give an example of how to link everything together. + + Questions, comments, bug reports to Niles Ritter + (ndr@tazboy.jpl.nasa.gov). Sam Leffler takes no responsibility + for the viability of this stuff. + + -Niles. diff --git a/contrib/mac-cw/mac_main.c b/contrib/mac-cw/mac_main.c new file mode 100644 index 00000000..294655de --- /dev/null +++ b/contrib/mac-cw/mac_main.c @@ -0,0 +1,20 @@ +/* + * mac_main.c -- The REAL entry point which + * calls the tools main code. For the tools + * the symbol "main" has been #defined to "tool_main" + * so that this entry point may be used to access + * the user-input first. + */ + +#undef main + +int +main() +{ + int argc; + char **argv; + + argc=ccommand(&argv); + + return tool_main(argc,argv); // Call the tool "main()" routine +} diff --git a/contrib/mac-cw/mac_main.h b/contrib/mac-cw/mac_main.h new file mode 100644 index 00000000..523300f7 --- /dev/null +++ b/contrib/mac-cw/mac_main.h @@ -0,0 +1,12 @@ +/* + * mac_main.h -- redefines main entry point + */ + +#ifndef _mac_main_h +#define _mac_main_h + +#undef main +#define main tool_main + +#endif /* _mac_main_h */ + diff --git a/contrib/mac-cw/metrowerks.note b/contrib/mac-cw/metrowerks.note new file mode 100644 index 00000000..9917cfd5 --- /dev/null +++ b/contrib/mac-cw/metrowerks.note @@ -0,0 +1,84 @@ +---------------------------------------------------- +Build instructions for LIBTIFF - CodeWarrior (6.1): +---------------------------------------------------- + +Note: there is a bug in CW earlier than 6.1 which will generate +16-bit offset link errors for any projects using libtiff; you must +download the CodeWarrior 6.1 patch located at: + + ftp://ftp.metrowerks.com/pub/updates/metro-patches-61.hqx + +unpack the archive, insert the files and recompile the libraries +using the AppleScript provided. + + +1. Make sure that the directory containing these files is under + the "contrib" directory of the tiff folder; otherwise, some + access path preferences will need to be updated. + +2. The instructions below are for the 68k platform build. + A similar script can be put together for the PPC version, + or you can just directly convert the projects. Be sure to + use the native libraries as well. NOTE: if anyone cooks + up an equivalent script for PPC, send it to me and I'll include + it with the rest of the package. + +3. Open the file Makefile.script with an AppleScript Editor + and change the PATHNAME variable to point to your + top-level TIFF directory + +4. Run the Script. It will do the following things: + + 4a. Prompt you for the current location of the CodeWarrior 68K + program. + + 4b. Create the source file "tif_fax3sm.c": + + i) Build the project CW project mkg3states.cw. It will + produce a small program called mkg3states. Only a + 68k version is provided, since you only have to run + this code once, and it only takes a few seconds. + + ii) Run the built mkg3states program: + + The program will temporarily take over ALL of the CPU, so + don't panic. After a few seconds it will produce a file called + "tif_fax3sm.c". + + 4c. Build the library project libtiff-68K.mw, producing library + called libtiff-68K. + + 4d. Build program project tiffinfo.mw; it will produce a + program called tiffinfo, which can dump the tiff tags of + a named file. Passing in no arguments will dump a help file + for the program. It is unix-flavored, but hey, it works. + +5 When the script finishes, you will have a usable libtiff-68K + library, a passable "tiffinfo" program, and the projects used + to build them. Note that to get tiffinfo to work I have put + an include file in the project that redefines main(), and + then have a mac_main.c program that calls ccommand() first + and passes that to the actual main code. A real mac app, + of course, would never use this stuff at all... + + . The tiffinfo.mw project may be used as a template to build + most of the other libtiff tools, or your own code. When + modifying a copy of the project, you will most likely need + to update the "Access Paths" directory if it is moved out of + the contrib folder. + +6. If you are going to create a project from scratch, be sure + to set up the preferences with + + 4-byte ints + 8-byte doubles + Far Code/Far Data + Large Linking model + + and everything should work fine. If the console-style error + reports bother you, you can always override the error and + warning mechanism with TIFFSetErrorHandler to do something + more Mac-like. + +Questions, comments to Niles Ritter (ndr@tazboy.jpl.nasa.gov). + diff --git a/contrib/mac-cw/mkg3_main.c b/contrib/mac-cw/mkg3_main.c new file mode 100644 index 00000000..b31c8d10 --- /dev/null +++ b/contrib/mac-cw/mkg3_main.c @@ -0,0 +1,14 @@ +/* + * mkg3_main.c -- passes fake arguments into main + */ + +#undef main + +int +main() +{ + static char *argv[4] = { + "mkg3states", "-c", "const", "tif_fax3sm.c" }; + + return tool_main(4,argv); // Call the tool "main()" routine +} diff --git a/contrib/mac-cw/version.h b/contrib/mac-cw/version.h new file mode 100644 index 00000000..3c5c56e1 --- /dev/null +++ b/contrib/mac-cw/version.h @@ -0,0 +1,4 @@ +#define VERSION \ +"LIBTIFF, Version 3.4beta028 \n"\ +"Copyright (c) 1988-1995 Sam Leffler\n"\ +"Copyright (c) 1991-1996 Silicon Graphics, Inc." diff --git a/contrib/mac-mpw/BUILD.mpw b/contrib/mac-mpw/BUILD.mpw new file mode 100644 index 00000000..7abf83a2 --- /dev/null +++ b/contrib/mac-mpw/BUILD.mpw @@ -0,0 +1,47 @@ +# BUILD.mpw: +# +# Full build for Apple Macintosh Programmer's Workshop (MPW). +# +# This is an executable MPW script which creates various +# utilities, sets up the MPW makefiles and runs the builds. +# This script should be run at the top level TIFF directory with: +# +# directory ::: +# :contrib:mac-mpw:BUILD.mpw +# +# NOTE: The full build requires that MPW have at least 6 MB +# allocated to it to compile the CCITT Fax codec tables. To +# deactivate CCITT compression edit the file :contrib:mac:libtiff.make +# first and follow the directions for disabling Fax decoding. +# +# All TIFF tools are built as MPW tools, executable from the +# MPW shell or other compatible tool server. +# +# Written by: Niles Ritter (ndr@tazboy.jpl.nasa.gov). +# + +echo "############# Full Scratch Build for MPW #############" + +# Create the ascii->mpw translation tool; this is used to +# convert standard ASCII files into ones using the special +# MPW characters, which don't live comfortably in unix tar files. +# +echo "######## Creating ASCII->MPW translator ########" +set contrib ':contrib:mac-mpw:' +directory {contrib} +createmake -tool mactrans mactrans.c > dev:null +make -f mactrans.make | streamedit -e "/CSANELib/||/Math/||/ToolLibs/ del" > mactrans.bld +execute mactrans.bld > dev:null +delete -y mactrans.make mactrans.bld mactrans.c.o || set status 0 +directory ::: #An mpw trick for going up two levels + +# Create the top-level Makefile and run it +echo "######## Creating Makefile ########" +catenate {contrib}top.make | {contrib}mactrans > Makefile + +echo "######## Running Makefile ########" +make > build.mpw +execute build.mpw +echo "############# MPW Build Complete #############" +exit 0 + diff --git a/contrib/mac-mpw/README b/contrib/mac-mpw/README new file mode 100644 index 00000000..053b0d0c --- /dev/null +++ b/contrib/mac-mpw/README @@ -0,0 +1,20 @@ +###################### +About contrib:mac-mpw: +###################### + +This directory contains all of the utilities and makefile source +to build the LIBTIFF library and tools from the MPW Shell. The +file BUILD.mpw in this directory is an executable script +which uses all of these files to create the MPW makefiles and +run them. + +The .make files are not MPW makefiles as such, +but are when run through the "mactrans" program, which turns +the ascii "%nn" metacharacters into the standard weird MPW +make characters. + +This translation trick is necessary to protect the files when +they are put into unix tarfiles, which tend to mangle the +special characters. + + --Niles Ritter (ndr@tazboy.jpl.nasa.gov) diff --git a/contrib/mac-mpw/libtiff.make b/contrib/mac-mpw/libtiff.make new file mode 100644 index 00000000..ee5296e3 --- /dev/null +++ b/contrib/mac-mpw/libtiff.make @@ -0,0 +1,202 @@ +# +# Tag Image File Format Library +# +# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 Sam Leffler +# Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# +# Makefile for Mac using MPW 3.3.1 and MPW C 3.2.4 +# +# Note: This file must be run through "mactrans" before it can +# be recognized by MPW as a valid makefile. The problem is that MPW +# uses special non-ASCII characters, which tend to get mangled when stored +# in unix tar files, etc. "mactrans" is built as part of the TIFF MPW build. +# +# + +DEPTH = :: + +# FAX Options: If you do not wish to include the FAX options, uncomment +# the first four definitions and comment out the next four +# definitions. Note that to build programs with the FAX libraries you +# have to include "-model far" in your compile and link statements. +# +# Also, to build the fax code (including the tif_fax3sm.c file, which is +# created by the MPW tool "mkg3states", also built below), you will +# need to size the MPW program up to about 6 megabytes or so. + +#FAX_OPTIONS = +#FAX_OBJECTS = +#FAX_SOURCES = tif_fax3.c +#FAX_CONFIG = + +FAX_OPTIONS = -model far +FAX_OBJECTS = tif_fax3.c.o tif_fax3sm.c.o +FAX_SOURCES = tif_fax3.c tif_fax3sm.c +FAX_CONFIG = -d CCITT_SUPPORT + +NULL= + +RM = delete -y -i +COPTS = + +LIBPORT=::port:libport.o + +# +.c.o %c4 .c + {C} -model far {CFLAGS} -s {Default} {DepDir}{Default}.c -o {TargDir}{Default}.c.o + + +CONF_LIBRARY= %b6 + -d HAVE_IEEEFP=1 %b6 + -d BSDTYPES + +CONF_COMPRESSION= %b6 + {FAX_CONFIG} %b6 + -d COMPRESSION_SUPPORT %b6 + -d PACKBITS_SUPPORT %b6 + -d LZW_SUPPORT %b6 + -d THUNDER_SUPPORT %b6 + -d NEXT_SUPPORT + +CFLAGS= {FAX_OPTIONS} {IPATH} {CONF_LIBRARY} {CONF_COMPRESSION} + +INCS= tiff.h tiffio.h + +SRCS= %b6 + {FAX_SOURCES} %b6 + tif_apple.c %b6 + tif_aux.c %b6 + tif_close.c %b6 + tif_codec.c %b6 + tif_compress.c %b6 + tif_dir.c %b6 + tif_dirinfo.c %b6 + tif_dirread.c %b6 + tif_dirwrite.c %b6 + tif_dumpmode.c %b6 + tif_error.c %b6 + tif_getimage.c %b6 + tif_jpeg.c %b6 + tif_flush.c %b6 + tif_lzw.c %b6 + tif_next.c %b6 + tif_open.c %b6 + tif_packbits.c %b6 + tif_predict.c %b6 + tif_print.c %b6 + tif_read.c %b6 + tif_swab.c %b6 + tif_strip.c %b6 + tif_thunder.c %b6 + tif_tile.c %b6 + tif_version.c %b6 + tif_warning.c %b6 + tif_write.c %b6 + tif_zip.c %b6 + {NULL} + +OBJS= %b6 + {FAX_OBJECTS} %b6 + tif_apple.c.o %b6 + tif_aux.c.o %b6 + tif_close.c.o %b6 + tif_codec.c.o %b6 + tif_compress.c.o %b6 + tif_dir.c.o %b6 + tif_dirinfo.c.o %b6 + tif_dirread.c.o %b6 + tif_dirwrite.c.o %b6 + tif_dumpmode.c.o %b6 + tif_error.c.o %b6 + tif_getimage.c.o %b6 + tif_jpeg.c.o %b6 + tif_flush.c.o %b6 + tif_lzw.c.o %b6 + tif_next.c.o %b6 + tif_open.c.o %b6 + tif_packbits.c.o %b6 + tif_predict.c.o %b6 + tif_print.c.o %b6 + tif_read.c.o %b6 + tif_swab.c.o %b6 + tif_strip.c.o %b6 + tif_thunder.c.o %b6 + tif_tile.c.o %b6 + tif_version.c.o %b6 + tif_warning.c.o %b6 + tif_write.c.o %b6 + tif_zip.c.o %b6 + {NULL} + +ALL=libtiff.o + +all %c4 {ALL} + +libtiff.o %c4 {OBJS} + Lib {OBJS} -o libtiff.o + + +{OBJS} %c4 tiffio.h tiff.h tiffcomp.h tiffiop.h tiffconf.h + +# +# The finite state machine tables used by the G3/G4 decoders +# are generated by the mkg3states program. On systems without +# make these rules have to be manually carried out. +# +tif_fax3sm.c %c4 mkg3states tif_fax3.h + {RM} tif_fax3sm.c || set status 0 + :mkg3states -c const tif_fax3sm.c + +mkg3states.c.o %c4 mkg3states.c + C -model far mkg3states.c -o mkg3states.c.o + +mkg3states %c4%c4 mkg3states.c.o + Link -model far -d -c 'MPS ' -t MPST %b6 + mkg3states.c.o %b6 + {LIBPORT} %b6 + "{CLibraries}"StdClib.o %b6 + "{Libraries}"Stubs.o %b6 + "{Libraries}"Runtime.o %b6 + "{Libraries}"Interface.o %b6 + -o mkg3states + +ALPHA = "{DEPTH}dist:tiff.alpha" +VERSION = "{DEPTH}VERSION" + +version.h %c4 {VERSION} {ALPHA} + Set VERSION1 `catenate {VERSION}` + Set VERSION2 "{VERSION1}`streamedit -e "1 rep /%a5%c5 %c5 (%c5)%a81/ %a81" {ALPHA}`" + delete -y -i version.h || set status 0 + echo '#define VERSION "LIBTIFF, Version' {VERSION2} '\nCopyright (c) 1988-1995 Sam Leffler\nCopyright (c) 1991-1995 Silicon Graphics, Inc."' >version.h + +tif_version.c.o %c4 version.h + +clean %c4 + {RM} {ALL} || set status 0 + {RM} {OBJS} || set status 0 + {RM} mkg3states || set status 0 + {RM} mkg3states.c.o || set status 0 + {RM} tif_fax3sm.c%c5 || set status 0 + {RM} version.h || set status 0 + diff --git a/contrib/mac-mpw/mactrans.c b/contrib/mac-mpw/mactrans.c new file mode 100644 index 00000000..5e321b90 --- /dev/null +++ b/contrib/mac-mpw/mactrans.c @@ -0,0 +1,56 @@ +/* + * mactrans.c -- Hack filter used to generate MPW files + * with special characters from pure ASCII, denoted "%nn" + * where nn is hex. (except for "%%", which is literal '%'). + * + * calling sequence: + * + * catenate file | mactrans [-toascii | -fromascii] > output + * + * Written by: Niles Ritter. + */ +#include +#include +#include + +void to_ascii(void); +void from_ascii(void); + +main(int argc, char *argv[]) +{ + if (argc<2 || argv[1][1]=='f') from_ascii(); + else to_ascii(); + exit (0); +} + +void from_ascii(void) +{ + char c; + int d; + while ((c=getchar())!=EOF) + { + if (c!='%' || (c=getchar())=='%') putchar(c); + else + { + ungetc(c,stdin); + scanf("%2x",&d); + *((unsigned char *)&c) = d; + putchar(c); + } + } +} + +void to_ascii(void) +{ + char c; + int d; + while ((c=getchar())!=EOF) + { + if (isascii(c)) putchar (c); + else + { + d = *((unsigned char *)&c); + printf("%%%2x",d); + } + } +} diff --git a/contrib/mac-mpw/port.make b/contrib/mac-mpw/port.make new file mode 100644 index 00000000..492c527e --- /dev/null +++ b/contrib/mac-mpw/port.make @@ -0,0 +1,53 @@ +# +# Tag Image File Format Library +# +# Copyright (c) 1995 Sam Leffler +# Copyright (c) 1995 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +DEPTH= :: +SRCDIR= : + +NULL = +CC = C +AR = Lib +AROPTS = +RM= delete -y + +IPATH = -I {DEPTH} -I {SRCDIR} +COPTS = +OPTIMIZER= +CFLAGS = {COPTS} {OPTIMIZER} {IPATH} + +CFILES = +OBJECTS = getopt.c.o +TARGETS = libport.o + +.c.o %c4 .c + {CC} -model far {COptions} {CFLAGS} -s {Default} {DepDir}{Default}.c -o {TargDir}{Default}.c.o + +all %c4 {TARGETS} + +libport.o %c4 {OBJECTS} + {AR} {OBJECTS} -o libport.o + +clean %c4 + {RM} {TARGETS} {OBJECTS} || set status 0 diff --git a/contrib/mac-mpw/tools.make b/contrib/mac-mpw/tools.make new file mode 100644 index 00000000..13b14e42 --- /dev/null +++ b/contrib/mac-mpw/tools.make @@ -0,0 +1,138 @@ +# +# Tag Image File Format Library +# +# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 Sam Leffler +# Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# +# Makefile for Mac using MPW 3.2.3 and MPW C 3.2.4 +# +COPTS = -model far + +.c.o %c4 .c + {C} {COPTS} {CFLAGS} -s {Default} {DepDir}{Default}.c -o {TargDir}{Default}.c.o + +RM = delete -y -i + +CONF_LIBRARY= %b6 + -d USE_CONST=0 %b6 + -d BSDTYPES +NULL= + +IPATH= -I ::libtiff + +CFLAGS= -w -m {IPATH} {CONF_LIBRARY} + +LIBPORT= ::port:libport.o + +LOptions= -model far -w -srt -d -c 'MPS ' -t MPST + +LIBTIFF= ::libtiff:libtiff.o + +LIBS= {LIBTIFF} %b6 + {LIBPORT} %b6 + "{CLibraries}"CSANELib.o %b6 + "{CLibraries}"Math.o %b6 + "{CLibraries}"StdClib.o %b6 + "{Libraries}"Stubs.o %b6 + "{Libraries}"Runtime.o %b6 + "{Libraries}"Interface.o %b6 + "{Libraries}"ToolLibs.o %b6 + {NULL} + +SRCS= %b6 + pal2rgb.c %b6 + ras2tiff.c %b6 + thumbnail.c %b6 + tiff2bw.c %b6 + tiff2ps.c %b6 + tiffcmp.c %b6 + tiffcp.c %b6 + tiffdither.c %b6 + tiffdump.c %b6 + tiffinfo.c %b6 + tiffmedian.c %b6 + {NULL} + +MACHALL=ras2tiff + +ALL= %b6 + tiffinfo %b6 + tiffcmp %b6 + tiffcp %b6 + tiffdump %b6 + tiffmedian %b6 + tiff2bw %b6 + tiffdither %b6 + tiff2ps %b6 + pal2rgb %b6 + gif2tiff %b6 + {MACHALL} + +all %c4 {ALL} + +tiffinfo %c4 tiffinfo.c.o {LIBTIFF} + Link {LOptions} tiffinfo.c.o {LIBS} -o tiffinfo + +tiffcmp %c4 tiffcmp.c.o {LIBTIFF} + Link {LOptions} tiffcmp.c.o {LIBS} -o tiffcmp + +tiffcp %c4 tiffcp.c.o {LIBTIFF} + Link {LOptions} tiffcp.c.o {LIBS} -o tiffcp + +tiffdump %c4 tiffdump.c.o {LIBTIFF} + Link {LOptions} tiffdump.c.o {LIBS} -o tiffdump + +tiffmedian %c4 tiffmedian.c.o {LIBTIFF} + Link {LOptions} tiffmedian.c.o {LIBS} -o tiffmedian + +tiff2ps %c4 tiff2ps.c.o {LIBTIFF} + Link {LOptions} tiff2ps.c.o {LIBS} -o tiff2ps + +# junky stuff... +# convert RGB image to B&W +tiff2bw %c4 tiff2bw.c.o {LIBTIFF} + Link {LOptions} tiff2bw.c.o {LIBS} -o tiff2bw + +# convert B&W image to bilevel w/ FS dithering +tiffdither %c4 tiffdither.c.o {LIBTIFF} + Link {LOptions} tiffdither.c.o {LIBS} -o tiffdither + +# GIF converter +gif2tiff %c4 gif2tiff.c.o {LIBTIFF} + Link {LOptions} gif2tiff.c.o {LIBS} -o gif2tiff + +# convert Palette image to RGB +pal2rgb %c4 pal2rgb.c.o {LIBTIFF} + Link {LOptions} pal2rgb.c.o {LIBS} -o pal2rgb + +# Sun rasterfile converter +ras2tiff %c4 ras2tiff.c.o {LIBTIFF} + Link {LOptions} ras2tiff.c.o {LIBS} -o ras2tiff + +# generate thumbnail images from fax +thumbnail %c4 thumbnail.c.o {LIBTIFF} + Link {LOptions} thumbnail.c.o {LIBS} -o thumbnail + +clean %c4 + {RM} {ALL} %c5.c.o ycbcr diff --git a/contrib/mac-mpw/top.make b/contrib/mac-mpw/top.make new file mode 100644 index 00000000..5a6a29b4 --- /dev/null +++ b/contrib/mac-mpw/top.make @@ -0,0 +1,133 @@ +# +# Tag Image File Format Library +# +# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 Sam Leffler +# Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# +# Makefile for Mac using MPW 3.2.3 and MPW C 3.2.4 +# +# +# Written by: Niles D. Ritter +# + +RM= delete -y -i +PORT=:port: +LIBTIFF=:libtiff: +TOOLS=:tools: +CONTRIB=:contrib:mac-mpw: + +MACTRANS="{CONTRIB}mactrans" + +NULL= + +MAKEFILES = %b6 + {PORT}Makefile %b6 + {LIBTIFF}Makefile %b6 + {TOOLS}Makefile %b6 + {NULL} + +all %c4 PORT LIBTIFF TOOLS + +MAKEFILES %c4 {MAKEFILES} +TOOLS %c4 LIBTIFF + +LIBTIFF %c4 PORT + +# Create the port routines +PORT %c4 {PORT}Makefile + directory {PORT} + (make || set status 0) > build.mpw + set echo 1 + execute build.mpw + set echo 0 + {RM} build.mpw || set status 0 + directory :: + +# Create the port routines +LIBTIFF %c4 {LIBTIFF}Makefile + directory {LIBTIFF} + (make || set status 0) > build.mpw + set echo 1 + execute build.mpw + set echo 0 + {RM} build.mpw || set status 0 + directory :: + +# Create the tools +TOOLS %c4 {TOOLS}Makefile + directory {TOOLS} + (make || set status 0) > build.mpw + set echo 1 + execute build.mpw + set echo 0 + {RM} build.mpw || set status 0 + directory :: + +# Makefile dependencies +{PORT}Makefile %c4 {CONTRIB}port.make + catenate {CONTRIB}port.make | {MACTRANS} > {PORT}Makefile + +{LIBTIFF}Makefile %c4 {CONTRIB}libtiff.make + catenate {CONTRIB}libtiff.make | {MACTRANS} > {LIBTIFF}Makefile + +{TOOLS}Makefile %c4 {CONTRIB}tools.make + catenate {CONTRIB}tools.make | {MACTRANS} > {TOOLS}Makefile + + +clean %c4 clean.port clean.contrib clean.libtiff clean.tools clean.make + +clean.port %c4 + directory {PORT} + (make clean || set status 0) > purge + purge + {RM} purge || set status 0 + {RM} Makefile || set status 0 + {RM} build.mpw || set status 0 + cd :: + +clean.contrib %c4 + {RM} {MACTRANS} || set status 0 + +clean.libtiff %c4 + directory {LIBTIFF} + (make clean || set status 0) > purge + purge + {RM} purge || set status 0 + {RM} Makefile || set status 0 + {RM} build.mpw || set status 0 + cd :: + +clean.tools %c4 + directory {TOOLS} + (make clean || set status 0) > purge + purge + {RM} purge || set status 0 + {RM} Makefile || set status 0 + {RM} build.mpw || set status 0 + cd :: + +clean.make %c4 + {RM} {MAKEFILES} || set status 0 + {RM} build.mpw || set status 0 + diff --git a/contrib/mfs/README b/contrib/mfs/README new file mode 100644 index 00000000..6f9befbc --- /dev/null +++ b/contrib/mfs/README @@ -0,0 +1,37 @@ +Date: Mon, 23 Jun 1997 13:30:48 +0200 +To: + +From: "Mike Johnson" +Subject: libtiff - Thanks + +Return-Path: mikehunt@swipnet.se +Delivery-Date: Mon, 23 Jun 1997 06:53:39 -0700 + +Hi Sam, + +I noticed in the README from libtiff that you would like to know about +what people have done with libtiff, so I thought I would drop you a +line. + +We have used libtiff to create and convert TIFF images of financial +documents which are sent from and to major document processing systems +in Sweden and Denmark. + +I would like to express my deep gratitude to yourself and Sillicon +Graphics for making this excellent library available for public use. +There is obviously a lot of work that has gone in to libtiff and the +quality of the code and documentation is an example to others. + +One thing that libtiff did not do was work on a memory area rather than +files. In my applications I had already read a TIFF or other format +file in to memory and did not want to waste I/O writing it out again +for libtiff's benefit. I therefore constructed a set of functions to +pass up to TIFFClientOpen to simulate a file in memory. I have attached +my mfs (memory file system) source code for you to use or junk, as you +see fit. :-) + +Once again, thanks very much for making my life simpler. + +Best Regards, + +Mike Johnson. diff --git a/contrib/mfs/mfs_file.c b/contrib/mfs/mfs_file.c new file mode 100644 index 00000000..fa408dab --- /dev/null +++ b/contrib/mfs/mfs_file.c @@ -0,0 +1,579 @@ +/* +-------------------------------------------------------------------------------- +- Module : mem_file.c +- Description : A general purpose library for manipulating a memory area +- as if it were a file. +- mfs_ stands for memory file system. +- Author : Mike Johnson - Banctec AB 03/07/96 +- +-------------------------------------------------------------------------------- +*/ + +/* + +Copyright (c) 1996 Mike Johnson +Copyright (c) 1996 BancTec AB + +Permission to use, copy, modify, distribute, and sell this software +for any purpose is hereby granted without fee, provided +that (i) the above copyright notices and this permission notice appear in +all copies of the software and related documentation, and (ii) the names of +Mike Johnson and BancTec may not be used in any advertising or +publicity relating to the software. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL MIKE JOHNSON OR BANCTEC BE LIABLE FOR +ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. + +*/ + + +/* +-------------------------------------------------------------------------------- +- Includes +-------------------------------------------------------------------------------- +*/ + +#include +#include +#include + +/* +-------------------------------------------------------------------------------- +- Definitions +-------------------------------------------------------------------------------- +*/ + +#define MAX_BUFFS 20 +#define FALSE 0 +#define TRUE 1 + +/* +-------------------------------------------------------------------------------- +- Globals +-------------------------------------------------------------------------------- +*/ + +static char *buf[MAX_BUFFS]; /* Memory for each open buf */ +static long buf_off[MAX_BUFFS]; /* File pointer for each buf */ +static long buf_size[MAX_BUFFS]; /* Count of bytes allocated for each buf */ +static long fds[MAX_BUFFS]; /* File descriptor status */ +static int buf_mode[MAX_BUFFS]; /* Mode of buffer (r, w, a) */ + +static int library_init_done = FALSE; + + +/* +-------------------------------------------------------------------------------- +- Function prototypes +-------------------------------------------------------------------------------- +*/ + +int mfs_open (void *ptr, int size, char *mode); +int mfs_lseek (int fd, int offset, int whence); +int mfs_read (int fd, void *buf, int size); +int mfs_write (int fd, void *buf, int size); +int mfs_size (int fd); +int mfs_map (int fd, char **addr, size_t *len); +int mfs_unmap (int fd); +int mfs_close (int fd); +static int extend_mem_file (int fd, int size); +static void mem_init (); + +/* +-------------------------------------------------------------------------------- +- Function code +-------------------------------------------------------------------------------- +*/ + +/* +-------------------------------------------------------------------------------- +- Function : mfs_open () +- +- Arguments : Pointer to allocated buffer, initial size of buffer, +- mode spec (r, w, a) +- +- Returns : File descriptor or -1 if error. +- +- Description : Register this area of memory (which has been allocated +- and has a file read into it) under the mem_file library. +- A file descriptor is returned which can the be passed +- back to TIFFClientOpen and used as if it was a disk +- based fd. +- If the call is for mode 'w' then pass (void *)NULL as +- the buffer and zero size and the library will +- allocate memory for you. +- If the mode is append then pass (void *)NULL and size +- zero or with a valid address. +- +-------------------------------------------------------------------------------- +*/ + +int mfs_open (void *buffer, int size, char *mode) +{ + int ret, i; + void *tmp; + + if (library_init_done == FALSE) + { + mem_init (); + library_init_done = TRUE; + } + + ret = -1; + + /* Find a free fd */ + + for (i = 0; i < MAX_BUFFS; i++) + { + if (fds[i] == -1) + { + ret = i; + break; + } + } + + if (i == MAX_BUFFS) /* No more free descriptors */ + { + ret = -1; + errno = EMFILE; + } + + if (ret >= 0 && *mode == 'r') + { + if (buffer == (void *)NULL) + { + ret = -1; + errno = EINVAL; + } + else + { + buf[ret] = (char *)buffer; + buf_size[ret] = size; + buf_off[ret] = 0; + } + } + else if (ret >= 0 && *mode == 'w') + { + + if (buffer != (void *)NULL) + { + ret = -1; + errno = EINVAL; + } + + else + { + tmp = malloc (0); /* Get a pointer */ + if (tmp == (void *)NULL) + { + ret = -1; + errno = EDQUOT; + } + else + { + buf[ret] = (char *)tmp; + buf_size[ret] = 0; + buf_off[ret] = 0; + } + } + } + else if (ret >= 0 && *mode == 'a') + { + if (buffer == (void *) NULL) /* Create space for client */ + { + tmp = malloc (0); /* Get a pointer */ + if (tmp == (void *)NULL) + { + ret = -1; + errno = EDQUOT; + } + else + { + buf[ret] = (char *)tmp; + buf_size[ret] = 0; + buf_off[ret] = 0; + } + } + else /* Client has file read in already */ + { + buf[ret] = (char *)buffer; + buf_size[ret] = size; + buf_off[ret] = 0; + } + } + else /* Some other invalid combination of parameters */ + { + ret = -1; + errno = EINVAL; + } + + if (ret != -1) + { + fds[ret] = 0; + buf_mode[ret] = *mode; + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_lseek () +- +- Arguments : File descriptor, offset, whence +- +- Returns : as per man lseek (2) +- +- Description : Does the same as lseek (2) except on a memory based file. +- Note: the memory area will be extended if the caller +- attempts to seek past the current end of file (memory). +- +-------------------------------------------------------------------------------- +*/ + +int mfs_lseek (int fd, int offset, int whence) +{ + int ret; + long test_off; + + if (fds[fd] == -1) /* Not open */ + { + ret = -1; + errno = EBADF; + } + else if (offset < 0 && whence == SEEK_SET) + { + ret = -1; + errno = EINVAL; + } + else + { + switch (whence) + { + case SEEK_SET: + if (offset > buf_size[fd]) + extend_mem_file (fd, offset); + buf_off[fd] = offset; + ret = offset; + break; + + case SEEK_CUR: + test_off = buf_off[fd] + offset; + + if (test_off < 0) + { + ret = -1; + errno = EINVAL; + } + else + { + if (test_off > buf_size[fd]) + extend_mem_file (fd, test_off); + buf_off[fd] = test_off; + ret = test_off; + } + break; + + case SEEK_END: + test_off = buf_size[fd] + offset; + + if (test_off < 0) + { + ret = -1; + errno = EINVAL; + } + else + { + if (test_off > buf_size[fd]) + extend_mem_file (fd, test_off); + buf_off[fd] = test_off; + ret = test_off; + } + break; + + default: + errno = EINVAL; + ret = -1; + break; + } + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_read () +- +- Arguments : File descriptor, buffer, size +- +- Returns : as per man read (2) +- +- Description : Does the same as read (2) except on a memory based file. +- Note: An attempt to read past the end of memory currently +- allocated to the file will return 0 (End Of File) +- +-------------------------------------------------------------------------------- +*/ + +int mfs_read (int fd, void *clnt_buf, int size) +{ + int ret; + + if (fds[fd] == -1 || buf_mode[fd] != 'r') + { + /* File is either not open, or not opened for read */ + + ret = -1; + errno = EBADF; + } + else if (buf_off[fd] + size > buf_size[fd]) + { + ret = 0; /* EOF */ + } + else + { + memcpy (clnt_buf, (void *) (buf[fd] + buf_off[fd]), size); + buf_off[fd] = buf_off[fd] + size; + ret = size; + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_write () +- +- Arguments : File descriptor, buffer, size +- +- Returns : as per man write (2) +- +- Description : Does the same as write (2) except on a memory based file. +- Note: the memory area will be extended if the caller +- attempts to write past the current end of file (memory). +- +-------------------------------------------------------------------------------- +*/ + +int mfs_write (int fd, void *clnt_buf, int size) +{ + int ret; + + if (fds[fd] == -1 || buf_mode[fd] == 'r') + { + /* Either the file is not open or it is opened for reading only */ + + ret = -1; + errno = EBADF; + } + else if (buf_mode[fd] == 'w') + { + /* Write */ + + if (buf_off[fd] + size > buf_size[fd]) + { + extend_mem_file (fd, buf_off[fd] + size); + buf_size[fd] = (buf_off[fd] + size); + } + + memcpy ((buf[fd] + buf_off[fd]), clnt_buf, size); + buf_off[fd] = buf_off[fd] + size; + + ret = size; + } + else + { + /* Append */ + + if (buf_off[fd] != buf_size[fd]) + buf_off[fd] = buf_size[fd]; + + extend_mem_file (fd, buf_off[fd] + size); + buf_size[fd] += size; + + memcpy ((buf[fd] + buf_off[fd]), clnt_buf, size); + buf_off[fd] = buf_off[fd] + size; + + ret = size; + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_size () +- +- Arguments : File descriptor +- +- Returns : integer file size +- +- Description : This function returns the current size of the file in bytes. +- +-------------------------------------------------------------------------------- +*/ + +int mfs_size (int fd) +{ + int ret; + + if (fds[fd] == -1) /* Not open */ + { + ret = -1; + errno = EBADF; + } + else + ret = buf_size[fd]; + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_map () +- +- Arguments : File descriptor, ptr to address, ptr to length +- +- Returns : Map status (succeeded or otherwise) +- +- Description : This function tells the client where the file is mapped +- in memory and what size the mapped area is. It is provided +- to satisfy the MapProc function in libtiff. It pretends +- that the file has been mmap (2)ped. +- +-------------------------------------------------------------------------------- +*/ + +int mfs_map (int fd, char **addr, size_t *len) +{ + int ret; + + if (fds[fd] == -1) /* Not open */ + { + ret = -1; + errno = EBADF; + } + else + { + *addr = buf[fd]; + *len = buf_size[fd]; + ret = 0; + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_unmap () +- +- Arguments : File descriptor +- +- Returns : UnMap status (succeeded or otherwise) +- +- Description : This function does nothing as the file is always +- in memory. +- +-------------------------------------------------------------------------------- +*/ + +int mfs_unmap (int fd) +{ + return (0); +} + +/* +-------------------------------------------------------------------------------- +- Function : mfs_close () +- +- Arguments : File descriptor +- +- Returns : close status (succeeded or otherwise) +- +- Description : Close the open memory file. (Make fd available again.) +- +-------------------------------------------------------------------------------- +*/ + +int mfs_close (int fd) +{ + int ret; + + if (fds[fd] == -1) /* Not open */ + { + ret = -1; + errno = EBADF; + } + else + { + fds[fd] = -1; + ret = 0; + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : extend_mem_file () +- +- Arguments : File descriptor, length to extend to. +- +- Returns : 0 - All OK, -1 - realloc () failed. +- +- Description : Increase the amount of memory allocated to a file. +- +-------------------------------------------------------------------------------- +*/ + +static int extend_mem_file (int fd, int size) +{ + void *new_mem; + int ret; + + if ((new_mem = realloc (buf[fd], size)) == (void *) NULL) + ret = -1; + else + { + buf[fd] = (char *) new_mem; + ret = 0; + } + + return (ret); +} + +/* +-------------------------------------------------------------------------------- +- Function : mem_init () +- +- Arguments : None +- +- Returns : void +- +- Description : Initialise the library. +- +-------------------------------------------------------------------------------- +*/ + +static void mem_init () +{ + int i; + + for (i = 0; i < MAX_BUFFS; i++) + { + fds[i] = -1; + buf[i] = (char *)NULL; + buf_size[i] = 0; + buf_off[i] = 0; + } +} + diff --git a/contrib/pds/README b/contrib/pds/README new file mode 100644 index 00000000..b9abc6b3 --- /dev/null +++ b/contrib/pds/README @@ -0,0 +1,90 @@ +Date: Fri, 01 Aug 1997 20:14:52 MDT +To: Sam Leffler + +From: "Conrad J. Poelman (WSAT)" +Subject: Potential TIFF library additions + +Delivery-Date: Fri, 01 Aug 1997 19:21:06 -0700 + +Sam, + +You probably don't remember me, but I sent in a couple of bug fixes +regarding the TIFF library about a 16 months ago or so... + +I just wanted to send you two other additions that I have made to our +local version of the TIFF library in hopes that you will want to +incorporate them into your next major release of the TIFF library. +(These additions are based on TIFF version 3.4beta31, but they sit on +top of the library so they shouldn't be much trouble to incorporate them +into any more recent version.) They are internally documented to a +reasonable extent and we've been successfully using them in our code +here for over a year. If you think they would make good additions to the +TIFF library, I'd be happy to clean them up more, document them more, +and/or integrate them with the latest version of the TIFF library, but I +figured I'd see if you were interested in using them before I went to +all that trouble. + +TIFF Image Iterator +------------------- +Your ReadRGBA() routine works well for reading many different formats +(TILED, STIP, compressed or not, etc.) of the most basic types of data +(RGB, 8-bit greyscale, 8-bit colormapped) into an SGI-style data array, +and serves as a good template for users with other needs. I used it as +an exmaple of how to make an iterator which, rather than fill a data +array, calls an arbitrary user-supplied callback function for each +"chunk" of data - that "chunk" might be a strip or a tile, and might +have one sample-per-pixel or two, and might be 8-bit data or 16-bit or +24-bit. The callback function can do whatever it wants with the data - +store it in a big array, convert it to RGBA, or draw it directly to the +screen. I was able to use this iterator to read 16-bit greyscale and 32- +and 64-bit floating point data, which wasn't possible with ReadRGBA(). + +I have tested this routine with 8- and 16-bit greyscale data as well as +with 32- and 64-bit floating point data. I believe nearly all of our +data is organized in strips, so actually I'd appreciate it if you had +some tiled images that I could test it with. + +It should certainly be possible and would be cleanest to reimplement +ReadRGBA() in terms of the image iterator, but I haven't done that. + + +Private Sub-Directory Read/Write +-------------------------------- +TIFF-PL is a Phillips Laboratory extension to the TIFF tags that allows +us to store satellite imaging-specific information in a TIFF format, +such as the satellite's trajectory, the imaging time, etc. In order to +give us the flexibility to modify the tag definitions without getting +approval from the TIFF committee every time, we were given only three +TIFF tags - a PL signature, a PL version number, and PL directory +offset, which lists the position in the file at which to find a private +sub-directory of tags-value pairs. So I wrote two routines: +TIFFWritePrivateDataSubDirectory(), which takes a list of tags and a +"get" function and writes the tag values into the TIFF file, returning +the offset within the file at which it wrote the directory; and +TIFFReadPrivateDataSubDirectory(), which takes an offset, a list of +tags, and a "set" function and reads all the data from the private +directory. The functions themselves are pretty simple. (The files are +huge because I had to basically copy all of the tif_dirread.c and +tif_dirwrite.c files in order to access the various fetching routines +which were all declared static and therefore inaccessible in the TIFF +library.) + + +I'm including the four source files (tif_imgiter.h, tif_imgiter.c, +tif_pdsdirread.c, tif_pdsdirwrite.c) in case you want to take a look at +them. I can also send you some sample code that uses them if you like. +If you're interested in having them incorporated into the standard TIFF +library, I'd be happy to do that integration and clean up and document +the routines. (For example, I've already realized that instead of +limiting the SEP callback function to three bands (R,G,B) it should take +an array to enable the handling of n-banded multi-spectral data...) If +not, I'll just leave them as they are, since they work fine for us now. + +Holler if you have any questions. + +-- Conrad +__________________________________________________________________ + Capt Conrad J. Poelman PL/WSAT (Phillips Laboratory) + 505-846-4347 3550 Aberdeen Ave SE + (FAX) 505-846-4374 Kirtland AFB, NM 87117-5776 + diff --git a/contrib/pds/tif_imageiter.c b/contrib/pds/tif_imageiter.c new file mode 100644 index 00000000..ca741c85 --- /dev/null +++ b/contrib/pds/tif_imageiter.c @@ -0,0 +1,518 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_imageiter.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1996 Sam Leffler + * Copyright (c) 1991-1996 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Written by Conrad J. Poelman, PL/WSAT, Kirtland AFB, NM on 26 Mar 96. + * + * This file contains code to allow a calling program to "iterate" over each + * pixels in an image as it is read from the file. The iterator takes care of + * reading strips versus (possibly clipped) tiles, decoding the information + * according to the decoding method, and so on, so that calling program can + * ignore those details. The calling program does, however, need to be + * conscious of the type of the pixel data that it is receiving. + * + * For reasons of efficiency, the callback function actually gets called for + * "blocks" of pixels rather than for individual pixels. The format of the + * callback arguments is given below. + * + * This code was taken from TIFFReadRGBAImage() in tif_getimage.c of the original + * TIFF distribution, and simplified and generalized to provide this general + * iteration capability. Those routines could certainly be re-implemented in terms + * of a TIFFImageIter if desired. + * + */ +#include "tiffiop.h" +#include "tif_imgiter.h" +#include +#include + +static int gtTileContig(TIFFImageIter*, void *udata, uint32, uint32); +static int gtTileSeparate(TIFFImageIter*, void *udata, uint32, uint32); +static int gtStripContig(TIFFImageIter*, void *udata, uint32, uint32); +static int gtStripSeparate(TIFFImageIter*, void *udata, uint32, uint32); + +static const char photoTag[] = "PhotometricInterpretation"; + +static int +isCCITTCompression(TIFF* tif) +{ + uint16 compress; + TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); + return (compress == COMPRESSION_CCITTFAX3 || + compress == COMPRESSION_CCITTFAX4 || + compress == COMPRESSION_CCITTRLE || + compress == COMPRESSION_CCITTRLEW); +} + +int +TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024]) +{ + uint16* sampleinfo; + uint16 extrasamples; + uint16 planarconfig; + int colorchannels; + + img->tif = tif; + img->stoponerr = stop; + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); + img->alpha = 0; + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, + &extrasamples, &sampleinfo); + if (extrasamples == 1) + switch (sampleinfo[0]) { + case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ + case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ + img->alpha = sampleinfo[0]; + break; + } + colorchannels = img->samplesperpixel - extrasamples; + TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { + switch (colorchannels) { + case 1: + if (isCCITTCompression(tif)) + img->photometric = PHOTOMETRIC_MINISWHITE; + else + img->photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + img->photometric = PHOTOMETRIC_RGB; + break; + default: + sprintf(emsg, "Missing needed %s tag", photoTag); + return (0); + } + } + switch (img->photometric) { + case PHOTOMETRIC_PALETTE: + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, + &img->redcmap, &img->greencmap, &img->bluecmap)) { + TIFFError(TIFFFileName(tif), "Missing required \"Colormap\" tag"); + return (0); + } + /* fall thru... */ + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: +/* This should work now so skip the check - BSR + if (planarconfig == PLANARCONFIG_CONTIG && img->samplesperpixel != 1) { + sprintf(emsg, + "Sorry, can not handle contiguous data with %s=%d, and %s=%d", + photoTag, img->photometric, + "Samples/pixel", img->samplesperpixel); + return (0); + } + */ + break; + case PHOTOMETRIC_YCBCR: + if (planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d", + "Planarconfiguration", planarconfig); + return (0); + } + /* It would probably be nice to have a reality check here. */ + { uint16 compress; + TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); + if (compress == COMPRESSION_JPEG && planarconfig == PLANARCONFIG_CONTIG) { + /* can rely on libjpeg to convert to RGB */ + /* XXX should restore current state on exit */ + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + img->photometric = PHOTOMETRIC_RGB; + } + } + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) { + sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + return (0); + } + break; + case PHOTOMETRIC_SEPARATED: { + uint16 inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "InkSet", inkset); + return (0); + } + if (img->samplesperpixel != 4) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "Samples/pixel", img->samplesperpixel); + return (0); + } + break; + } + default: + sprintf(emsg, "Sorry, can not handle image with %s=%d", + photoTag, img->photometric); + return (0); + } + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); + + TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); + switch (img->orientation) { + case ORIENTATION_BOTRIGHT: + case ORIENTATION_RIGHTBOT: /* XXX */ + case ORIENTATION_LEFTBOT: /* XXX */ + TIFFWarning(TIFFFileName(tif), "using bottom-left orientation"); + img->orientation = ORIENTATION_BOTLEFT; + /* fall thru... */ + case ORIENTATION_BOTLEFT: + break; + case ORIENTATION_TOPRIGHT: + case ORIENTATION_RIGHTTOP: /* XXX */ + case ORIENTATION_LEFTTOP: /* XXX */ + default: + TIFFWarning(TIFFFileName(tif), "using top-left orientation"); + img->orientation = ORIENTATION_TOPLEFT; + /* fall thru... */ + case ORIENTATION_TOPLEFT: + break; + } + + img->isContig = + !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1); + if (img->isContig) { + img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig; + } else { + img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate; + } + return (1); +} + +int +TIFFImageIterGet(TIFFImageIter* img, void *udata, uint32 w, uint32 h) +{ + if (img->get == NULL) { + TIFFError(TIFFFileName(img->tif), "No \"get\" routine setup"); + return (0); + } + if (img->callback.any == NULL) { + TIFFError(TIFFFileName(img->tif), + "No \"put\" routine setupl; probably can not handle image format"); + return (0); + } + return (*img->get)(img, udata, w, h); +} + +TIFFImageIterEnd(TIFFImageIter* img) +{ + /* Nothing to free... ? */ +} + +/* + * Read the specified image into an ABGR-format raster. + */ +int +TIFFReadImageIter(TIFF* tif, + uint32 rwidth, uint32 rheight, uint8* raster, int stop) +{ + char emsg[1024]; + TIFFImageIter img; + int ok; + + if (TIFFImageIterBegin(&img, tif, stop, emsg)) { + /* XXX verify rwidth and rheight against width and height */ + ok = TIFFImageIterGet(&img, raster, rwidth, img.height); + TIFFImageIterEnd(&img); + } else { + TIFFError(TIFFFileName(tif), emsg); + ok = 0; + } + return (ok); +} + + +/* + * Get an tile-organized image that has + * PlanarConfiguration contiguous if SamplesPerPixel > 1 + * or + * SamplesPerPixel == 1 + */ +static int +gtTileContig(TIFFImageIter* img, void *udata, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + ImageIterTileContigRoutine callback = img->callback.contig; + uint16 orientation; + uint32 col, row; + uint32 tw, th; + u_char* buf; + int32 fromskew; + uint32 nrow; + + buf = (u_char*) _TIFFmalloc(TIFFTileSize(tif)); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + orientation = img->orientation; + for (row = 0; row < h; row += th) { + nrow = (row + th > h ? h - row : th); + for (col = 0; col < w; col += tw) { + if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 && img->stoponerr) + break; + if (col + tw > w) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + uint32 npix = w - col; + fromskew = tw - npix; + (*callback)(img, udata, col, row, npix, nrow, fromskew, buf); + } else { + (*callback)(img, udata, col, row, tw, nrow, 0, buf); + } + } + } + _TIFFfree(buf); + return (1); +} + +/* + * Get an tile-organized image that has + * SamplesPerPixel > 1 + * PlanarConfiguration separated + * We assume that all such images are RGB. + */ +static int +gtTileSeparate(TIFFImageIter* img, void *udata, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + ImageIterTileSeparateRoutine callback = img->callback.separate; + uint16 orientation; + uint32 col, row; + uint32 tw, th; + u_char* buf; + u_char* r; + u_char* g; + u_char* b; + u_char* a; + tsize_t tilesize; + int32 fromskew; + int alpha = img->alpha; + uint32 nrow; + + tilesize = TIFFTileSize(tif); + buf = (u_char*) _TIFFmalloc(4*tilesize); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + r = buf; + g = r + tilesize; + b = g + tilesize; + a = b + tilesize; + if (!alpha) + memset(a, 0xff, tilesize); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + orientation = img->orientation; + for (row = 0; row < h; row += th) { + nrow = (row + th > h ? h - row : th); + for (col = 0; col < w; col += tw) { + if (TIFFReadTile(tif, r, col, row,0,0) < 0 && img->stoponerr) + break; + if (TIFFReadTile(tif, g, col, row,0,1) < 0 && img->stoponerr) + break; + if (TIFFReadTile(tif, b, col, row,0,2) < 0 && img->stoponerr) + break; + if (alpha && TIFFReadTile(tif,a,col,row,0,3) < 0 && img->stoponerr) + break; + if (col + tw > w) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + uint32 npix = w - col; + fromskew = tw - npix; + (*callback)(img, udata, col, row, npix, nrow, fromskew, r, g, b, a); + } else { + (*callback)(img, udata, col, row, tw, nrow, 0, r, g, b, a); + } + } + } + _TIFFfree(buf); + return (1); +} + +/* + * Get a strip-organized image that has + * PlanarConfiguration contiguous if SamplesPerPixel > 1 + * or + * SamplesPerPixel == 1 + */ +static int +gtStripContig(TIFFImageIter* img, void *udata, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + ImageIterTileContigRoutine callback = img->callback.contig; + uint16 orientation; + uint32 row, nrow; + u_char* buf; + uint32 rowsperstrip; + uint32 imagewidth = img->width; + tsize_t scanline; + int32 fromskew; + + buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif)); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for strip buffer"); + return (0); + } + orientation = img->orientation; + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += rowsperstrip) { + nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), + buf, nrow*scanline) < 0 && img->stoponerr) + break; + (*callback)(img, udata, 0, row, w, nrow, fromskew, buf); + } + _TIFFfree(buf); + return (1); +} + +/* + * Get a strip-organized image with + * SamplesPerPixel > 1 + * PlanarConfiguration separated + * We assume that all such images are RGB. + */ +static int +gtStripSeparate(TIFFImageIter* img, void *udata, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + ImageIterTileSeparateRoutine callback = img->callback.separate; + uint16 orientation; + u_char *buf; + u_char *r, *g, *b, *a; + uint32 row, nrow; + tsize_t scanline; + uint32 rowsperstrip; + uint32 imagewidth = img->width; + tsize_t stripsize; + int32 fromskew; + int alpha = img->alpha; + + stripsize = TIFFStripSize(tif); + r = buf = (u_char *)_TIFFmalloc(4*stripsize); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + g = r + stripsize; + b = g + stripsize; + a = b + stripsize; + if (!alpha) + memset(a, 0xff, stripsize); + orientation = img->orientation; + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += rowsperstrip) { + nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), + r, nrow*scanline) < 0 && img->stoponerr) + break; + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1), + g, nrow*scanline) < 0 && img->stoponerr) + break; + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2), + b, nrow*scanline) < 0 && img->stoponerr) + break; + if (alpha && + (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3), + a, nrow*scanline) < 0 && img->stoponerr)) + break; + (*callback)(img, udata, 0, row, w, nrow, fromskew, r, g, b, a); + } + _TIFFfree(buf); + return (1); +} + +DECLAREContigCallbackFunc(TestContigCallback) +{ + printf("Contig Callback called with x = %d, y = %d, w = %d, h = %d, fromskew = %d\n", + x, y, w, h, fromskew); +} + + +DECLARESepCallbackFunc(TestSepCallback) +{ + printf("Sep Callback called with x = %d, y = %d, w = %d, h = %d, fromskew = %d\n", + x, y, w, h, fromskew); +} + + +#ifdef MAIN +main(int argc, char **argv) +{ + char emsg[1024]; + TIFFImageIter img; + int ok; + int stop = 1; + + TIFF *tif; + unsigned long nx, ny; + unsigned short BitsPerSample, SamplesPerPixel; + int isColorMapped, isPliFile; + unsigned char *ColorMap; + unsigned char *data; + + if (argc < 2) { + fprintf(stderr,"usage: %s tiff_file\n",argv[0]); + exit(1); + } + tif = (TIFF *)PLIGetImage(argv[1], (void *) &data, &ColorMap, + &nx, &ny, &BitsPerSample, &SamplesPerPixel, + &isColorMapped, &isPliFile); + if (tif != NULL) { + + if (TIFFImageIterBegin(&img, tif, stop, emsg)) { + /* Here need to set data and callback function! */ + if (img.isContig) { + img.callback = TestContigCallback; + } else { + img.callback = TestSepCallback; + } + ok = TIFFImageIterGet(&img, NULL, img.width, img.height); + TIFFImageIterEnd(&img); + } else { + TIFFError(TIFFFileName(tif), emsg); + } + } + +} +#endif diff --git a/contrib/pds/tif_imageiter.h b/contrib/pds/tif_imageiter.h new file mode 100644 index 00000000..5b7ea40a --- /dev/null +++ b/contrib/pds/tif_imageiter.h @@ -0,0 +1,57 @@ +typedef struct _TIFFImageIter TIFFImageIter; + +/* The callback function is called for each "block" of image pixel data after + it has been read from the file and decoded. This image pixel data is in the + buffer pp, and this data represents the image pixels from (x,y) to + (x+w,y+h). It is stored in pixel format, so each pixel contains + img->samplesperpixel consecutive samples each containing img->bitspersample + bits of data. The array pp is ordered in h consecutive rows of w+fromskew + pixels each. */ +typedef void (*ImageIterTileContigRoutine) + (TIFFImageIter*, void *, uint32, uint32, uint32, uint32, int32, + unsigned char*); +#define DECLAREContigCallbackFunc(name) \ +static void name(\ + TIFFImageIter* img, \ + void* user_data, \ + uint32 x, uint32 y, \ + uint32 w, uint32 h, \ + int32 fromskew, \ + u_char* pp \ +) + +typedef void (*ImageIterTileSeparateRoutine) + (TIFFImageIter*, void *, uint32, uint32, uint32, uint32, int32, + unsigned char*, unsigned char*, unsigned char*, unsigned char*); +#define DECLARESepCallbackFunc(name) \ +static void name(\ + TIFFImageIter* img, \ + void* user_data, \ + uint32 x, uint32 y, \ + uint32 w, uint32 h,\ + int32 fromskew, \ + u_char* r, u_char* g, u_char* b, u_char* a\ +) + +struct _TIFFImageIter { + TIFF* tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32 width; /* image width */ + uint32 height; /* image height */ + uint16 bitspersample; /* image bits/sample */ + uint16 samplesperpixel; /* image samples/pixel */ + uint16 orientation; /* image orientation */ + uint16 photometric; /* image photometric interp */ + uint16* redcmap; /* colormap pallete */ + uint16* greencmap; + uint16* bluecmap; + /* get image data routine */ + int (*get)(TIFFImageIter*, void *udata, uint32, uint32); + union { + void (*any)(TIFFImageIter*); + ImageIterTileContigRoutine contig; + ImageIterTileSeparateRoutine separate; + } callback; /* fn to exec for each block */ +}; diff --git a/contrib/pds/tif_pdsdirread.c b/contrib/pds/tif_pdsdirread.c new file mode 100644 index 00000000..f8e3235a --- /dev/null +++ b/contrib/pds/tif_pdsdirread.c @@ -0,0 +1,1124 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_pdsdirread.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1996 Sam Leffler + * Copyright (c) 1991-1996 Silicon Graphics, Inc. + * Copyright (c( 1996 USAF Phillips Laboratory + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * These routines written by Conrad J. Poelman on a single late-night of + * March 20-21, 1996. + * + * The entire purpose of this file is to provide a single external function, + * TIFFReadPrivateDataSubDirectory(). This function is intended for use in reading a + * private subdirectory from a TIFF file into a private structure. The + * actual writing of data into the structure is handled by the setFieldFn(), + * which is passed to TIFFReadPrivateDataSubDirectory() as a parameter. The idea is to + * enable any application wishing to store private subdirectories to do so + * easily using this function, without modifying the TIFF library. + * + * The astute observer will notice that only two functions are at all different + * from the original tif_dirread.c file: TIFFReadPrivateDataSubDirectory() and + * TIFFFetchNormalSubTag(). All the other stuff that makes this file so huge + * is only necessary because all of those functions are declared static in + * tif_dirread.c, so we have to totally duplicate them in order to use them. + * + * Oh, also note the bug fix in TIFFFetchFloat(). + * + */ + +#include "tiffiop.h" + +#define IGNORE 0 /* tag placeholder used below */ + +#if HAVE_IEEEFP +#define TIFFCvtIEEEFloatToNative(tif, n, fp) +#define TIFFCvtIEEEDoubleToNative(tif, n, dp) +#else +extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); +extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*); +#endif + +static void EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16); +static void MissingRequired(TIFF*, const char*); +static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); +static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*); +static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*); +static float TIFFFetchRational(TIFF*, TIFFDirEntry*); +static int TIFFFetchNormalSubTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*, + int (*getFieldFn)(TIFF *tif,ttag_t tag,...)); +static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, int*); +static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*); +static int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*); +static int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**); +static int TIFFFetchExtraSamples(TIFF*, TIFFDirEntry*); +static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*); +static float TIFFFetchFloat(TIFF*, TIFFDirEntry*); +static int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*); +static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*); +static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*); +static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*); +#if STRIPCHOP_SUPPORT +static void ChopUpSingleUncompressedStrip(TIFF*); +#endif + +static char * +CheckMalloc(TIFF* tif, tsize_t n, const char* what) +{ + char *cp = (char*)_TIFFmalloc(n); + if (cp == NULL) + TIFFError(tif->tif_name, "No space %s", what); + return (cp); +} + +/* Just as was done with TIFFWritePrivateDataSubDirectory(), here we implement + TIFFReadPrivateDataSubDirectory() which takes an offset into the TIFF file, + a TIFFFieldInfo structure specifying the types of the various tags, + and a function to use to set individual tags when they are encountered. + The data is read from the file, translated using the TIFF library's + built-in machine-independent conversion functions, and filled into + private subdirectory structure. + + This code was written by copying the original TIFFReadDirectory() function + from tif_dirread.c and paring it down to what is needed for this. + + It is the caller's responsibility to allocate and initialize the internal + structure that setFieldFn() will be writing into. If this function is being + called more than once before closing the file, the caller also must be + careful to free data in the structure before re-initializing. + + It is also the caller's responsibility to verify the presence of + any required fields after reading the directory in. +*/ + + +int +TIFFReadPrivateDataSubDirectory(TIFF* tif, toff_t pdir_offset, + TIFFFieldInfo *field_info, + int (*setFieldFn)(TIFF *tif, ttag_t tag, ...)) +{ + register TIFFDirEntry* dp; + register int n; + register TIFFDirectory* td; + TIFFDirEntry* dir; + int iv; + long v; + double dv; + const TIFFFieldInfo* fip; + int fix; + uint16 dircount; + uint32 nextdiroff; + char* cp; + int diroutoforderwarning = 0; + + /* Skipped part about checking for directories or compression data. */ + + if (!isMapped(tif)) { + if (!SeekOK(tif, pdir_offset)) { + TIFFError(tif->tif_name, + "Seek error accessing TIFF private subdirectory"); + return (0); + } + if (!ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFError(tif->tif_name, + "Can not read TIFF private subdirectory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + dir = (TIFFDirEntry *)CheckMalloc(tif, + dircount * sizeof (TIFFDirEntry), "to read TIFF private subdirectory"); + if (dir == NULL) + return (0); + if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) { + TIFFError(tif->tif_name, "Can not read TIFF private subdirectory"); + goto bad; + } + /* + * Read offset to next directory for sequential scans. + */ + (void) ReadOK(tif, &nextdiroff, sizeof (uint32)); + } else { + toff_t off = pdir_offset; + + if (off + sizeof (short) > tif->tif_size) { + TIFFError(tif->tif_name, + "Can not read TIFF private subdirectory count"); + return (0); + } else + _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16)); + off += sizeof (uint16); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + dir = (TIFFDirEntry *)CheckMalloc(tif, + dircount * sizeof (TIFFDirEntry), "to read TIFF private subdirectory"); + if (dir == NULL) + return (0); + if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) { + TIFFError(tif->tif_name, "Can not read TIFF private subdirectory"); + goto bad; + } else + _TIFFmemcpy(dir, tif->tif_base + off, + dircount*sizeof (TIFFDirEntry)); + off += dircount* sizeof (TIFFDirEntry); + if (off + sizeof (uint32) < tif->tif_size) + _TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32)); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdiroff); + + /* + * Setup default value and then make a pass over + * the fields to check type and tag information, + * and to extract info required to size data + * structures. A second pass is made afterwards + * to read in everthing not taken in the first pass. + */ + td = &tif->tif_dir; + + for (fip = field_info, dp = dir, n = dircount; + n > 0; n--, dp++) { + if (tif->tif_flags & TIFF_SWAB) { + TIFFSwabArrayOfShort(&dp->tdir_tag, 2); + TIFFSwabArrayOfLong(&dp->tdir_count, 2); + } + /* + * Find the field information entry for this tag. + */ + /* + * Silicon Beach (at least) writes unordered + * directory tags (violating the spec). Handle + * it here, but be obnoxious (maybe they'll fix it?). + */ + if (dp->tdir_tag < fip->field_tag) { + if (!diroutoforderwarning) { + TIFFWarning(tif->tif_name, + "invalid TIFF private subdirectory; tags are not sorted in ascending order"); + diroutoforderwarning = 1; + } + fip = field_info; /* O(n^2) */ + } + + while (fip->field_tag && fip->field_tag < dp->tdir_tag) + fip++; + if (!fip->field_tag || fip->field_tag != dp->tdir_tag) { + TIFFWarning(tif->tif_name, + "unknown field with tag %d (0x%x) in private subdirectory ignored", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_tag = IGNORE; + fip = field_info;/* restart search */ + continue; + } + /* + * Null out old tags that we ignore. + */ + + /* Not implemented yet, since FIELD_IGNORE is specific to + the main directories. Could pass this in too... */ + if (0 /* && fip->field_bit == FIELD_IGNORE */) { + ignore: + dp->tdir_tag = IGNORE; + continue; + } + + /* + * Check data type. + */ + + while (dp->tdir_type != (u_short)fip->field_type) { + if (fip->field_type == TIFF_ANY) /* wildcard */ + break; + fip++; + if (!fip->field_tag || fip->field_tag != dp->tdir_tag) { + TIFFWarning(tif->tif_name, + "wrong data type %d for \"%s\"; tag ignored", + dp->tdir_type, fip[-1].field_name); + goto ignore; + } + } + /* + * Check count if known in advance. + */ + if (fip->field_readcount != TIFF_VARIABLE) { + uint32 expected = (fip->field_readcount == TIFF_SPP) ? + (uint32) td->td_samplesperpixel : + (uint32) fip->field_readcount; + if (!CheckDirCount(tif, dp, expected)) + goto ignore; + } + + /* Now read in and process data from field. */ + if (!TIFFFetchNormalSubTag(tif, dp, fip, setFieldFn)) + goto bad; + + } + + if (dir) + _TIFFfree(dir); + return (1); +bad: + if (dir) + _TIFFfree(dir); + return (0); +} + +static void +EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +{ + register TIFFDirEntry *dp; + register TIFFDirectory *td = &tif->tif_dir; + uint16 i; + + if (td->td_stripbytecount) + _TIFFfree(td->td_stripbytecount); + td->td_stripbytecount = (uint32*) + CheckMalloc(tif, td->td_nstrips * sizeof (uint32), + "for \"StripByteCounts\" array"); + if (td->td_compression != COMPRESSION_NONE) { + uint32 space = (uint32)(sizeof (TIFFHeader) + + sizeof (uint16) + + (dircount * sizeof (TIFFDirEntry)) + + sizeof (uint32)); + toff_t filesize = TIFFGetFileSize(tif); + uint16 n; + + /* calculate amount of space used by indirect values */ + for (dp = dir, n = dircount; n > 0; n--, dp++) { + uint32 cc = dp->tdir_count*tiffDataWidth[dp->tdir_type]; + if (cc > sizeof (uint32)) + space += cc; + } + space = (filesize - space) / td->td_samplesperpixel; + for (i = 0; i < td->td_nstrips; i++) + td->td_stripbytecount[i] = space; + /* + * This gross hack handles the case were the offset to + * the last strip is past the place where we think the strip + * should begin. Since a strip of data must be contiguous, + * it's safe to assume that we've overestimated the amount + * of data in the strip and trim this number back accordingly. + */ + i--; + if (td->td_stripoffset[i] + td->td_stripbytecount[i] > filesize) + td->td_stripbytecount[i] = + filesize - td->td_stripoffset[i]; + } else { + uint32 rowbytes = TIFFScanlineSize(tif); + uint32 rowsperstrip = td->td_imagelength / td->td_nstrips; + for (i = 0; i < td->td_nstrips; i++) + td->td_stripbytecount[i] = rowbytes*rowsperstrip; + } + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + td->td_rowsperstrip = td->td_imagelength; +} + +static void +MissingRequired(TIFF* tif, const char* tagname) +{ + TIFFError(tif->tif_name, + "TIFF directory is missing required \"%s\" field", tagname); +} + +/* + * Check the count field of a directory + * entry against a known value. The caller + * is expected to skip/ignore the tag if + * there is a mismatch. + */ +static int +CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) +{ + if (count != dir->tdir_count) { + TIFFWarning(tif->tif_name, + "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, + dir->tdir_count, count); + return (0); + } + return (1); +} + +/* + * Fetch a contiguous directory item. + */ +static tsize_t +TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + int w = tiffDataWidth[dir->tdir_type]; + tsize_t cc = dir->tdir_count * w; + + if (!isMapped(tif)) { + if (!SeekOK(tif, dir->tdir_offset)) + goto bad; + if (!ReadOK(tif, cp, cc)) + goto bad; + } else { + if (dir->tdir_offset + cc > tif->tif_size) + goto bad; + _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc); + } + if (tif->tif_flags & TIFF_SWAB) { + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); + break; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); + break; + case TIFF_DOUBLE: + TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); + break; + } + } + return (cc); +bad: + TIFFError(tif->tif_name, "Error fetching data for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + return ((tsize_t) 0); +} + +/* + * Fetch an ASCII item from the file. + */ +static tsize_t +TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + if (dir->tdir_count <= 4) { + uint32 l = dir->tdir_offset; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&l); + _TIFFmemcpy(cp, &l, dir->tdir_count); + return (1); + } + return (TIFFFetchData(tif, dir, cp)); +} + +/* + * Convert numerator+denominator to float. + */ +static int +cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv) +{ + if (denom == 0) { + TIFFError(tif->tif_name, + "%s: Rational with zero denominator (num = %lu)", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num); + return (0); + } else { + if (dir->tdir_type == TIFF_RATIONAL) + *rv = ((float)num / (float)denom); + else + *rv = ((float)(int32)num / (float)(int32)denom); + return (1); + } +} + +/* + * Fetch a rational item from the file + * at offset off and return the value + * as a floating point number. + */ +static float +TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir) +{ + uint32 l[2]; + float v; + + return (!TIFFFetchData(tif, dir, (char *)l) || + !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v); +} + +/* + * Fetch a single floating point value + * from the offset field and return it + * as a native float. + */ +static float +TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir) +{ + /* This appears to be a flagrant bug in the TIFF library, yet I + actually don't understand how it could have ever worked the old + way. Look at the comments in my new code and you'll understand. */ +#if (0) + float v = (float) + TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset); + TIFFCvtIEEEFloatToNative(tif, 1, &v); +#else + float v; + /* This is a little bit tricky - if we just cast the uint32 to a float, + C will perform a numerical conversion, which is not what we want. + We want to take the actual bit pattern in the uint32 and interpret + it as a float. Thus we cast a uint32 * into a float * and then + dereference to get v. */ + uint32 l = (uint32) + TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset); + v = * (float *) &l; + TIFFCvtIEEEFloatToNative(tif, 1, &v); +#endif + return (v); + +} + +/* + * Fetch an array of BYTE or SBYTE values. + */ +static int +TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) +{ + if (dir->tdir_count <= 4) { + /* + * Extract data from offset field. + */ + if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { + switch (dir->tdir_count) { + case 4: v[3] = dir->tdir_offset & 0xff; + case 3: v[2] = (dir->tdir_offset >> 8) & 0xff; + case 2: v[1] = (dir->tdir_offset >> 16) & 0xff; + case 1: v[0] = dir->tdir_offset >> 24; + } + } else { + switch (dir->tdir_count) { + case 4: v[3] = dir->tdir_offset >> 24; + case 3: v[2] = (dir->tdir_offset >> 16) & 0xff; + case 2: v[1] = (dir->tdir_offset >> 8) & 0xff; + case 1: v[0] = dir->tdir_offset & 0xff; + } + } + return (1); + } else + return (TIFFFetchData(tif, dir, (char*) v) != 0); /* XXX */ +} + +/* + * Fetch an array of SHORT or SSHORT values. + */ +static int +TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) +{ + if (dir->tdir_count <= 2) { + if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { + switch (dir->tdir_count) { + case 2: v[1] = dir->tdir_offset & 0xffff; + case 1: v[0] = dir->tdir_offset >> 16; + } + } else { + switch (dir->tdir_count) { + case 2: v[1] = dir->tdir_offset >> 16; + case 1: v[0] = dir->tdir_offset & 0xffff; + } + } + return (1); + } else + return (TIFFFetchData(tif, dir, (char *)v) != 0); +} + +/* + * Fetch a pair of SHORT or BYTE values. + */ +static int +TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir) +{ + uint16 v[2]; + int ok = 0; + + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + ok = TIFFFetchShortArray(tif, dir, v); + break; + case TIFF_BYTE: + case TIFF_SBYTE: + ok = TIFFFetchByteArray(tif, dir, v); + break; + } + if (ok) + TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); + return (ok); +} + +/* + * Fetch an array of LONG or SLONG values. + */ +static int +TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) +{ + if (dir->tdir_count == 1) { + v[0] = dir->tdir_offset; + return (1); + } else + return (TIFFFetchData(tif, dir, (char*) v) != 0); +} + +/* + * Fetch an array of RATIONAL or SRATIONAL values. + */ +static int +TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) +{ + int ok = 0; + uint32* l; + + l = (uint32*)CheckMalloc(tif, + dir->tdir_count*tiffDataWidth[dir->tdir_type], + "to fetch array of rationals"); + if (l) { + if (TIFFFetchData(tif, dir, (char *)l)) { + uint32 i; + for (i = 0; i < dir->tdir_count; i++) { + ok = cvtRational(tif, dir, + l[2*i+0], l[2*i+1], &v[i]); + if (!ok) + break; + } + } + _TIFFfree((char *)l); + } + return (ok); +} + +/* + * Fetch an array of FLOAT values. + */ +static int +TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) +{ + + if (dir->tdir_count == 1) { + v[0] = *(float*) &dir->tdir_offset; + TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); + return (1); + } else if (TIFFFetchData(tif, dir, (char*) v)) { + TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); + return (1); + } else + return (0); +} + +/* + * Fetch an array of DOUBLE values. + */ +static int +TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) +{ + if (TIFFFetchData(tif, dir, (char*) v)) { + TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v); + return (1); + } else + return (0); +} + +/* + * Fetch an array of ANY values. The actual values are + * returned as doubles which should be able hold all the + * types. Yes, there really should be an tany_t to avoid + * this potential non-portability ... Note in particular + * that we assume that the double return value vector is + * large enough to read in any fundamental type. We use + * that vector as a buffer to read in the base type vector + * and then convert it in place to double (from end + * to front of course). + */ +static int +TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v) +{ + int i; + + switch (dir->tdir_type) { + case TIFF_BYTE: + case TIFF_SBYTE: + if (!TIFFFetchByteArray(tif, dir, (uint16*) v)) + return (0); + if (dir->tdir_type == TIFF_BYTE) { + uint16* vp = (uint16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } else { + int16* vp = (int16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_SHORT: + case TIFF_SSHORT: + if (!TIFFFetchShortArray(tif, dir, (uint16*) v)) + return (0); + if (dir->tdir_type == TIFF_SHORT) { + uint16* vp = (uint16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } else { + int16* vp = (int16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_LONG: + case TIFF_SLONG: + if (!TIFFFetchLongArray(tif, dir, (uint32*) v)) + return (0); + if (dir->tdir_type == TIFF_LONG) { + uint32* vp = (uint32*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } else { + int32* vp = (int32*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + if (!TIFFFetchRationalArray(tif, dir, (float*) v)) + return (0); + { float* vp = (float*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_FLOAT: + if (!TIFFFetchFloatArray(tif, dir, (float*) v)) + return (0); + { float* vp = (float*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_DOUBLE: + return (TIFFFetchDoubleArray(tif, dir, (double*) v)); + default: + /* TIFF_NOTYPE */ + /* TIFF_ASCII */ + /* TIFF_UNDEFINED */ + TIFFError(tif->tif_name, + "Cannot read TIFF_ANY type %d for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + return (0); + } + return (1); +} + + +/* + * Fetch a tag that is not handled by special case code. + */ +/* The standard function TIFFFetchNormalTag() could definitely be replaced + with a simple call to this function, just adding TIFFSetField() as the + last argument. */ +static int +TIFFFetchNormalSubTag(TIFF* tif, TIFFDirEntry* dp, const TIFFFieldInfo* fip, + int (*setFieldFn)(TIFF *tif, ttag_t tag, ...)) +{ + static char mesg[] = "to fetch tag value"; + int ok = 0; + + if (dp->tdir_count > 1) { /* array of values */ + char* cp = NULL; + + switch (dp->tdir_type) { + case TIFF_BYTE: + case TIFF_SBYTE: + /* NB: always expand BYTE values to shorts */ + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (uint16), mesg); + ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp); + break; + case TIFF_SHORT: + case TIFF_SSHORT: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (uint16), mesg); + ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp); + break; + case TIFF_LONG: + case TIFF_SLONG: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (uint32), mesg); + ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp); + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (float), mesg); + ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp); + break; + case TIFF_FLOAT: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (float), mesg); + ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp); + break; + case TIFF_DOUBLE: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (double), mesg); + ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp); + break; + case TIFF_ASCII: + case TIFF_UNDEFINED: /* bit of a cheat... */ + /* + * Some vendors write strings w/o the trailing + * NULL byte, so always append one just in case. + */ + cp = CheckMalloc(tif, dp->tdir_count+1, mesg); + if (ok = (cp && TIFFFetchString(tif, dp, cp))) + cp[dp->tdir_count] = '\0'; /* XXX */ + break; + } + if (ok) { + ok = (fip->field_passcount ? + (*setFieldFn)(tif, dp->tdir_tag, dp->tdir_count, cp) + : (*setFieldFn)(tif, dp->tdir_tag, cp)); + } + if (cp != NULL) + _TIFFfree(cp); + } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */ + switch (dp->tdir_type) { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + /* + * If the tag is also acceptable as a LONG or SLONG + * then (*setFieldFn) will expect an uint32 parameter + * passed to it (through varargs). Thus, for machines + * where sizeof (int) != sizeof (uint32) we must do + * a careful check here. It's hard to say if this + * is worth optimizing. + * + * NB: We use TIFFFieldWithTag here knowing that + * it returns us the first entry in the table + * for the tag and that that entry is for the + * widest potential data type the tag may have. + */ + { TIFFDataType type = fip->field_type; + if (type != TIFF_LONG && type != TIFF_SLONG) { + uint16 v = (uint16) + TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset); + ok = (fip->field_passcount ? + (*setFieldFn)(tif, dp->tdir_tag, 1, &v) + : (*setFieldFn)(tif, dp->tdir_tag, v)); + break; + } + } + /* fall thru... */ + case TIFF_LONG: + case TIFF_SLONG: + { uint32 v32 = + TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset); + ok = (fip->field_passcount ? + (*setFieldFn)(tif, dp->tdir_tag, 1, &v32) + : (*setFieldFn)(tif, dp->tdir_tag, v32)); + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + { float v = (dp->tdir_type == TIFF_FLOAT ? + TIFFFetchFloat(tif, dp) + : TIFFFetchRational(tif, dp)); + ok = (fip->field_passcount ? + (*setFieldFn)(tif, dp->tdir_tag, 1, &v) + : (*setFieldFn)(tif, dp->tdir_tag, v)); + } + break; + case TIFF_DOUBLE: + { double v; + ok = (TIFFFetchDoubleArray(tif, dp, &v) && + (fip->field_passcount ? + (*setFieldFn)(tif, dp->tdir_tag, 1, &v) + : (*setFieldFn)(tif, dp->tdir_tag, v)) + ); + } + break; + case TIFF_ASCII: + case TIFF_UNDEFINED: /* bit of a cheat... */ + { char c[2]; + if (ok = (TIFFFetchString(tif, dp, c) != 0)) { + c[1] = '\0'; /* XXX paranoid */ + ok = (*setFieldFn)(tif, dp->tdir_tag, c); + } + } + break; + } + } + return (ok); +} + +/* Everything after this is exactly duplicated from the standard tif_dirread.c + file, necessitated by the fact that they are declared static there so + we can't call them! +*/ +#define NITEMS(x) (sizeof (x) / sizeof (x[0])) +/* + * Fetch samples/pixel short values for + * the specified tag and verify that + * all values are the same. + */ +static int +TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl) +{ + int samples = tif->tif_dir.td_samplesperpixel; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { + uint16 buf[10]; + uint16* v = buf; + + if (samples > NITEMS(buf)) + v = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); + if (TIFFFetchShortArray(tif, dir, v)) { + int i; + for (i = 1; i < samples; i++) + if (v[i] != v[0]) { + TIFFError(tif->tif_name, + "Cannot handle different per-sample values for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + goto bad; + } + *pl = v[0]; + status = 1; + } + bad: + if (v != buf) + _TIFFfree((char*) v); + } + return (status); +} + +/* + * Fetch samples/pixel ANY values for + * the specified tag and verify that + * all values are the same. + */ +static int +TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl) +{ + int samples = (int) tif->tif_dir.td_samplesperpixel; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { + double buf[10]; + double* v = buf; + + if (samples > NITEMS(buf)) + v = (double*) _TIFFmalloc(samples * sizeof (double)); + if (TIFFFetchAnyArray(tif, dir, v)) { + int i; + for (i = 1; i < samples; i++) + if (v[i] != v[0]) { + TIFFError(tif->tif_name, + "Cannot handle different per-sample values for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + goto bad; + } + *pl = v[0]; + status = 1; + } + bad: + if (v != buf) + _TIFFfree(v); + } + return (status); +} +#undef NITEMS + +/* + * Fetch a set of offsets or lengths. + * While this routine says "strips", + * in fact it's also used for tiles. + */ +static int +TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp) +{ + register uint32* lp; + int status; + + if (!CheckDirCount(tif, dir, (uint32) nstrips)) + return (0); + /* + * Allocate space for strip information. + */ + if (*lpp == NULL && + (*lpp = (uint32 *)CheckMalloc(tif, + nstrips * sizeof (uint32), "for strip array")) == NULL) + return (0); + lp = *lpp; + if (dir->tdir_type == (int)TIFF_SHORT) { + /* + * Handle uint16->uint32 expansion. + */ + uint16* dp = (uint16*) CheckMalloc(tif, + dir->tdir_count* sizeof (uint16), "to fetch strip tag"); + if (dp == NULL) + return (0); + if (status = TIFFFetchShortArray(tif, dir, dp)) { + register uint16* wp = dp; + while (nstrips-- > 0) + *lp++ = *wp++; + } + _TIFFfree((char*) dp); + } else + status = TIFFFetchLongArray(tif, dir, lp); + return (status); +} + +#define NITEMS(x) (sizeof (x) / sizeof (x[0])) +/* + * Fetch and set the ExtraSamples tag. + */ +static int +TIFFFetchExtraSamples(TIFF* tif, TIFFDirEntry* dir) +{ + uint16 buf[10]; + uint16* v = buf; + int status; + + if (dir->tdir_count > NITEMS(buf)) + v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16)); + if (dir->tdir_type == TIFF_BYTE) + status = TIFFFetchByteArray(tif, dir, v); + else + status = TIFFFetchShortArray(tif, dir, v); + if (status) + status = TIFFSetField(tif, dir->tdir_tag, dir->tdir_count, v); + if (v != buf) + _TIFFfree((char*) v); + return (status); +} +#undef NITEMS + +#ifdef COLORIMETRY_SUPPORT +/* + * Fetch and set the RefBlackWhite tag. + */ +static int +TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir) +{ + static char mesg[] = "for \"ReferenceBlackWhite\" array"; + char* cp; + int ok; + + if (dir->tdir_type == TIFF_RATIONAL) + return (1/*TIFFFetchNormalTag(tif, dir) just so linker won't complain - this part of the code is never used anyway */); + /* + * Handle LONG's for backward compatibility. + */ + cp = CheckMalloc(tif, dir->tdir_count * sizeof (uint32), mesg); + if (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) { + float* fp = (float*) + CheckMalloc(tif, dir->tdir_count * sizeof (float), mesg); + if (ok = (fp != NULL)) { + uint32 i; + for (i = 0; i < dir->tdir_count; i++) + fp[i] = (float)((uint32*) cp)[i]; + ok = TIFFSetField(tif, dir->tdir_tag, fp); + _TIFFfree((char*) fp); + } + } + if (cp) + _TIFFfree(cp); + return (ok); +} +#endif + +#if STRIPCHOP_SUPPORT +/* + * Replace a single strip (tile) of uncompressed data by + * multiple strips (tiles), each approximately 8Kbytes. + * This is useful for dealing with large images or + * for dealing with machines with a limited amount + * memory. + */ +static void +ChopUpSingleUncompressedStrip(TIFF* tif) +{ + register TIFFDirectory *td = &tif->tif_dir; + uint32 bytecount = td->td_stripbytecount[0]; + uint32 offset = td->td_stripoffset[0]; + tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes; + tstrip_t strip, nstrips, rowsperstrip; + uint32* newcounts; + uint32* newoffsets; + + /* + * Make the rows hold at least one + * scanline, but fill 8k if possible. + */ + if (rowbytes > 8192) { + stripbytes = rowbytes; + rowsperstrip = 1; + } else { + rowsperstrip = 8192 / rowbytes; + stripbytes = rowbytes * rowsperstrip; + } + /* never increase the number of strips in an image */ + if (rowsperstrip >= td->td_rowsperstrip) + return; + nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes); + newcounts = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32), + "for chopped \"StripByteCounts\" array"); + newoffsets = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32), + "for chopped \"StripOffsets\" array"); + if (newcounts == NULL || newoffsets == NULL) { + /* + * Unable to allocate new strip information, give + * up and use the original one strip information. + */ + if (newcounts != NULL) + _TIFFfree(newcounts); + if (newoffsets != NULL) + _TIFFfree(newoffsets); + return; + } + /* + * Fill the strip information arrays with + * new bytecounts and offsets that reflect + * the broken-up format. + */ + for (strip = 0; strip < nstrips; strip++) { + if (stripbytes > bytecount) + stripbytes = bytecount; + newcounts[strip] = stripbytes; + newoffsets[strip] = offset; + offset += stripbytes; + bytecount -= stripbytes; + } + /* + * Replace old single strip info with multi-strip info. + */ + td->td_stripsperimage = td->td_nstrips = nstrips; + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + + _TIFFfree(td->td_stripbytecount); + _TIFFfree(td->td_stripoffset); + td->td_stripbytecount = newcounts; + td->td_stripoffset = newoffsets; +} +#endif /* STRIPCHOP_SUPPORT */ diff --git a/contrib/pds/tif_pdsdirwrite.c b/contrib/pds/tif_pdsdirwrite.c new file mode 100644 index 00000000..d3bb0987 --- /dev/null +++ b/contrib/pds/tif_pdsdirwrite.c @@ -0,0 +1,964 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_pdsdirwrite.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* When writing data to TIFF files, it is often useful to store application- + specific data in a private TIFF directory so that the tags don't need to + be registered and won't conflict with other people's user-defined tags. + One needs to have a registered public tag which contains some amount of + raw data. That raw data, however, is interpreted at an independent, + separate, private tiff directory. This file provides some routines which + will be useful for converting that data from its raw binary form into + the proper form for your application. +*/ + +/* + * Copyright (c) 1988-1996 Sam Leffler + * Copyright (c) 1991-1996 Silicon Graphics, Inc. + * Copyright (c( 1996 USAF Phillips Laboratory + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * These routines written by Conrad J. Poelman on a single late-night of + * March 20-21, 1996. + * + * The entire purpose of this file is to provide a single external function, + * TIFFWritePrivateDataSubDirectory(). This function is intended for use + * in writing a private subdirectory structure into a TIFF file. The + * actual reading of data from the structure is handled by the getFieldFn(), + * which is passed to TIFFWritePrivateDataSubDirectory() as a parameter. The + * idea is to enable any application wishing to read private subdirectories to + * do so easily using this function, without modifying the TIFF library. + * + * The astute observer will notice that only two functions are at all different + * from the original tif_dirwrite.c file: TIFFWritePrivateDataSubDirectory()and + * TIFFWriteNormalSubTag(). All the other stuff that makes this file so huge + * is only necessary because all of those functions are declared static in + * tif_dirwrite.c, so we have to totally duplicate them in order to use them. + * + * Oh, also please note the bug-fix in the routine TIFFWriteNormalSubTag(), + * which equally should be applied to TIFFWriteNormalTag(). + * + */ +#include "tiffiop.h" + +#if HAVE_IEEEFP +#define TIFFCvtNativeToIEEEFloat(tif, n, fp) +#define TIFFCvtNativeToIEEEDouble(tif, n, dp) +#else +extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*); +extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*); +#endif + +static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*); +static int TIFFWriteNormalSubTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*, + int (*getFieldFn)(TIFF *tif,ttag_t tag,...)); +static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32); +static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*); +static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*); +static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*); +static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**); +static int TIFFWriteShortArray(TIFF*, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*); +static int TIFFWriteLongArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*); +static int TIFFWriteRationalArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); +static int TIFFWriteFloatArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); +static int TIFFWriteDoubleArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); +static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*); +static int TIFFWriteAnyArray(TIFF*, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); +#ifdef COLORIMETRY_SUPPORT +static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*); +#endif +static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*); +static int TIFFLinkDirectory(TIFF*); + +#define WriteRationalPair(type, tag1, v1, tag2, v2) { \ + if (!TIFFWriteRational(tif, type, tag1, dir, v1)) \ + goto bad; \ + if (!TIFFWriteRational(tif, type, tag2, dir+1, v2)) \ + goto bad; \ + dir++; \ +} +#define TIFFWriteRational(tif, type, tag, dir, v) \ + TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v)) +#ifndef TIFFWriteRational +static int TIFFWriteRational(TIFF*, + TIFFDataType, ttag_t, TIFFDirEntry*, float); +#endif + +/* This function will write an entire directory to the disk, and return the + offset value indicating where in the file it wrote the beginning of the + directory structure. This is NOT the same as the offset value before + calling this function, because some of the fields may have caused various + data items to be written out BEFORE writing the directory structure. + + This code was basically written by ripping of the TIFFWriteDirectory() + code and generalizing it, using RPS's TIFFWritePliIfd() code for + inspiration. My original goal was to make this code general enough that + the original TIFFWriteDirectory() could be rewritten to just call this + function with the appropriate field and field-accessing arguments. + + However, now I realize that there's a lot of code that gets executed for + the main, standard TIFF directories that does not apply to special + private subdirectories, so such a reimplementation for the sake of + eliminating redundant or duplicate code is probably not possible, + unless we also pass in a Main flag to indiciate which type of handling + to do, which would be kind of a hack. I've marked those places where I + changed or ripped out code which would have to be re-inserted to + generalize this function. If it can be done in a clean and graceful way, + it would be a great way to generalize the TIFF library. Otherwise, I'll + just leave this code here where it duplicates but remains on top of and + hopefully mostly independent of the main TIFF library. + + The caller will probably want to free the sub directory structure after + returning from this call, since otherwise once written out, the user + is likely to forget about it and leave data lying around. +*/ +toff_t +TIFFWritePrivateDataSubDirectory(TIFF* tif, + uint32 pdir_fieldsset[], int pdir_fields_last, + TIFFFieldInfo *field_info, + int (*getFieldFn)(TIFF *tif, ttag_t tag, ...)) +{ + uint16 dircount; + uint32 diroff, nextdiroff; + ttag_t tag; + uint32 nfields; + tsize_t dirsize; + char* data; + TIFFDirEntry* dir; + u_long b, *fields, fields_size; + toff_t directory_offset; + TIFFFieldInfo* fip; + + /* + * Deleted out all of the encoder flushing and such code from here - + * not necessary for subdirectories. + */ + + /* Finish writing out any image data. */ + TIFFFlushData(tif); + + /* + * Size the directory so that we can calculate + * offsets for the data items that aren't kept + * in-place in each field. + */ + nfields = 0; + for (b = 0; b <= pdir_fields_last; b++) + if (FieldSet(pdir_fieldsset, b)) + /* Deleted code to make size of first 4 tags 2 + instead of 1. */ + nfields += 1; + dirsize = nfields * sizeof (TIFFDirEntry); + data = (char*) _TIFFmalloc(dirsize); + if (data == NULL) { + TIFFError(tif->tif_name, + "Cannot write private subdirectory, out of space"); + return (0); + } + /* + * Place directory in data section of the file. If there isn't one + * yet, place it at the end of the file. The directory is treated as + * data, so we don't link it into the directory structure at all. + */ + if (tif->tif_dataoff == 0) + tif->tif_dataoff =(TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; + diroff = tif->tif_dataoff; + tif->tif_dataoff = (toff_t)( + diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); + if (tif->tif_dataoff & 1) + tif->tif_dataoff++; + (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); + /*tif->tif_curdir++;*/ + dir = (TIFFDirEntry*) data; + /* + * Setup external form of directory + * entries and write data items. + */ + /* + * We make a local copy of the fieldsset here so that we don't mess + * up the original one when we call ResetFieldBit(). But I'm not sure + * why the original code calls ResetFieldBit(), since we're already + * going through the fields in order... + * + * fields_size is the number of uint32's we will need to hold the + * bit-mask for all of the fields. If our highest field number is + * 100, then we'll need 100 / (8*4)+1 == 4 uint32's to hold the + * fieldset. + * + * Unlike the original code, we allocate fields dynamically based + * on the requested pdir_fields_last value, allowing private + * data subdirectories to contain more than the built-in code's limit + * of 95 tags in a directory. + */ + fields_size = pdir_fields_last / (8*sizeof(uint32)) + 1; + fields = _TIFFmalloc(fields_size*sizeof(uint32)); + _TIFFmemcpy(fields, pdir_fieldsset, fields_size * sizeof(uint32)); + + /* Deleted "write out extra samples tag" code here. */ + + /* Deleted code for checking a billion little special cases for the + * standard TIFF tags. Should add a general mechanism for overloading + * write function for each field, just like Brian kept telling me!!! + */ + for (fip = field_info; fip->field_tag; fip++) { + /* Deleted code to check for FIELD_IGNORE!! */ + if (/* fip->field_bit == FIELD_IGNORE || */ + !FieldSet(fields, fip->field_bit)) + continue; + if (!TIFFWriteNormalSubTag(tif, dir, fip, getFieldFn)) + goto bad; + dir++; + ResetFieldBit(fields, fip->field_bit); + } + + /* Now we've written all of the referenced data, and are about to + write the main directory structure, so grab the tif_dataoff value + now so we can remember where we wrote the directory. */ + directory_offset = tif->tif_dataoff; + + /* + * Write directory. + */ + dircount = (uint16) nfields; + /* Deleted code to link to the next directory - we set it to zero! */ + nextdiroff = 0; + if (tif->tif_flags & TIFF_SWAB) { + /* + * The file's byte order is opposite to the + * native machine architecture. We overwrite + * the directory information with impunity + * because it'll be released below after we + * write it to the file. Note that all the + * other tag construction routines assume that + * we do this byte-swapping; i.e. they only + * byte-swap indirect data. + */ + for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { + TIFFSwabArrayOfShort(&dir->tdir_tag, 2); + TIFFSwabArrayOfLong(&dir->tdir_count, 2); + } + dircount = (uint16) nfields; + TIFFSwabShort(&dircount); + TIFFSwabLong(&nextdiroff); + } + + (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); + if (!WriteOK(tif, &dircount, sizeof (dircount))) { + TIFFError(tif->tif_name, "Error writing private subdirectory count"); + goto bad; + } + if (!WriteOK(tif, data, dirsize)) { + TIFFError(tif->tif_name, "Error writing private subdirectory contents"); + goto bad; + } + if (!WriteOK(tif, &nextdiroff, sizeof (nextdiroff))) { + TIFFError(tif->tif_name, "Error writing private subdirectory link"); + goto bad; + } + tif->tif_dataoff += sizeof(dircount) + dirsize + sizeof(nextdiroff); + + _TIFFfree(data); + _TIFFfree(fields); + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + +#if (0) + /* This stuff commented out because I don't think we want it for + subdirectories, but I could be wrong. */ + (*tif->tif_cleanup)(tif); + + /* + * Reset directory-related state for subsequent + * directories. + */ + TIFFDefaultDirectory(tif); + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (tstrip_t) -1; +#endif + + return (directory_offset); +bad: + _TIFFfree(data); + _TIFFfree(fields); + return (0); +} +#undef WriteRationalPair + +/* + * Process tags that are not special cased. + */ +/* The standard function TIFFWriteNormalTag() could definitely be replaced + with a simple call to this function, just adding TIFFGetField() as the + last argument. */ +static int +TIFFWriteNormalSubTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip, + int (*getFieldFn)(TIFF *tif, ttag_t tag, ...)) +{ + u_short wc = (u_short) fip->field_writecount; + + dir->tdir_tag = fip->field_tag; + dir->tdir_type = (u_short) fip->field_type; + dir->tdir_count = wc; +#define WRITEF(x,y) x(tif, fip->field_type, fip->field_tag, dir, wc, y) + switch (fip->field_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + if (wc > 1) { + uint16* wp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &wp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &wp); + if (!WRITEF(TIFFWriteShortArray, wp)) + return (0); + } else { + uint16 sv; + (*getFieldFn)(tif, fip->field_tag, &sv); + dir->tdir_offset = + TIFFInsertData(tif, dir->tdir_type, sv); + } + break; + case TIFF_LONG: + case TIFF_SLONG: + if (wc > 1) { + uint32* lp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &lp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &lp); + if (!WRITEF(TIFFWriteLongArray, lp)) + return (0); + } else { + /* XXX handle LONG->SHORT conversion */ + (*getFieldFn)(tif, fip->field_tag, &dir->tdir_offset); + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + if (wc > 1) { + float* fp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &fp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &fp); + if (!WRITEF(TIFFWriteRationalArray, fp)) + return (0); + } else { + float fv; + (*getFieldFn)(tif, fip->field_tag, &fv); + if (!WRITEF(TIFFWriteRationalArray, &fv)) + return (0); + } + break; + case TIFF_FLOAT: + if (wc > 1) { + float* fp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &fp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &fp); + if (!WRITEF(TIFFWriteFloatArray, fp)) + return (0); + } else { + float fv; + (*getFieldFn)(tif, fip->field_tag, &fv); + if (!WRITEF(TIFFWriteFloatArray, &fv)) + return (0); + } + break; + case TIFF_DOUBLE: + /* Hey - I think this is a bug, or at least a "gross + inconsistency", in the TIFF library. Look at the original + TIFF library code below within the "#if (0) ... #else". + Just from the type of *dp, you can see that this code + expects TIFFGetField() to be handed a double ** for + any TIFF_DOUBLE tag, even for the constant wc==1 case. + This is totally inconsistent with other fields (like + TIFF_FLOAT, above) and is also inconsistent with the + TIFFSetField() function for TIFF_DOUBLEs, which expects + to be passed a single double by value for the wc==1 case. + (See the handling of TIFFFetchNormalTag() in tif_dirread.c + for an example.) Maybe this function was written before + TIFFWriteDoubleArray() was written, not that that's an + excuse. Anyway, the new code below is a trivial modification + of the TIFF_FLOAT code above. The fact that even single + doubles get written out in the data segment and get an + offset value stored is irrelevant here - that is all + handled by TIFFWriteDoubleArray(). */ +#if (0) + { double* dp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &dp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &dp); + TIFFCvtNativeToIEEEDouble(tif, wc, dp); + if (!TIFFWriteData(tif, dir, (char*) dp)) + return (0); + } +#else + if (wc > 1) { + double* dp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &dp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &dp); + if (!WRITEF(TIFFWriteDoubleArray, dp)) + return (0); + } else { + double dv; + (*getFieldFn)(tif, fip->field_tag, &dv); + if (!WRITEF(TIFFWriteDoubleArray, &dv)) + return (0); + } +#endif + break; + case TIFF_ASCII: + { char* cp; + (*getFieldFn)(tif, fip->field_tag, &cp); + dir->tdir_count = (uint32) (strlen(cp) + 1); + if (!TIFFWriteByteArray(tif, dir, cp)) + return (0); + } + break; + case TIFF_UNDEFINED: + { char* cp; + if (wc == (u_short) TIFF_VARIABLE) { + (*getFieldFn)(tif, fip->field_tag, &wc, &cp); + dir->tdir_count = wc; + } else + (*getFieldFn)(tif, fip->field_tag, &cp); + if (!TIFFWriteByteArray(tif, dir, cp)) + return (0); + } + break; + } + return (1); +} +#undef WRITEF + +/* Everything after this is exactly duplicated from the standard tif_dirwrite.c + file, necessitated by the fact that they are declared static there so + we can't call them! +*/ +/* + * Setup a directory entry with either a SHORT + * or LONG type according to the value. + */ +static void +TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v) +{ + dir->tdir_tag = tag; + dir->tdir_count = 1; + if (v > 0xffffL) { + dir->tdir_type = (short) TIFF_LONG; + dir->tdir_offset = v; + } else { + dir->tdir_type = (short) TIFF_SHORT; + dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); + } +} +#undef MakeShortDirent + +#ifndef TIFFWriteRational +/* + * Setup a RATIONAL directory entry and + * write the associated indirect value. + */ +static int +TIFFWriteRational(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v) +{ + return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v)); +} +#endif + +#define NITEMS(x) (sizeof (x) / sizeof (x[0])) +/* + * Setup a directory entry that references a + * samples/pixel array of SHORT values and + * (potentially) write the associated indirect + * values. + */ +static int +TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) +{ + uint16 buf[10], v; + uint16* w = buf; + int i, status, samples = tif->tif_dir.td_samplesperpixel; + + if (samples > NITEMS(buf)) + w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); + TIFFGetField(tif, tag, &v); + for (i = 0; i < samples; i++) + w[i] = v; + status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w); + if (w != buf) + _TIFFfree((char*) w); + return (status); +} + +/* + * Setup a directory entry that references a samples/pixel array of ``type'' + * values and (potentially) write the associated indirect values. The source + * data from TIFFGetField() for the specified tag must be returned as double. + */ +static int +TIFFWritePerSampleAnys(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir) +{ + double buf[10], v; + double* w = buf; + int i, status; + int samples = (int) tif->tif_dir.td_samplesperpixel; + + if (samples > NITEMS(buf)) + w = (double*) _TIFFmalloc(samples * sizeof (double)); + TIFFGetField(tif, tag, &v); + for (i = 0; i < samples; i++) + w[i] = v; + status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w); + if (w != buf) + _TIFFfree(w); + return (status); +} +#undef NITEMS + +/* + * Setup a pair of shorts that are returned by + * value, rather than as a reference to an array. + */ +static int +TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) +{ + uint16 v[2]; + + TIFFGetField(tif, tag, &v[0], &v[1]); + return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v)); +} + +/* + * Setup a directory entry for an NxM table of shorts, + * where M is known to be 2**bitspersample, and write + * the associated indirect data. + */ +static int +TIFFWriteShortTable(TIFF* tif, + ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) +{ + uint32 i, off; + + dir->tdir_tag = tag; + dir->tdir_type = (short) TIFF_SHORT; + /* XXX -- yech, fool TIFFWriteData */ + dir->tdir_count = (uint32) (1L<tif_dir.td_bitspersample); + off = tif->tif_dataoff; + for (i = 0; i < n; i++) + if (!TIFFWriteData(tif, dir, (char *)table[i])) + return (0); + dir->tdir_count *= n; + dir->tdir_offset = off; + return (1); +} + +/* + * Write/copy data associated with an ASCII or opaque tag value. + */ +static int +TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + if (dir->tdir_count > 4) { + if (!TIFFWriteData(tif, dir, cp)) + return (0); + } else + _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count); + return (1); +} + +/* + * Setup a directory entry of an array of SHORT + * or SSHORT and write the associated indirect values. + */ +static int +TIFFWriteShortArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (n <= 2) { + if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { + dir->tdir_offset = (uint32) ((long) v[0] << 16); + if (n == 2) + dir->tdir_offset |= v[1] & 0xffff; + } else { + dir->tdir_offset = v[0] & 0xffff; + if (n == 2) + dir->tdir_offset |= (long) v[1] << 16; + } + return (1); + } else + return (TIFFWriteData(tif, dir, (char*) v)); +} + +/* + * Setup a directory entry of an array of LONG + * or SLONG and write the associated indirect values. + */ +static int +TIFFWriteLongArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (n == 1) { + dir->tdir_offset = v[0]; + return (1); + } else + return (TIFFWriteData(tif, dir, (char*) v)); +} + +/* + * Setup a directory entry of an array of RATIONAL + * or SRATIONAL and write the associated indirect values. + */ +static int +TIFFWriteRationalArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) +{ + uint32 i; + uint32* t; + int status; + + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32)); + for (i = 0; i < n; i++) { + float fv = v[i]; + int sign = 1; + uint32 den; + + if (fv < 0) { + if (type == TIFF_RATIONAL) { + TIFFWarning(tif->tif_name, + "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", + _TIFFFieldWithTag(tif,tag)->field_name, v); + fv = 0; + } else + fv = -fv, sign = -1; + } + den = 1L; + if (fv > 0) { + while (fv < 1L<<(31-3) && den < 1L<<(31-3)) + fv *= 1<<3, den *= 1L<<3; + } + t[2*i+0] = sign * (fv + 0.5); + t[2*i+1] = den; + } + status = TIFFWriteData(tif, dir, (char *)t); + _TIFFfree((char*) t); + return (status); +} + +static int +TIFFWriteFloatArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + TIFFCvtNativeToIEEEFloat(tif, n, v); + if (n == 1) { + dir->tdir_offset = *(uint32*) &v[0]; + return (1); + } else + return (TIFFWriteData(tif, dir, (char*) v)); +} + +static int +TIFFWriteDoubleArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + TIFFCvtNativeToIEEEDouble(tif, n, v); + return (TIFFWriteData(tif, dir, (char*) v)); +} + +/* + * Write an array of ``type'' values for a specified tag (i.e. this is a tag + * which is allowed to have different types, e.g. SMaxSampleType). + * Internally the data values are represented as double since a double can + * hold any of the TIFF tag types (yes, this should really be an abstract + * type tany_t for portability). The data is converted into the specified + * type in a temporary buffer and then handed off to the appropriate array + * writer. + */ +static int +TIFFWriteAnyArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) +{ + char buf[10 * sizeof(double)]; + char* w = buf; + int i, status = 0; + + if (n * tiffDataWidth[type] > sizeof buf) + w = (char*) _TIFFmalloc(n * tiffDataWidth[type]); + switch (type) { + case TIFF_BYTE: + { unsigned char* bp = (unsigned char*) w; + for (i = 0; i < n; i++) + bp[i] = (unsigned char) v[i]; + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (!TIFFWriteByteArray(tif, dir, (char*) bp)) + goto out; + } + break; + case TIFF_SBYTE: + { signed char* bp = (signed char*) w; + for (i = 0; i < n; i++) + bp[i] = (signed char) v[i]; + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (!TIFFWriteByteArray(tif, dir, (char*) bp)) + goto out; + } + break; + case TIFF_SHORT: + { uint16* bp = (uint16*) w; + for (i = 0; i < n; i++) + bp[i] = (uint16) v[i]; + if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) + goto out; + } + break; + case TIFF_SSHORT: + { int16* bp = (int16*) w; + for (i = 0; i < n; i++) + bp[i] = (int16) v[i]; + if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) + goto out; + } + break; + case TIFF_LONG: + { uint32* bp = (uint32*) w; + for (i = 0; i < n; i++) + bp[i] = (uint32) v[i]; + if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp)) + goto out; + } + break; + case TIFF_SLONG: + { int32* bp = (int32*) w; + for (i = 0; i < n; i++) + bp[i] = (int32) v[i]; + if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp)) + goto out; + } + break; + case TIFF_FLOAT: + { float* bp = (float*) w; + for (i = 0; i < n; i++) + bp[i] = (float) v[i]; + if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp)) + goto out; + } + break; + case TIFF_DOUBLE: + return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v)); + default: + /* TIFF_NOTYPE */ + /* TIFF_ASCII */ + /* TIFF_UNDEFINED */ + /* TIFF_RATIONAL */ + /* TIFF_SRATIONAL */ + goto out; + } + status = 1; + out: + if (w != buf) + _TIFFfree(w); + return (status); +} + +#ifdef COLORIMETRY_SUPPORT +static int +TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir) +{ + TIFFDirectory* td = &tif->tif_dir; + tsize_t n = (1L<td_bitspersample) * sizeof (uint16); + uint16** tf = td->td_transferfunction; + int ncols; + + /* + * Check if the table can be written as a single column, + * or if it must be written as 3 columns. Note that we + * write a 3-column tag if there are 2 samples/pixel and + * a single column of data won't suffice--hmm. + */ + switch (td->td_samplesperpixel - td->td_extrasamples) { + default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; } + case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; } + case 1: case 0: ncols = 1; + } + return (TIFFWriteShortTable(tif, + TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf)); +} +#endif + +/* + * Write a contiguous directory item. + */ +static int +TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + tsize_t cc; + + if (tif->tif_flags & TIFF_SWAB) { + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); + break; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); + break; + case TIFF_DOUBLE: + TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); + break; + } + } + dir->tdir_offset = tif->tif_dataoff; + cc = dir->tdir_count * tiffDataWidth[dir->tdir_type]; + if (SeekOK(tif, dir->tdir_offset) && + WriteOK(tif, cp, cc)) { + tif->tif_dataoff += (cc + 1) & ~1; + return (1); + } + TIFFError(tif->tif_name, "Error writing data for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + return (0); +} + +/* + * Link the current directory into the + * directory chain for the file. + */ +static int +TIFFLinkDirectory(TIFF* tif) +{ + static const char module[] = "TIFFLinkDirectory"; + uint32 nextdir; + uint32 diroff; + + tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; + diroff = (uint32) tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&diroff); +#if SUBIFD_SUPPORT + if (tif->tif_flags & TIFF_INSUBIFD) { + (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(module, + "%s: Error writing SubIFD directory link", + tif->tif_name); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += sizeof (diroff); + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } +#endif + if (tif->tif_header.tiff_diroff == 0) { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff; +#define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f)) + (void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET); + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(tif->tif_name, "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + nextdir = tif->tif_header.tiff_diroff; + do { + uint16 dircount; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount, sizeof (dircount))) { + TIFFError(module, "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void) TIFFSeekFile(tif, + dircount * sizeof (TIFFDirEntry), SEEK_CUR); + if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { + TIFFError(module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir); + } while (nextdir != 0); + (void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR); + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(module, "Error writing directory link"); + return (0); + } + return (1); +} diff --git a/contrib/ras/README b/contrib/ras/README new file mode 100644 index 00000000..f87bfde0 --- /dev/null +++ b/contrib/ras/README @@ -0,0 +1,10 @@ +Sun May 19 22:28:16 PDT 1991 + +These programs are from Patrick Naughton (naughton@wind.sun.com). +I've tried to update them to reflect changes to the library, but +I am unable to verify that they operate properly, because they +require the Sun pixrect library. + +Please contact Patrick directly if you have questions/problems. + + Sam diff --git a/contrib/ras/ras2tif.c b/contrib/ras/ras2tif.c new file mode 100644 index 00000000..25c59021 --- /dev/null +++ b/contrib/ras/ras2tif.c @@ -0,0 +1,244 @@ +#ifndef lint +static char sccsid[] = "@(#)ras2tif.c 1.2 90/03/06"; +#endif +/*- + * ras2tif.c - Converts from a Sun Rasterfile to a Tagged Image File. + * + * Copyright (c) 1990 by Sun Microsystems, Inc. + * + * Author: Patrick J. Naughton + * naughton@wind.sun.com + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Comments and additions should be sent to the author: + * + * Patrick J. Naughton + * Sun Microsystems + * 2550 Garcia Ave, MS 14-40 + * Mountain View, CA 94043 + * (415) 336-1080 + * + * Revision History: + * 11-Jan-89: Created. + * 06-Mar-90: fix bug in SCALE() macro. + * got rid of xres and yres, (they weren't working anyways). + * fixed bpsl calculation. + * + * Description: + * This program takes a Sun Rasterfile [see rasterfile(5)] as input and + * writes a MicroSoft/Aldus "Tagged Image File Format" image or "TIFF" file. + * The input file may be standard input, but the output TIFF file must be a + * real file since seek(2) is used. + */ + +#include +#include +#include +#include "tiffio.h" + +typedef int boolean; +#define True (1) +#define False (0) +#define SCALE(x) (((x)*((1L<<16)-1))/255) + +boolean Verbose = False; +boolean dummyinput = False; +char *pname; /* program name (used for error messages) */ + +void +error(s1, s2) + char *s1, + *s2; +{ + fprintf(stderr, s1, pname, s2); + exit(1); +} + +void +usage() +{ + error("usage: %s -[vq] [-|rasterfile] TIFFfile\n", NULL); +} + + +main(argc, argv) + int argc; + char *argv[]; +{ + char *inf = NULL; + char *outf = NULL; + FILE *fp; + int depth, + i; + long row; + TIFF *tif; + Pixrect *pix; /* The Sun Pixrect */ + colormap_t Colormap; /* The Pixrect Colormap */ + u_short red[256], + green[256], + blue[256]; + struct tm *ct; + struct timeval tv; + long width, + height; + long rowsperstrip; + short photometric; + short samplesperpixel; + short bitspersample; + int bpsl; + static char *version = "ras2tif 1.0"; + static char *datetime = "1990:01:01 12:00:00"; + + gettimeofday(&tv, (struct timezone *) NULL); + ct = localtime(&tv.tv_sec); + sprintf(datetime, "19%02d:%02d:%02d %02d:%02d:%02d", + ct->tm_year, ct->tm_mon + 1, ct->tm_mday, + ct->tm_hour, ct->tm_min, ct->tm_sec); + + setbuf(stderr, NULL); + pname = argv[0]; + + while (--argc) { + if ((++argv)[0][0] == '-') { + switch (argv[0][1]) { + case 'v': + Verbose = True; + break; + case 'q': + usage(); + break; + case '\0': + if (inf == NULL) + dummyinput = True; + else + usage(); + break; + default: + fprintf(stderr, "%s: illegal option -%c.\n", pname, + argv[0][1]); + exit(1); + } + } else if (inf == NULL && !dummyinput) { + inf = argv[0]; + } else if (outf == NULL) + outf = argv[0]; + else + usage(); + } + + if (outf == NULL) + error("%s: can't write output file to a stream.\n", NULL); + + if (dummyinput || inf == NULL) { + inf = "Standard Input"; + fp = stdin; + } else if ((fp = fopen(inf, "r")) == NULL) + error("%s: %s couldn't be opened.\n", inf); + + if (Verbose) + fprintf(stderr, "Reading rasterfile from %s...", inf); + + pix = pr_load(fp, &Colormap); + if (pix == NULL) + error("%s: %s is not a raster file.\n", inf); + + if (Verbose) + fprintf(stderr, "done.\n"); + + if (Verbose) + fprintf(stderr, "Writing %s...", outf); + + tif = TIFFOpen(outf, "w"); + + if (tif == NULL) + error("%s: error opening TIFF file %s", outf); + + width = pix->pr_width; + height = pix->pr_height; + depth = pix->pr_depth; + + switch (depth) { + case 1: + samplesperpixel = 1; + bitspersample = 1; + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 8: + samplesperpixel = 1; + bitspersample = 8; + photometric = PHOTOMETRIC_PALETTE; + break; + case 24: + samplesperpixel = 3; + bitspersample = 8; + photometric = PHOTOMETRIC_RGB; + break; + case 32: + samplesperpixel = 4; + bitspersample = 8; + photometric = PHOTOMETRIC_RGB; + break; + default: + error("%s: bogus depth: %d\n", depth); + } + + bpsl = ((depth * width + 15) >> 3) & ~1; + rowsperstrip = (8 * 1024) / bpsl; + + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample); + TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, inf); + TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "converted Sun rasterfile"); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + TIFFSetField(tif, TIFFTAG_STRIPBYTECOUNTS, height / rowsperstrip); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_SOFTWARE, version); + TIFFSetField(tif, TIFFTAG_DATETIME, datetime); + + memset(red, 0, sizeof(red)); + memset(green, 0, sizeof(green)); + memset(blue, 0, sizeof(blue)); + if (depth == 8) { + TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue); + for (i = 0; i < Colormap.length; i++) { + red[i] = SCALE(Colormap.map[0][i]); + green[i] = SCALE(Colormap.map[1][i]); + blue[i] = SCALE(Colormap.map[2][i]); + } + } + if (Verbose) + fprintf(stderr, "%dx%dx%d image, ", width, height, depth); + + for (row = 0; row < height; row++) + if (TIFFWriteScanline(tif, + (u_char *) mprd_addr(mpr_d(pix), 0, row), + row, 0) < 0) { + fprintf("failed a scanline write (%d)\n", row); + break; + } + TIFFFlushData(tif); + TIFFClose(tif); + + if (Verbose) + fprintf(stderr, "done.\n"); + + pr_destroy(pix); + + exit(0); +} diff --git a/contrib/ras/tif2ras.c b/contrib/ras/tif2ras.c new file mode 100644 index 00000000..344c94de --- /dev/null +++ b/contrib/ras/tif2ras.c @@ -0,0 +1,337 @@ +#ifndef lint +static char sccsid[] = "@(#)tif2ras.c 1.2 90/03/06"; +#endif +/*- + * tif2ras.c - Converts from a Tagged Image File Format image to a Sun Raster. + * + * Copyright (c) 1990 by Sun Microsystems, Inc. + * + * Author: Patrick J. Naughton + * naughton@wind.sun.com + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Comments and additions should be sent to the author: + * + * Patrick J. Naughton + * Sun Microsystems + * 2550 Garcia Ave, MS 14-40 + * Mountain View, CA 94043 + * (415) 336-1080 + * + * Revision History: + * 10-Jan-89: Created. + * 06-Mar-90: Change to byte encoded rasterfiles. + * fix bug in call to ReadScanline(). + * fix bug in CVT() macro. + * fix assignment of td, (missing &). + * + * Description: + * This program takes a MicroSoft/Aldus "Tagged Image File Format" image or + * "TIFF" file as input and writes a Sun Rasterfile [see rasterfile(5)]. The + * output file may be standard output, but the input TIFF file must be a real + * file since seek(2) is used. + */ + +#include +#include +#include "tiffio.h" + +typedef int boolean; +#define True (1) +#define False (0) +#define CVT(x) (((x) * 255) / ((1L<<16)-1)) + +boolean Verbose = False; +char *pname; /* program name (used for error messages) */ + +void +error(s1, s2) + char *s1, + *s2; +{ + fprintf(stderr, s1, pname, s2); + exit(1); +} + +void +usage() +{ + error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL); +} + + +main(argc, argv) + int argc; + char *argv[]; +{ + char *inf = NULL; + char *outf = NULL; + FILE *fp; + long width, + height; + int depth, + numcolors; + register TIFF *tif; + TIFFDirectory *td; + register u_char *inp, + *outp; + register int col, + i; + register long row; + u_char *Map = NULL; + u_char *buf; + short bitspersample; + short samplesperpixel; + short photometric; + u_short *redcolormap, + *bluecolormap, + *greencolormap; + + Pixrect *pix; /* The Sun Pixrect */ + colormap_t Colormap; /* The Pixrect Colormap */ + u_char red[256], + green[256], + blue[256]; + + setbuf(stderr, NULL); + pname = argv[0]; + + while (--argc) { + if ((++argv)[0][0] == '-') + switch (argv[0][1]) { + case 'v': + Verbose = True; + break; + case 'q': + usage(); + break; + default: + fprintf(stderr, "%s: illegal option -%c.\n", pname, + argv[0][1]); + exit(1); + } + else if (inf == NULL) + inf = argv[0]; + else if (outf == NULL) + outf = argv[0]; + else + usage(); + + } + + if (inf == NULL) + error("%s: can't read input file from a stream.\n", NULL); + + if (Verbose) + fprintf(stderr, "Reading %s...", inf); + + tif = TIFFOpen(inf, "r"); + + if (tif == NULL) + error("%s: error opening TIFF file %s", inf); + + if (Verbose) + TIFFPrintDirectory(tif, stderr, True, False, False); + TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); + if (bitspersample > 8) + error("%s: can't handle more than 8-bits per sample\n", NULL); + + TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + switch (samplesperpixel) { + case 1: + if (bitspersample == 1) + depth = 1; + else + depth = 8; + break; + case 3: + case 4: + depth = 24; + break; + default: + error("%s: only handle 1-channel gray scale or 3-channel color\n"); + } + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); + + if (Verbose) + fprintf(stderr, "%dx%dx%d image, ", width, height, depth); + if (Verbose) + fprintf(stderr, "%d bits/sample, %d samples/pixel, ", + bitspersample, samplesperpixel); + + pix = mem_create(width, height, depth); + if (pix == (Pixrect *) NULL) + error("%s: can't allocate memory for output pixrect...\n", NULL); + + numcolors = (1 << bitspersample); + + TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric); + if (numcolors == 2) { + if (Verbose) + fprintf(stderr, "monochrome "); + Colormap.type = RMT_NONE; + Colormap.length = 0; + Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL; + } else { + switch (photometric) { + case PHOTOMETRIC_MINISBLACK: + if (Verbose) + fprintf(stderr, "%d graylevels (min=black), ", numcolors); + Map = (u_char *) malloc(numcolors * sizeof(u_char)); + for (i = 0; i < numcolors; i++) + Map[i] = (255 * i) / numcolors; + Colormap.type = RMT_EQUAL_RGB; + Colormap.length = numcolors; + Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map; + break; + case PHOTOMETRIC_MINISWHITE: + if (Verbose) + fprintf(stderr, "%d graylevels (min=white), ", numcolors); + Map = (u_char *) malloc(numcolors * sizeof(u_char)); + for (i = 0; i < numcolors; i++) + Map[i] = 255 - ((255 * i) / numcolors); + Colormap.type = RMT_EQUAL_RGB; + Colormap.length = numcolors; + Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map; + break; + case PHOTOMETRIC_RGB: + if (Verbose) + fprintf(stderr, "truecolor "); + Colormap.type = RMT_NONE; + Colormap.length = 0; + Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL; + break; + case PHOTOMETRIC_PALETTE: + if (Verbose) + fprintf(stderr, "colormapped "); + Colormap.type = RMT_EQUAL_RGB; + Colormap.length = numcolors; + memset(red, 0, sizeof(red)); + memset(green, 0, sizeof(green)); + memset(blue, 0, sizeof(blue)); + TIFFGetField(tif, TIFFTAG_COLORMAP, + &redcolormap, &greencolormap, &bluecolormap); + for (i = 0; i < numcolors; i++) { + red[i] = (u_char) CVT(redcolormap[i]); + green[i] = (u_char) CVT(greencolormap[i]); + blue[i] = (u_char) CVT(bluecolormap[i]); + } + Colormap.map[0] = red; + Colormap.map[1] = green; + Colormap.map[2] = blue; + break; + case PHOTOMETRIC_MASK: + error("%s: Don't know how to handle PHOTOMETRIC_MASK\n"); + break; + case PHOTOMETRIC_DEPTH: + error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n"); + break; + default: + error("%s: unknown photometric (cmap): %d\n", photometric); + } + } + + buf = (u_char *) malloc(TIFFScanlineSize(tif)); + if (buf == NULL) + error("%s: can't allocate memory for scanline buffer...\n", NULL); + + for (row = 0; row < height; row++) { + if (TIFFReadScanline(tif, buf, row, 0) < 0) + error("%s: bad data read on line: %d\n", row); + inp = buf; + outp = (u_char *) mprd_addr(mpr_d(pix), 0, row); + switch (photometric) { + case PHOTOMETRIC_RGB: + if (samplesperpixel == 4) + for (col = 0; col < width; col++) { + *outp++ = *inp++; /* Blue */ + *outp++ = *inp++; /* Green */ + *outp++ = *inp++; /* Red */ + inp++; /* skip alpha channel */ + } + else + for (col = 0; col < width; col++) { + *outp++ = *inp++; /* Blue */ + *outp++ = *inp++; /* Green */ + *outp++ = *inp++; /* Red */ + } + break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + switch (bitspersample) { + case 1: + for (col = 0; col < ((width + 7) / 8); col++) + *outp++ = *inp++; + break; + case 2: + for (col = 0; col < ((width + 3) / 4); col++) { + *outp++ = (*inp >> 6) & 3; + *outp++ = (*inp >> 4) & 3; + *outp++ = (*inp >> 2) & 3; + *outp++ = *inp++ & 3; + } + break; + case 4: + for (col = 0; col < width / 2; col++) { + *outp++ = *inp >> 4; + *outp++ = *inp++ & 0xf; + } + break; + case 8: + for (col = 0; col < width; col++) + *outp++ = *inp++; + break; + default: + error("%s: bad bits/sample: %d\n", bitspersample); + } + break; + case PHOTOMETRIC_PALETTE: + memcpy(outp, inp, width); + break; + default: + error("%s: unknown photometric (write): %d\n", photometric); + } + } + + free((char *) buf); + + if (Verbose) + fprintf(stderr, "done.\n"); + + if (outf == NULL || strcmp(outf, "Standard Output") == 0) { + outf = "Standard Output"; + fp = stdout; + } else { + if (!(fp = fopen(outf, "w"))) + error("%s: %s couldn't be opened for writing.\n", outf); + } + + if (Verbose) + fprintf(stderr, "Writing rasterfile in %s...", outf); + + if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR) + error("%s: error writing Sun Rasterfile: %s\n", outf); + + if (Verbose) + fprintf(stderr, "done.\n"); + + pr_destroy(pix); + + if (fp != stdout) + fclose(fp); + + exit(0); +} diff --git a/contrib/vms/libtiff/makevms.com b/contrib/vms/libtiff/makevms.com new file mode 100755 index 00000000..90964e85 --- /dev/null +++ b/contrib/vms/libtiff/makevms.com @@ -0,0 +1,229 @@ +$!======================================================================== +$! +$! Name : MAKEVMS +$! +$! Purpose : Compile TIFF library +$! +$! Arguments : If P1 is DEBUG, compile with debug +$! +$! Created 1-DEC-1994 Karsten Spang +$! +$!======================================================================== +$ CURRENT_DIR=F$ENVIRONMENT("DEFAULT") +$ ON CONTROL_Y THEN GOTO EXIT +$ ON ERROR THEN GOTO EXIT +$! +$! Get hold on definitions +$! +$! Older versions of VMS may not recoqnize the "ARCH_NAME" keyword +$! This happens only on VAX +$! +$ SAVE_MESS=F$ENVIRONMENT("MESSAGE") +$ SET MESSAGE/NOID/NOFAC/NOSEV/NOTEXT +$ ARCH=F$GETSYI("ARCH_NAME") +$ SET MESSAGE 'SAVE_MESS' +$ IF F$TYPE(ARCH).EQS."" THEN ARCH="VAX" +$ ARCH=F$EDIT(ARCH,"UPCASE") +$! +$ DEFINE/NOLOG SYS SYS$LIBRARY +$ THIS_FILE=F$ENVIRONMENT("PROCEDURE") +$ PROC_NAME=F$PARSE(THIS_FILE,,,"NAME","SYNTAX_ONLY") +$ THIS_DIR=F$PARSE(THIS_FILE,,,"DEVICE","SYNTAX_ONLY")+ - + F$PARSE(THIS_FILE,,,"DIRECTORY","SYNTAX_ONLY") +$ SET DEFAULT 'THIS_DIR' +$ IF ARCH.EQS."ALPHA" +$ THEN +$ CONF_FP="HAVE_IEEEFP=1" +$ ELSE +$ CONF_FP="HAVE_IEEEFP=0" +$ ENDIF +$ CONF_LIBRARY="BSDTYPES,HAVE_MMAP" +$ IF P1.EQS."DEBUG" +$ THEN +$ DEBUG_OPTIONS="/DEBUG/NOOPTIMIZE" +$ CONF_LIBRARY=CONF_LIBRARY+",DEBUG" +$ LINK_OPTIONS="/DEBUG" +$ ELSE +$ DEBUG_OPTIONS="" +$ LINK_OPTIONS="" +$ ENDIF +$ DEFINES="/DEFINE=("+CONF_FP+","+CONF_LIBRARY+")" +$ C_COMPILE="CC"+DEBUG_OPTIONS+DEFINES +$ IF ARCH.EQS."ALPHA" +$ THEN +$! +$! You may want a different floating point option +$! +$ C_COMPILE=C_COMPILE+ - + "/FLOAT=IEEE_FLOAT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES" +$ ENDIF +$! +$ SOURCES="TIF_AUX,TIF_CLOSE,TIF_CODEC,TIF_COMPRESS,"+ - + "TIF_DIR,TIF_DIRINFO,TIF_DIRREAD,TIF_DIRWRITE,"+ - + "TIF_DUMPMODE,TIF_ERROR,TIF_FAX3,TIF_FAX3SM,TIF_FLUSH,TIF_GETIMAGE,"+ - +-! "TIF_JPEG,"+ - + "TIF_LZW,TIF_NEXT,TIF_OPEN,TIF_PACKBITS,TIF_PIXARLOG,TIF_PREDICT,"+ - + "TIF_PRINT,TIF_READ,TIF_STRIP,TIF_SWAB,TIF_THUNDER,TIF_TILE,"+ - + "TIF_VERSION,TIF_VMS,TIF_WARNING,TIF_WRITE" +! ",TIF_ZIP" +$ LIBFILE="TIFF" +$ IF F$SEARCH(LIBFILE+".OLB").EQS."" THEN - + LIBRARY/CREATE 'LIBFILE' +$! +$! Create the port library +$! +$ LIBPORT="[-.PORT]PORT" +$ IF F$SEARCH(LIBPORT+".OLB") .EQS "" +$ THEN +$ WRITE SYS$OUTPUT "Creating PORT.OLB" +$ LIBRARY/CREATE 'LIBPORT' +$ CREATE DUM.C +main(){getopt();strtoul();strcasecmp();} +$ C_COMPILE DUM +$ SET MESSAGE/ID/FAC/SEV/TEXT +$ DEFINE/USER SYS$OUTPUT LINK.WARNINGS +$ DEFINE/USER SYS$ERROR NLA0: +$ IF ARCH.EQS."ALPHA" +$ THEN +$ LINK DUM +$ ELSE +$ LINK DUM,SYS$INPUT:/OPTIONS +SYS$SHARE:VAXCRTL/SHARE +$ ENDIF +$ DELETE DUM.C;,DUM.OBJ;,DUM.EXE; +$ SEARCH/OUT=MISSING.OBJECTS LINK.WARNINGS LINK-I-UDFSYM +$ DELETE LINK.WARNINGS; +$ OPEN/READ MISSING MISSING.OBJECTS +$NEXTMIS: +$ READ/END=NOMOREMIS MISSING LINE +$ LINE=F$EDIT(LINE,"TRIM,COMPRESS,UPCASE") +$ LINE=F$ELEMENT(1," ",LINE) +$ IF LINE .EQS. " " THEN GOTO NEXTMIS +$ WRITE SYS$OUTPUT " "+LINE +$ C_COMPILE/OBJECT=[-.PORT]'LINE' [-.PORT]'LINE' +$ LIBRARY 'LIBPORT' [-.PORT]'LINE' +$ DELETE [-.PORT]'LINE'.OBJ; +$ GOTO NEXTMIS +$NOMOREMIS: +$ CLOSE MISSING +$ DELETE MISSING.OBJECTS; +$ ENDIF +$! +$! Create VERSION.H +$! +$ IF F$SEARCH("VERSION.H").EQS."" +$ THEN +$ WRITE SYS$OUTPUT "Creating VERSION.H" +$ IF F$SEARCH("MKVERSION.EXE").EQS."" +$ THEN +$ IF F$SEARCH("MKVERSION.OBJ").EQS."" +$ THEN +$ C_COMPILE MKVERSION +$ ENDIF +$ IF ARCH.EQS."ALPHA" +$ THEN +$ LINK MKVERSION,'LIBPORT'/LIBRARY +$ ELSE +$ LINK MKVERSION,'LIBPORT'/LIBRARY,SYS$INPUT:/OPTIONS +SYS$SHARE:VAXCRTL/SHARE +$ ENDIF +$ DELETE MKVERSION.OBJ;* +$ ENDIF +$ MKVERSION:=$'THIS_DIR'MKVERSION +$ MKVERSION -V [-]VERSION -A [-.DIST]TIFF.ALPHA VERSION.H +$ DELETE MKVERSION.EXE;* +$ ENDIF +$! +$! Create TIF_FAX3SM.C +$! +$ IF F$SEARCH("TIF_FAX3SM.C").EQS."" +$ THEN +$ WRITE SYS$OUTPUT "Creating FAX3SM.C" +$ IF F$SEARCH("MKG3STATES.EXE").EQS."" +$ THEN +$ IF F$SEARCH("MKG3STATES.OBJ").EQS."" +$ THEN +$ C_COMPILE MKG3STATES +$ ENDIF +$ IF ARCH.EQS."ALPHA" +$ THEN +$ LINK MKG3STATES,'LIBPORT'/LIBRARY +$ ELSE +$ LINK MKG3STATES,'LIBPORT'/LIBRARY,SYS$INPUT:/OPTIONS +SYS$SHARE:VAXCRTL/SHARE +$ ENDIF +$ DELETE MKG3STATES.OBJ;* +$ ENDIF +$ MKG3STATES:=$'THIS_DIR'MKG3STATES +$ MKG3STATES -c const TIF_FAX3SM.C +$ DELETE MKG3STATES.EXE;* +$ ENDIF +$! +$! Loop over modules +$! +$ NUMBER=0 +$COMPILE_LOOP: +$ FILE=F$ELEMENT(NUMBER,",",SOURCES) +$ IF FILE.EQS."," THEN GOTO END_COMPILE +$ C_FILE=F$PARSE(FILE,".C",,,"SYNTAX_ONLY") +$ C_FILE=F$SEARCH(C_FILE) +$ IF C_FILE.EQS."" +$ THEN +$ WRITE SYS$OUTPUT "Source file "+FILE+" not found" +$ GOTO EXIT +$ ENDIF +$ C_DATE=F$CVTIME(F$FILE_ATTRIBUTES(C_FILE,"RDT")) +$ OBJ_FILE=F$PARSE("",".OBJ",C_FILE,,"SYNTAX_ONLY") +$ OBJ_FILE=F$EXTRACT(0,F$LOCATE(";",OBJ_FILE),OBJ_FILE) +$ FOUND_OBJ_FILE=F$SEARCH(OBJ_FILE) +$ IF FOUND_OBJ_FILE.EQS."" +$ THEN +$ OBJ_DATE="" +$ ELSE +$ OBJ_DATE=F$CVTIME(F$FILE_ATTRIBUTES(FOUND_OBJ_FILE,"CDT")) +$ ENDIF +$ IF OBJ_DATE.LTS.C_DATE +$ THEN +$ WRITE SYS$OUTPUT "Compiling "+FILE +$ ON ERROR THEN CONTINUE +$ C_COMPILE/OBJECT='OBJ_FILE' 'C_FILE' +$ ON ERROR THEN GOTO EXIT +$ LIBRARY 'LIBFILE' 'OBJ_FILE' +$ +$ ENDIF +$ NUMBER=NUMBER+1 +$ GOTO COMPILE_LOOP +$END_COMPILE: +$ IF ARCH.EQS."ALPHA" +$ THEN +$ OPT_FILE="TIFFSHRAXP" +$ ELSE +$ OPT_FILE="TIFFSHRVAX" +$ FILE="TIFFVEC" +$ MAR_FILE=F$PARSE(FILE,".MAR",,,"SYNTAX_ONLY") +$ MAR_FILE=F$SEARCH(MAR_FILE) +$ MAR_FILE=F$SEARCH("TIFFVEC.MAR") +$ MAR_DATE=F$CVTIME(F$FILE_ATTRIBUTES(MAR_FILE,"RDT")) +$ OBJ_FILE=F$PARSE("",".OBJ",MAR_FILE,,"SYNTAX_ONLY") +$ OBJ_FILE=F$EXTRACT(0,F$LOCATE(";",OBJ_FILE),OBJ_FILE) +$ FOUND_OBJ_FILE=F$SEARCH(OBJ_FILE) +$ IF FOUND_OBJ_FILE.EQS."" +$ THEN +$ OBJ_DATE="" +$ ELSE +$ OBJ_DATE=F$CVTIME(F$FILE_ATTRIBUTES(FOUND_OBJ_FILE,"CDT")) +$ ENDIF +$ IF OBJ_DATE.LTS.MAR_DATE +$ THEN +$ WRITE SYS$OUTPUT "Compiling "+FILE +$ MACRO 'MAR_FILE' +$ LIBRARY 'LIBFILE' 'OBJ_FILE' +$ PURGE 'OBJ_FILE' +$ ENDIF +$ ENDIF +$ WRITE SYS$OUTPUT "Creating shareable library" +$ LINK/SHAREABLE='THIS_DIR'TIFFSHR'LINK_OPTIONS' 'OPT_FILE'/OPTIONS +$ PURGE/LOG TIFFSHR.EXE +$EXIT: +$ SET DEFAULT 'CURRENT_DIR' +$ EXIT diff --git a/contrib/vms/libtiff/tiff.opt b/contrib/vms/libtiff/tiff.opt new file mode 100755 index 00000000..587bf110 --- /dev/null +++ b/contrib/vms/libtiff/tiff.opt @@ -0,0 +1 @@ +TIFFSHR/SHAREABLE diff --git a/contrib/vms/libtiff/tiffshraxp.opt b/contrib/vms/libtiff/tiffshraxp.opt new file mode 100755 index 00000000..f8006516 --- /dev/null +++ b/contrib/vms/libtiff/tiffshraxp.opt @@ -0,0 +1,122 @@ +! VMS linker options file for linking the TIFF library into a shareable image +! +IDENTIFICATION="LIBTIFF 3.4-032" +! +! Please update the minor version number below, when adding new routines +GSMATCH=LEQUAL,1,9 +! +! Here goes the definitions of all public functions in the library, plus +! a few extra that are called by the tools. +! The sequence MUST NOT be changed, otherwise you will have to relink +! all applications. Add new functions at the end. +! +SYMBOL_VECTOR=(- + TIFFCheckTile=PROCEDURE,- + TIFFClose=PROCEDURE,- + TIFFComputeStrip=PROCEDURE,- + TIFFComputeTile=PROCEDURE,- + TIFFCurrentDirectory=PROCEDURE,- + TIFFCurrentRow=PROCEDURE,- + TIFFCurrentStrip=PROCEDURE,- + TIFFCurrentTile=PROCEDURE,- + TIFFError=PROCEDURE,- + TIFFFdOpen=PROCEDURE,- + TIFFFileName=PROCEDURE,- + TIFFFileno=PROCEDURE,- + TIFFFlush=PROCEDURE,- + TIFFFlushData=PROCEDURE,- + TIFFGetField=PROCEDURE,- + TIFFGetFieldDefaulted=PROCEDURE,- + TIFFGetMode=PROCEDURE,- + TIFFIsTiled=PROCEDURE,- + TIFFModeCCITTFax3=PRIVATE_PROCEDURE,- ! gone in 3.3 beta 024 + TIFFNumberOfStrips=PROCEDURE,- + TIFFNumberOfTiles=PROCEDURE,- + TIFFOpen=PROCEDURE,- + TIFFPrintDirectory=PROCEDURE,- + TIFFReadBufferSetup=PROCEDURE,- + TIFFReadDirectory=PROCEDURE,- + TIFFReadEncodedStrip=PROCEDURE,- + TIFFReadEncodedTile=PROCEDURE,- + TIFFReadRawStrip=PROCEDURE,- + TIFFReadRawTile=PROCEDURE,- + TIFFReadRGBAImage=PROCEDURE,- + TIFFReadScanline=PROCEDURE,- + TIFFReadTile=PROCEDURE,- + TIFFReverseBits=PROCEDURE,- + TIFFScanlineSize=PROCEDURE,- + TIFFSetDirectory=PROCEDURE,- + TIFFSetErrorHandler=PROCEDURE,- + TIFFSetField=PROCEDURE,- + TIFFSetWarningHandler=PROCEDURE,- + TIFFStripSize=PROCEDURE,- + TIFFSwabShort=PROCEDURE,- + TIFFSwabLong=PROCEDURE,- + TIFFSwabArrayOfShort=PROCEDURE,- + TIFFSwabArrayOfLong=PROCEDURE,- + TIFFTileRowSize=PROCEDURE,- + TIFFTileSize=PROCEDURE,- + TIFFVGetField=PROCEDURE,- + TIFFVGetFieldDefaulted=PROCEDURE,- + TIFFVSetField=PROCEDURE,- + TIFFWarning=PROCEDURE,- + TIFFWriteDirectory=PROCEDURE,- + TIFFWriteEncodedStrip=PROCEDURE,- + TIFFWriteEncodedTile=PROCEDURE,- + TIFFWriteRawStrip=PROCEDURE,- + TIFFWriteRawTile=PROCEDURE,- + TIFFWriteScanline=PROCEDURE,- + TIFFWriteTile=PROCEDURE,- +! +! New entries in version 3.1 +! + TIFFClientOpen=PROCEDURE,- + TIFFVStripSize=PROCEDURE,- ! For tiffcp +! +! New entries in version 3.2 +! + TIFFGetVersion=PROCEDURE,- + TIFFGetBitRevTable=PROCEDURE,- + _TIFFmalloc=PROCEDURE,- ! For fax2tiff +! +! New entries in version 3.3 +! + TIFFIsByteSwapped=PROCEDURE,- + TIFFSetWriteOffset=PROCEDURE,- +! +! New entries in version 3.3 beta 020 +! + TIFFSetSubDirectory=PROCEDURE,- + TIFFUnlinkDirectory=PROCEDURE,- +! +! These needs to be global on the Alpha (used in fax2tiff) +! + tiffDataWidth=DATA,- + tiffFieldInfo=DATA,- +! +! New entries in version 3.3 beta 026 (for the tools) +! + _TIFFfree=PROCEDURE,- + _TIFFrealloc=PROCEDURE,- + _TIFFmemset=PROCEDURE,- + _TIFFmemcpy=PROCEDURE,- + _TIFFmemcmp=PROCEDURE,- +! +! New entries in version 3.4 beta 002 +! + TIFFRasterScanlineSize=PROCEDURE,- + TIFFDefaultStripSize=PROCEDURE,- + TIFFDefaultTileSize=PROCEDURE,- + TIFFVTileSize=PROCEDURE,- ! not new, but omitted previously + TIFFSwabDouble=PROCEDURE,- + TIFFSwabArrayOfDouble=PROCEDURE,- + TIFFLastDirectory=PROCEDURE,- ! not new either +! +! New entries in version 3.4 beta 007 through 032 +! + TIFFCurrentDirOffset=PROCEDURE,- + TIFFWriteBufferSetup=PROCEDURE) +! +! Then take the object library +! +TIFF/LIBRARY diff --git a/contrib/vms/libtiff/tiffshrvax.opt b/contrib/vms/libtiff/tiffshrvax.opt new file mode 100755 index 00000000..28b7ea4d --- /dev/null +++ b/contrib/vms/libtiff/tiffshrvax.opt @@ -0,0 +1,18 @@ +! VMS linker options file for linking the TIFF library into a shareable image +! +IDENTIFICATION="LIBTIFF 3.4-032" +! +! Please update the minor version number below, when adding new routines +GSMATCH=LEQUAL,1,9 +! +! Place the transfer vector at the beginning of the image +! +CLUSTER=TIFFVEC,,,TIFFVEC +! +! Then take the object library +! +TIFF/LIBRARY/INCLUDE=(TIF_FAX3SM,TIF_CODEC) +! +! The C RTL shareable image +! +SYS$SHARE:VAXCRTL/SHARE diff --git a/contrib/vms/libtiff/tiffvec.mar b/contrib/vms/libtiff/tiffvec.mar new file mode 100755 index 00000000..f17e5b2b --- /dev/null +++ b/contrib/vms/libtiff/tiffvec.mar @@ -0,0 +1,131 @@ + .TITLE TIFFVEC - Transfer vector for TIFF library + .IDENT /LIBTIFF 3.4-002/ +; + .PSECT TIFFVEC,EXE,NOWRT,PIC,SHR,GBL,QUAD +; +; Macro that defines one entry in the transfer vector +; + .MACRO VECTOR,NAME + .ALIGN QUAD + .TRANSFER NAME + .MASK NAME + JMP L^NAME+2 + .ENDM +; +; Here goes the definitions of all public functions in the library, plus +; a few extra that are called by the tools. +; The sequence MUST NOT be changed, otherwise you will have to relink +; all applications. Add new functions at the end. +; + VECTOR TIFFCheckTile + VECTOR TIFFClose + VECTOR TIFFComputeStrip + VECTOR TIFFComputeTile + VECTOR TIFFCurrentDirectory + VECTOR TIFFCurrentRow + VECTOR TIFFCurrentStrip + VECTOR TIFFCurrentTile + VECTOR TIFFError + VECTOR TIFFFdOpen + VECTOR TIFFFileName + VECTOR TIFFFileno + VECTOR TIFFFlush + VECTOR TIFFFlushData + VECTOR TIFFGetField + VECTOR TIFFGetFieldDefaulted +; +; TIFFGetFileSize was removed in version 3.2. It has been replaced by a +; dummy value that makes the program abort with a privileged instruction +; fault, in case an old program calls TIFFGetFileSize. +; +; VECTOR TIFFGetFileSize + .QUAD 0 +; + VECTOR TIFFGetMode + VECTOR TIFFIsTiled +; +; TIFFModeCCITTFax3 gone in 3.3 beta 024 +; VECTOR TIFFModeCCITTFax3 + .QUAD 0 + VECTOR TIFFNumberOfStrips + VECTOR TIFFNumberOfTiles + VECTOR TIFFOpen + VECTOR TIFFPrintDirectory + VECTOR TIFFReadBufferSetup + VECTOR TIFFReadDirectory + VECTOR TIFFReadEncodedStrip + VECTOR TIFFReadEncodedTile + VECTOR TIFFReadRawStrip + VECTOR TIFFReadRawTile + VECTOR TIFFReadRGBAImage + VECTOR TIFFReadScanline + VECTOR TIFFReadTile + VECTOR TIFFReverseBits + VECTOR TIFFScanlineSize + VECTOR TIFFSetDirectory + VECTOR TIFFSetErrorHandler + VECTOR TIFFSetField + VECTOR TIFFSetWarningHandler + VECTOR TIFFStripSize + VECTOR TIFFSwabShort + VECTOR TIFFSwabLong + VECTOR TIFFSwabArrayOfShort + VECTOR TIFFSwabArrayOfLong + VECTOR TIFFTileRowSize + VECTOR TIFFTileSize + VECTOR TIFFVGetField + VECTOR TIFFVGetFieldDefaulted + VECTOR TIFFVSetField + VECTOR TIFFWarning + VECTOR TIFFWriteDirectory + VECTOR TIFFWriteEncodedStrip + VECTOR TIFFWriteEncodedTile + VECTOR TIFFWriteRawStrip + VECTOR TIFFWriteRawTile + VECTOR TIFFWriteScanline + VECTOR TIFFWriteTile +; +; New entries in version 3.1 +; + VECTOR TIFFClientOpen + VECTOR TIFFVStripSize ; For tiffcp +; +; New entries in version 3.2 +; + VECTOR TIFFGetVersion + VECTOR TIFFGetBitRevTable + VECTOR _TIFFmalloc ; For fax2tiff +; +; New entries in version 3.3 +; + VECTOR TIFFIsByteSwapped + VECTOR TIFFSetWriteOffset +; +; New entries in version 3.3 beta 020 +; + VECTOR TIFFSetSubDirectory + VECTOR TIFFUnlinkDirectory +; +; New entries in version 3.3 beta 026 (for the tools) +; + VECTOR _TIFFfree + VECTOR _TIFFrealloc + VECTOR _TIFFmemset + VECTOR _TIFFmemcpy + VECTOR _TIFFmemcmp +; +; New entries in version 3.4 beta 002 +; + VECTOR TIFFRasterScanlineSize + VECTOR TIFFDefaultStripSize + VECTOR TIFFDefaultTileSize + VECTOR TIFFVTileSize ; not new, but omitted previously + VECTOR TIFFSwabDouble + VECTOR TIFFSwabArrayOfDouble + VECTOR TIFFLastDirectory ; not new either +; +; New entries in version 3.4 beta 007 through 032 +; + VECTOR TIFFCurrentDirOffset + VECTOR TIFFWriteBufferSetup + .END diff --git a/contrib/vms/tools/makevms.com b/contrib/vms/tools/makevms.com new file mode 100755 index 00000000..174b94db --- /dev/null +++ b/contrib/vms/tools/makevms.com @@ -0,0 +1,113 @@ +$!======================================================================== +$! +$! Name : MAKEVMS +$! +$! Purpose : Compile TIFF tools +$! +$! Arguments : +$! +$! Created 6-DEC-1991 Karsten Spang +$! +$!======================================================================== +$ CURRENT_DIR=F$ENVIRONMENT("DEFAULT") +$ ON CONTROL_Y THEN GOTO EXIT +$ ON ERROR THEN GOTO EXIT +$! +$! Get hold on definitions +$! +$! Older versions of VMS may not recoqnize the "ARCH_NAME" keyword +$! This happens only on VAX +$! +$ SAVE_MESS=F$ENVIRONMENT("MESSAGE") +$ SET MESSAGE/NOID/NOFAC/NOSEV/NOTEXT +$ ARCH=F$GETSYI("ARCH_NAME") +$ SET MESSAGE 'SAVE_MESS' +$ IF F$TYPE(ARCH).EQS."" THEN ARCH="VAX" +$ ARCH=F$EDIT(ARCH,"UPCASE") +$! +$ DEFINE SYS SYS$LIBRARY +$ THIS_FILE=F$ENVIRONMENT("PROCEDURE") +$ PROC_NAME=F$PARSE(THIS_FILE,,,"NAME","SYNTAX_ONLY") +$ THIS_DIR=F$PARSE(THIS_FILE,,,"DEVICE","SYNTAX_ONLY")+ - + F$PARSE(THIS_FILE,,,"DIRECTORY","SYNTAX_ONLY") +$ SET DEFAULT 'THIS_DIR' +$ LIB_DIR=F$PARSE("[-.LIBTIFF]") +$ LIB_DIR=F$PARSE(LIB_DIR,,,"DEVICE","SYNTAX_ONLY")+ - + F$PARSE(LIB_DIR,,,"DIRECTORY","SYNTAX_ONLY") +$ DEFINE TIFFSHR 'LIB_DIR'TIFFSHR +$ CONF_LIBRARY="USE_VARARGS=0,USE_PROTOTYPES=1,USE_CONST=1,"+ - + "BSDTYPES,MMAP_SUPPORT" +$ IF ARCH.EQS."ALPHA" +$ THEN +$! +$! You may want a different floating point option +$! +$ CONF_FP="HAVE_IEEEFP=1" +$ ALPHA_OPT="/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES/FLOAT=IEEE_FLOAT" +$ ELSE +$ CONF_FP="HAVE_IEEEFP=0" +$ ALPHA_OPT="" +$ ENDIF +$ DEFINES="/DEFINE=("+CONF_LIBRARY+","+CONF_FP+")" +$ INCLUDES="/INCLUDE="+LIB_DIR +$ IF P1.EQS."DEBUG" +$ THEN +$ DEBUG_OPTIONS="/DEBUG/NOOPTIMIZE" +$ LINK_OPTIONS="/DEBUG" +$ ELSE +$ DEBUG_OPTIONS="" +$ LINK_OPTIONS="" +$ ENDIF +$ C_COMPILE="CC"+DEBUG_OPTIONS+DEFINES+INCLUDES+ALPHA_OPT +$ LIBPORT="[-.PORT]PORT" +$! +$ SOURCES="FAX2PS,FAX2TIFF,GIF2TIFF,PAL2RGB," + - + "PPM2TIFF,RAS2TIFF,RGB2YCBCR," + - + "THUMBNAIL,TIFF2BW," + - + "TIFF2PS,TIFFCMP,TIFFCP,TIFFDITHER," + - + "TIFFDUMP,TIFFINFO,TIFFMEDIAN,TIFFSPLIT,YCBCR" +$! +$! Loop over programs +$! +$ NUMBER=0 +$COMPILE_LOOP: +$ FILE=F$ELEMENT(NUMBER,",",SOURCES) +$ IF FILE.EQS."," THEN GOTO END_COMPILE +$ C_FILE=F$PARSE(FILE,".C",,,"SYNTAX_ONLY") +$ C_FILE=F$SEARCH(C_FILE) +$ IF C_FILE.EQS."" +$ THEN +$ WRITE SYS$OUTPUT "Source file "+FILE+" not found" +$ GOTO EXIT +$ ENDIF +$ C_DATE=F$CVTIME(F$FILE_ATTRIBUTES(C_FILE,"RDT")) +$ EXE_FILE=F$PARSE("",".EXE",C_FILE,,"SYNTAX_ONLY") +$ EXE_FILE=F$EXTRACT(0,F$LOCATE(";",EXE_FILE),EXE_FILE) +$ FOUND_EXE_FILE=F$SEARCH(EXE_FILE) +$ IF FOUND_EXE_FILE.EQS."" +$ THEN +$ EXE_DATE="" +$ ELSE +$ EXE_DATE=F$CVTIME(F$FILE_ATTRIBUTES(FOUND_EXE_FILE,"CDT")) +$ ENDIF +$ IF EXE_DATE.LTS.C_DATE +$ THEN +$ WRITE SYS$OUTPUT "Compiling "+FILE +$ C_COMPILE 'FILE' +$ IF ARCH.EQS."ALPHA" +$ THEN +$ LINK'LINK_OPTIONS' 'FILE','LIBPORT'/LIB,'LIB_DIR'TIFF/OPTIONS +$ ELSE +$ LINK'LINK_OPTIONS' 'FILE','LIBPORT'/LIB, - + 'LIB_DIR'TIFF/OPTIONS,SYS$INPUT:/OPTIONS +SYS$SHARE:VAXCRTL/SHAREABLE +$ ENDIF +$ DELETE 'FILE'.OBJ;* +$ PURGE 'EXE_FILE' +$ ENDIF +$ NUMBER=NUMBER+1 +$ GOTO COMPILE_LOOP +$END_COMPILE: +$EXIT: +$ SET DEFAULT 'CURRENT_DIR' +$ EXIT diff --git a/contrib/win32/README b/contrib/win32/README new file mode 100644 index 00000000..649f829e --- /dev/null +++ b/contrib/win32/README @@ -0,0 +1,111 @@ +This mail from Scott describes changes to the library that I have +not made because I couldn't figure out exactly where they went. +Anything not in this file has either been placed in the appropriate +directory (e.g. libtiff/tif_win32.c) or applied to the current +source code (e.g. libtiff/tiffiop.h). + +Note that the Window NT/Window 95 support is untested; Scott's work +was done with an earlier version of the library. Hopefully this'll +get cleaned up soon. + + Sam + +Date: Fri, 14 Apr 95 17:01:42 EDT +From: wagner@itek.com (scott wagner) +Message-Id: <9504142101.AA00764@cyan.> +To: sam@cthulhu.engr.sgi.com +Subject: Re: Libtiff for Win32 (Windows NT / Windows 95) + +Hi, Sam! + +Enclosed are my libtiff for win32 pieces. They are in the form of 3 files +(tif_w32.c, dllshell.c, and libtiff.def), and 2 diffs (for tiffiop.h and +tiffio.h). + +Hope this is not too difficult to separate! + +Regards, +Scott Wagner (wagner@itek.com) + +tif_w32.c --------------------------------------------------------------- + +tiffiop.h --------------------------------------------------------------- + +tiffio.h --------------------------------------------------------------- +38a39 +> #ifdef _TIFFIOP_ +39a41,43 +> #else +> typedef void TIFF; /* Avoid ANSI undefined structure warning */ +> #endif +66a71,75 +> #ifdef WIN32 /* WIN32 identifies Win32 compiles */ +> #pragma warn -sig /* Turn off Borland warn of long to short int convert */ +> #pragma warn -par /* Turn off Borland warn "Parameter x is never used" */ +> DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +> #else /* if not WIN32_ */ +67a77 +> #endif /* defined WIN32 */ + +(Message tiff:1396) + -- using template mhl.format -- +Date: Mon, 17 Apr 1995 07:51:03 EDT +To: sam@cthulhu.engr.sgi.com + +From: wagner@itek.com (scott wagner) +Subject: Libtiff for Win32 + +Return-Path: sam@flake.asd.sgi.com +Delivery-Date: Mon, 17 Apr 1995 05:36:50 PDT +Return-Path: sam@flake.asd.sgi.com + +Hello, Sam! + +> ... libtiff for win32 pieces. They are in the form of 3 files +> (tif_w32.c, dllshell.c, and libtiff.def), and 2 diffs (for tiffiop.h and +> tiffio.h). +> +> I don't understand how these pieces fit together. Can you please explain +> what dllshell.c and libtiff.def are for? + +Sorry I was short on documentation here ... I was rushing to get home to +dinner on Friday and the material for you was the last loose end I had to +deal with. Excuses aside ... + +The goal of the adaptation of libtiff to Win32 was to replace only one +environment-specific code module and to make minimal changes to header +files. tif_win32.c required one addition to tiffio.h (the +DECLARE_HANDLE line, which is probably a better way to typedef thandle-t +under Windows 3.1 as well); it also required the addition of pv_map_handle +to the tiff structure and the conditional definition of the +TIFFUnmapFileContents macro in tiffiop.h (this because Win32 uses a handle +and a pointer in mapping memory, and I needed to save both). + +Additionally, I made a general style change to tiffio.h. If tiffio.h is +included by a client, which does not include tiffiop.h, then ANSI compilers +warn about the typedef of TIFF to a non-existent structure. To avoid this, +I changed the typedef of TIFF in this case to void. + +I also made a style change in the tiff structure. All references to tif_fd +in the library treat it as int, yet the tif_fd member itself is short. I +changed this member to int and added the reserved member to maintain +32-bit structure member alignment in a 32 bit environment. [ At cost of +4 more bytes in an already bloated structure! :-) ] As long as fd's are +less than 64k, the old member works; this is not the case in Win32, and is +not generally a safe assumption. + +The module dllshell.c and the file libtiff.def are not specific to the +functionality of libtiff; they are used to make a Win32 dynamic link +library, and would be best packaged with a Win32 makefile, which I have +not yet perfected. I will, however, commit to a Borland and Microsoft C +makefile for libtiff; perhaps these two could be combined with the +makefile for the _next_ (!) release of libtiff when it is ready. + +Once again, sorry for the confused message on Friday. I hope that at +least tif_w32 and the tiffio.h and tiffiop.h diffs will be useful for +this release. + +Regards, +Scott Wagner (wagner@itek.com) +Itek Graphix +Rochester, NY diff --git a/contrib/win32/dllshell.c b/contrib/win32/dllshell.c new file mode 100644 index 00000000..839ebdb5 --- /dev/null +++ b/contrib/win32/dllshell.c @@ -0,0 +1,38 @@ +dllshell.c --------------------------------------------------------------- +#define STRICT +#include +#pragma hdrstop + +#pragma argsused + +/* DLL has an entry point LibMain || DllEntryPoint and an exit point WEP. */ + +#if defined(__FLAT__) + +BOOL WINAPI DllEntryPoint(HINSTANCE hinstDll, DWORD fdwRreason, + LPVOID plvReserved) +{ + return 1; /* Indicate that the DLL was initialized successfully. */ +} + +#else /* not flat model */ + +int FAR PASCAL LibMain(HINSTANCE hInstance, WORD wDataSegment, WORD wHeapSize, + LPSTR lpszCmdLine) +{ +/* The startup code for the DLL initializes the local heap(if there is one) + with a call to LocalInit which locks the data segment. */ + + if ( wHeapSize != 0 ) + UnlockData( 0 ); + return 1; /* Indicate that the DLL was initialized successfully. */ +} + +#endif /* __FLAT */ + +#pragma argsused + +int FAR PASCAL WEP ( int bSystemExit ) +{ + return 1; +} diff --git a/contrib/win32/libtiff.def b/contrib/win32/libtiff.def new file mode 100644 index 00000000..7f41bed3 --- /dev/null +++ b/contrib/win32/libtiff.def @@ -0,0 +1,72 @@ +LIBRARY LIBTIFF +EXETYPE WINDOWS +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +HEAPSIZE 4096 +STACKSIZE 8192 +EXPORTS +_TIFFGetVersion @1 +_TIFFClose @2 +_TIFFFlush @3 +_TIFFFlushData @4 +_TIFFGetField @5 +_TIFFVGetField @6 +_TIFFGetFieldDefaulted @7 +_TIFFVGetFieldDefaulted @8 +_TIFFReadDirectory @9 +_TIFFScanlineSize @10 +_TIFFStripSize @11 +_TIFFVStripSize @12 +_TIFFTileRowSize @13 +_TIFFTileSize @14 +_TIFFVTileSize @15 +_TIFFFileno @16 +_TIFFGetMode @17 +_TIFFIsTiled @18 +_TIFFIsByteSwapped @19 +_TIFFCurrentRow @20 +_TIFFCurrentDirectory @21 +_TIFFCurrentStrip @22 +_TIFFCurrentTile @23 +_TIFFReadBufferSetup @24 +_TIFFLastDirectory @25 +_TIFFSetDirectory @26 +_TIFFSetSubDirectory @27 +_TIFFUnlinkDirectory @28 +_TIFFSetField @29 +_TIFFVSetField @30 +_TIFFWriteDirectory @31 +_TIFFReadScanline @32 +_TIFFWriteScanline @33 +_TIFFReadRGBAImage @34 +_TIFFOpen @35 +_TIFFFdOpen @36 +_TIFFClientOpen @37 +_TIFFFileName @38 +_TIFFError @39 +_TIFFWarning @40 +_TIFFSetErrorHandler @41 +_TIFFSetWarningHandler @42 +_TIFFComputeTile @43 +_TIFFCheckTile @44 +_TIFFNumberOfTiles @45 +_TIFFReadTile @46 +_TIFFWriteTile @47 +_TIFFComputeStrip @48 +_TIFFNumberOfStrips @49 +_TIFFReadEncodedStrip @50 +_TIFFReadRawStrip @51 +_TIFFReadEncodedTile @52 +_TIFFReadRawTile @53 +_TIFFWriteEncodedStrip @54 +_TIFFWriteRawStrip @55 +_TIFFWriteEncodedTile @56 +_TIFFWriteRawTile @57 +_TIFFSetWriteOffset @58 +_TIFFSwabShort @59 +_TIFFSwabLong @60 +_TIFFSwabArrayOfShort @61 +_TIFFSwabArrayOfLong @62 +_TIFFReverseBits @63 +_TIFFGetBitRevTable @64 +_TIFFModeCCITTFax3 @65 diff --git a/contrib/win95/Makefile.w95 b/contrib/win95/Makefile.w95 new file mode 100644 index 00000000..3f461ef5 --- /dev/null +++ b/contrib/win95/Makefile.w95 @@ -0,0 +1,134 @@ +# $Header: /usr/people/sam/tiff/libtiff/RCS/Makefile.w95,v 1.2 1994/11/28 +06:13:31 sam Exp $ +# +# Tag Image File Format Library +# +# Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler +# Copyright (c) 1991, 1992 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +# This Makefile is for use with microsoft nmake version 1.50 and +# Microsoft 32-bit C/C++ Compiler 9.00 +# +DESTDIR=. +# +IPATH= -I. +CONF_LIBRARY=$(NULL) +COPTS= -Oxa -DBSDTYPES -Zd +CFLAGS= $(COPTS) $(CONF_LIBRARY) +# +INCS= tiff.h tiffio.h +SRCS= tif_aux.c \ + tif_close.c \ + tif_codec.c \ + tif_compress.c \ + tif_dir.c \ + tif_dirinfo.c \ + tif_dirread.c \ + tif_dirwrite.c \ + tif_dumpmode.c \ + tif_error.c \ + tif_getimage.c \ + tif_jpeg.c \ + tif_flush.c \ + tif_lzw.c \ + tif_next.c \ + tif_open.c \ + tif_packbits.c \ + tif_predict \ + tif_print.c \ + tif_read.c \ + tif_swab.c \ + tif_strip.c \ + tif_thunder.c \ + tif_tile.c \ + tif_version.c \ + tif_warning.c \ + tif_write.c \ + tif_win32.c + + +OBJS= tif_aux.obj \ + tif_close.obj \ + tif_codec.obj \ + tif_compress.obj \ + tif_dir.obj \ + tif_dirinfo.obj \ + tif_dirread.obj \ + tif_dirwrite.obj \ + tif_dumpmode.obj \ + tif_error.obj \ + tif_getimage.obj \ + tif_jpeg.obj \ + tif_flush.obj \ + tif_lzw.obj \ + tif_next.obj \ + tif_open.obj \ + tif_packbits.obj \ + tif_predict.obj \ + tif_print.obj \ + tif_read.obj \ + tif_swab.obj \ + tif_strip.obj \ + tif_thunder.obj \ + tif_tile.obj \ + tif_version.obj \ + tif_warning.obj \ + tif_write.obj \ + tif_win32.obj + + + +ALL= libtiff.lib + +all: $(ALL) + +%.obj : %.c + $(CC) $(CFLAGS) -c $*.c + + +#.INCLUDE .IGNORE : depend + +libtiff.lib: $(OBJS) + - del libtiff.lib + lib /OUT:libtiff.lib $(OBJS) + + +#To include fax3 support, you need to modify mkg3states.c so it could run +#under windows 95 or NT. This application make the file g3state.h. +#after that, you have to add to the build script : tif_fax3.c and tif_fax3.obj +#and define CCITT_SUPPORT in the file tifconf.h + +#$(OBJS): tiffio.h tiff.h tiffcomp.h tiffiop.h tiffconf.h +#tif_fax3.obj: tif_fax3.c g3states.h t4.h tif_fax3.h + +#g3states.h: mkg3states.c t4.h +# $(CC) $(CFLAGS) mkg3states.c +# mkg3states -c > g3states.h + + +clean: + del *.obj + del mkg3stat + del g3states.h + +tags: $(SRCS) + $(CTAGS) $(SRCS) diff --git a/contrib/win95/README b/contrib/win95/README new file mode 100644 index 00000000..edb05d33 --- /dev/null +++ b/contrib/win95/README @@ -0,0 +1,50 @@ +Date: 04 Dec 95 10:34:23 EST +From: Philippe <100423.3705@compuserve.com> +To: TIFF/sam Leffler +Subject: TIFF library and Windows 95 +Message-Id: <951204153422_100423.3705_BHG101-1@CompuServe.COM> + +Sam, + +First, let me thanks all of you how have worked +on that great TIFF library ! + +Here is some information that may help someone. + +I build the library under Windows 95 as a 32-bit library. +The contribution of Scott Wagner (tif_win32.c) worked fine, but +the makefile "makefile.msc" was unsable because it was +written for DOS or Windows 3.1 and all the files names +are limited to 8 characters. + +Here is the makefile I used : makefile.w95 + +Also, I had to disable fax3 support because I wasn't able +to build (as it is) the tool "mkg3states" to generate the include +file "g3states.h". +This source file must be modify to be build under Windows 95. + +To build the library under Windows 95 with Visual C++ 2.0, +I had to : + +- undefine CCITT_SUPPORT in "tiffconf.h" + +- create the file version.h with this line : + #define VERSION "3.4beta024" + +- build the makefile "makefile.w95" + +I also join the source file "tif2dib.c" that I created, +it contain the function LoadTIFFinDIB that load +a TIFF file and build a memory DIB with it and return the +HANDLE (HDIB) of the memory bloc containing this DIB. +Since DIB is the "natural" bitmap format for Windows 3.1, 95 and NT, +this function sould be usefull for some Windows 95 (or NT) developer. + + +Sorry for my approximate english ... + +Regards, + +Philippe Tenenhaus 100423.3705@compuserve.com +Paris diff --git a/contrib/win95/tiff2dib.c b/contrib/win95/tiff2dib.c new file mode 100644 index 00000000..f5d4040f --- /dev/null +++ b/contrib/win95/tiff2dib.c @@ -0,0 +1,372 @@ +/************************************************************************* + * + * Source file for Windows 95/Win32. + * + * The function LoadTIFFinDIB in this source file let you load + * a TIFF file and build a memory DIB with it and return the + * HANDLE (HDIB) of the memory bloc containing the DIB. + * + * Example : + * + * HDIB hDIB; + * hDIB = LoadTIFFinDIB("sample.tif"); + * + * + * To build this source file you must include the TIFF library + * in your project. + * + * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com + * + ************************************************************************/ + + +#include "tiffio.h" + +#define HDIB HANDLE +#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER)) +#define CVT(x) (((x) * 255L) / ((1L<<16)-1)) + +static HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount); +static LPSTR FindDIBBits(LPSTR lpDIB); +static WORD PaletteSize(LPSTR lpDIB); +static WORD DIBNumColors(LPSTR lpDIB); +static int checkcmap(int n, uint16* r, uint16* g, uint16* b); + + + +/************************************************************************* + * + * HDIB LoadTIFFinDIB(LPSTR lpFileName) + * + * Parameter: + * + * LPSTR lpDIB - File name of a tiff imag + * + * Return Value: + * + * LPSTR - HANDLE of a DIB + * + * Description: + * + * This function load a TIFF file and build a memory DIB with it + * and return the HANDLE (HDIB) of the memory bloc containing + * the DIB. + * + * 4/12/95 Philippe Tenenhaus 100423.3705@compuserve.com + * + ************************************************************************/ + +HDIB LoadTIFFinDIB(LPSTR lpFileName) +{ + TIFF *tif; + unsigned long imageLength; + unsigned long imageWidth; + unsigned int BitsPerSample; + unsigned long LineSize; + unsigned int SamplePerPixel; + unsigned long RowsPerStrip; + int PhotometricInterpretation; + long nrow; + unsigned long row; + char *buf; + LPBITMAPINFOHEADER lpDIB; + HDIB hDIB; + char *lpBits; + HGLOBAL hStrip; + int i,l; + int Align; + + tif = TIFFOpen(lpFileName, "r"); + + if (!tif) + goto TiffOpenError; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength); + TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample); + TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); + TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); + TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation); + + LineSize = TIFFScanlineSize(tif); //Number of byte in ine line + + SamplePerPixel = (int) (LineSize/imageWidth); + + //Align = Number of byte to add at the end of each line of the DIB + Align = 4 - (LineSize % 4); + if (Align == 4) Align = 0; + + + //Create a new DIB + hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD) +(BitsPerSample*SamplePerPixel)); + lpDIB = (LPBITMAPINFOHEADER) GlobalLock(hDIB); + if (!lpDIB) + goto OutOfDIBMemory; + + if (lpDIB) + lpBits = FindDIBBits((LPSTR) lpDIB); + + //In the tiff file the lines are save from up to down + //In a DIB the lines must be save from down to up + if (lpBits) + { + lpBits = FindDIBBits((LPSTR) lpDIB); + lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1); + //now lpBits pointe on the bottom line + + hStrip = GlobalAlloc(GHND,TIFFStripSize(tif)); + buf = GlobalLock(hStrip); + + if (!buf) + goto OutOfBufMemory; + + //PhotometricInterpretation = 2 image is RGB + //PhotometricInterpretation = 3 image have a color palette + if (PhotometricInterpretation == 3) + { + uint16* red; + uint16* green; + uint16* blue; + int16 i; + LPBITMAPINFO lpbmi; + int Palette16Bits; + + TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); + + //Is the palette 16 or 8 bits ? + if (checkcmap(1<= 0; i--) + { + if (Palette16Bits) + { + lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]); + lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]); + lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]); + } + else + { + lpbmi->bmiColors[i].rgbRed = (BYTE) red[i]; + lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i]; + lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i]; + } + } + + } + + //read the tiff lines and save them in the DIB + //with RGB mode, we have to change the order of the 3 samples RGB +<=> BGR + for (row = 0; row < imageLength; row += RowsPerStrip) + { + nrow = (row + RowsPerStrip > imageLength ? imageLength - row : +RowsPerStrip); + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), + buf, nrow*LineSize)==-1) + { + goto TiffReadError; + } + else + { + for (l = 0; l < nrow; l++) + { + if (SamplePerPixel == 3) + for (i=0;i< (int) (imageWidth);i++) + { + lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample +PerPixel+2]; + lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample +PerPixel+1]; + lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample +PerPixel+0]; + } + else + memcpy(lpBits, &buf[(int) (l*LineSize)], (int) +imageWidth*SamplePerPixel); + + lpBits-=imageWidth*SamplePerPixel+Align; + + } + } + } + GlobalUnlock(hStrip); + GlobalFree(hStrip); + GlobalUnlock(hDIB); + TIFFClose(tif); + } + + return hDIB; + + OutOfBufMemory: + + TiffReadError: + GlobalUnlock(hDIB); + GlobalFree(hStrip); + OutOfDIBMemory: + TIFFClose(tif); + TiffOpenError: + return (HANDLE) 0; + + +} + + +static int checkcmap(int n, uint16* r, uint16* g, uint16* b) +{ + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + + return (8); +} + + + +/************************************************************************* + * All the following functions were created by microsoft, they are + * parts of the sample project "wincap" given with the SDK Win32. + * + * Microsoft says that : + * + * You have a royalty-free right to use, modify, reproduce and + * distribute the Sample Files (and/or any modified version) in + * any way you find useful, provided that you agree that + * Microsoft has no warranty obligations or liability for any + * Sample Application Files which are modified. + * + ************************************************************************/ + +HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) +{ + BITMAPINFOHEADER bi; // bitmap header + LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER + DWORD dwLen; // size of memory block + HDIB hDIB; + DWORD dwBytesPerLine; // Number of bytes per scanline + + + // Make sure bits per pixel is valid + if (wBitCount <= 1) + wBitCount = 1; + else if (wBitCount <= 4) + wBitCount = 4; + else if (wBitCount <= 8) + wBitCount = 8; + else if (wBitCount <= 24) + wBitCount = 24; + else + wBitCount = 4; // set default value to 4 if parameter is bogus + + // initialize BITMAPINFOHEADER + bi.biSize = sizeof(BITMAPINFOHEADER); + bi.biWidth = dwWidth; // fill in width from parameter + bi.biHeight = dwHeight; // fill in height from parameter + bi.biPlanes = 1; // must be 1 + bi.biBitCount = wBitCount; // from parameter + bi.biCompression = BI_RGB; + bi.biSizeImage = (dwWidth*dwHeight*wBitCount)/8; //0; // 0's here +mean "default" + bi.biXPelsPerMeter = 2834; //0; + bi.biYPelsPerMeter = 2834; //0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + // calculate size of memory block required to store the DIB. This + // block should be big enough to hold the BITMAPINFOHEADER, the color + // table, and the bits + + dwBytesPerLine = (((wBitCount * dwWidth) + 31) / 32 * 4); + dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight); + + // alloc memory block to store our bitmap + hDIB = GlobalAlloc(GHND, dwLen); + + // major bummer if we couldn't get memory block + if (!hDIB) + { + return NULL; + } + + // lock memory and get pointer to it + lpbi = (VOID FAR *)GlobalLock(hDIB); + + // use our bitmap info structure to fill in first part of + // our DIB with the BITMAPINFOHEADER + *lpbi = bi; + + // Since we don't know what the colortable and bits should contain, + // just leave these blank. Unlock the DIB and return the HDIB. + + GlobalUnlock(hDIB); + + /* return handle to the DIB */ + return hDIB; +} + + +LPSTR FAR FindDIBBits(LPSTR lpDIB) +{ + return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB)); +} + + +WORD FAR PaletteSize(LPSTR lpDIB) +{ + /* calculate the size required by the palette */ + if (IS_WIN30_DIB (lpDIB)) + return (DIBNumColors(lpDIB) * sizeof(RGBQUAD)); + else + return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE)); +} + + +WORD DIBNumColors(LPSTR lpDIB) +{ + WORD wBitCount; // DIB bit count + + /* If this is a Windows-style DIB, the number of colors in the + * color table can be less than the number of bits per pixel + * allows for (i.e. lpbi->biClrUsed can be set to some value). + * If this is the case, return the appropriate value. + */ + + if (IS_WIN30_DIB(lpDIB)) + { + DWORD dwClrUsed; + + dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed; + if (dwClrUsed) + return (WORD)dwClrUsed; + } + + /* Calculate the number of colors in the color table based on + * the number of bits per pixel for the DIB. + */ + if (IS_WIN30_DIB(lpDIB)) + wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount; + else + wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount; + + /* return number of colors based on bits per pixel */ + switch (wBitCount) + { + case 1: + return 2; + + case 4: + return 16; + + case 8: + return 256; + + default: + return 0; + } +} diff --git a/contrib/winnt/README b/contrib/winnt/README new file mode 100644 index 00000000..68c64410 --- /dev/null +++ b/contrib/winnt/README @@ -0,0 +1,26 @@ +Date: Fri, 10 Nov 1995 13:02:33 -0800 +Message-Id: <199511102102.NAA07993@lido> +To: tiff@sgi.engr.sgi.com +Subject: Contribution: libtiff for Windows-nt +Reply-To: Dave Dyer +Sender: owner-tiff@sgi.engr.sgi.com +Precedence: bulk + + +Since I needed it, and the support for windows-nt versions of libtiff +is sketchy at best, I packaged up my port of libtiff v3.4beta024 +to windows-nt. + + ftp://torii.triple-i.com/pub/ddyer/libtiff.tar.gz + +this contains "libtiff.mak", a makefile for microsoft visual c++, +a couple of hand-built .h and .c files (corresponding to those which +are automatically constructed by unix makefiles) and static libraries +compiled for intel and dec alpha. + +As customary, I make no claims regarding the completeness or +correctness of these libraries, and accept no responsibily for any +mishaps you may have as a result of using them. They work for me. + +I hope Sam will copy and incorporate this into the "contrib" section +of the next libtiff release. diff --git a/contrib/winnt/README.console b/contrib/winnt/README.console new file mode 100644 index 00000000..05d7dd58 --- /dev/null +++ b/contrib/winnt/README.console @@ -0,0 +1,182 @@ +Date: Fri, 18 Apr 1997 09:25:09 EDT +To: "'sam@cthulhu.engr.sgi.com'" +cc: "'tiff@sgi.engr.sgi.com'" + +From: xingong chang +Subject: Contribution: libtiff for Windows-nt console applications + +Return-Path: xingong@feith1.FEITH.COM +Delivery-Date: Fri, 18 Apr 1997 06:37:38 -0700 +Return-Path: xingong@feith1.FEITH.COM +MIME-Version: 1.0 + +Hi, +I built the libtiff under WINNT 4.0 as a 32-bit library for pure +console applications. I made the makefile.nt based on Philippe +Tenenhaus' makefile.w95 file. Since I want my stuff to be a pure +console application running on WinNT, Dave Dyer's makefile for WINNT is +not good for me since it is for Windows applications. + +I used the tif_msdos.c file instead of the tif_win32.c in the $(OBJS) +list because tif_win32.c is not a pure console program, it includes +some function calls such as MessageBox etc which requires windows +application library ($winslib as defined in ). + +unlike Philippe Tenenhaus' makefile.w95 file, this makefile.nt does +support fax3 stuff. And to make the mkg3states.exe,the getopt.obj is +needed. "getopt" package is ATT public domain source for getopt(3). +Also you need to inlcude the g3states.h in tif_fax.c fileand modify the +tif_fax3.h to delete the external declaration of FFFaxMainTable, +TIFFFaxWhileTable and TIFFFaxBlackTable + + +libtiff version: TIFFLIB_VERSION 19960307 + +Hardware you are using: i386 + +Operating system you are using: Windows NT 4.0 + +C compiler : Microsoft Visual C++ 4.1 + +NMAKE : Microsoft nmake 1.61 + + +Here is the makefile.nt I used: +--------------------------------------------------------- + +# makefile.nt for the tiff library +# Tag Image File Format Library +# +# Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler +# Copyright (c) 1991, 1992 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +# This Makefile is for use with microsoft nmake version 1.61 +# + +!include + +DEFS = -DBSDTYPES -DO_RDONLY=S_IREAD -DO_RDWR=S_IWRITE + +INCS= tiff.h tiffio.h +SRCS= tif_aux.c \ + tif_close.c \ + tif_codec.c \ + tif_compress.c \ + tif_dir.c \ + tif_dirinfo.c \ + tif_dirread.c \ + tif_dirwrite.c \ + tif_dumpmode.c \ + tif_error.c \ + tif_getimage.c \ + tif_jpeg.c \ + tif_flush.c \ + tif_lzw.c \ + tif_next.c \ + tif_open.c \ + tif_packbits.c \ + tif_predict \ + tif_print.c \ + tif_read.c \ + tif_swab.c \ + tif_strip.c \ + tif_thunder.c \ + tif_tile.c \ + tif_version.c \ + tif_warning.c \ + tif_write.c \ + tif_msdos.c \ + tif_fax3.c + + +OBJS= tif_aux.obj \ + tif_close.obj \ + tif_codec.obj \ + tif_compress.obj \ + tif_dir.obj \ + tif_dirinfo.obj \ + tif_dirread.obj \ + tif_dirwrite.obj \ + tif_dumpmode.obj \ + tif_error.obj \ + tif_getimage.obj \ + tif_jpeg.obj \ + tif_flush.obj \ + tif_lzw.obj \ + tif_next.obj \ + tif_open.obj \ + tif_packbits.obj \ + tif_predict.obj \ + tif_print.obj \ + tif_read.obj \ + tif_swab.obj \ + tif_strip.obj \ + tif_thunder.obj \ + tif_tile.obj \ + tif_version.obj \ + tif_warning.obj \ + tif_write.obj \ + tif_msdos.obj \ + tif_fax3.obj + +#To make the mkg3states.exe,the getopt.obj is needed. getopt package is +# ATT public domain source for getopt(3). +EXTRA_OBJS = getopt.obj + +all: libtiff.lib + +libtiff.lib: $(OBJS) + del libtiff.lib + lib -out:libtiff.lib $(OBJS) + +.c.obj: + $(cc) $(DEFS) $(cdebug) $(cflags) $(cvarsmt) $*.c + + +#To include fax3 support, we did this modification +#add to the build script : tif_fax3.c and tif_fax3.obj +#define CCITT_SUPPORT in the file tifconf.h +#inlcude the g3states.h in tif_fax.c file +#modify the tif_fax3.h to delete the TIFFFaxMainTable,TIFFFaxWhileTable +# TIFFFaxBlackTable etc external declaration +#mkg3states.exe without any command line options will produce the g3states.h + +$(OBJS): tiffio.h tiff.h tiffcomp.h tiffiop.h tiffconf.h +tif_fax3.obj: tif_fax3.c g3states.h t4.h tif_fax3.h + +g3states.h: mkg3states.obj t4.h + $(link) $(ldebug) $(conslflags) -out:mkg3states.exe mkg3states.obj \ + $(EXTRA_OBJS) + mkg3states.exe + +clean: + del *.obj + del g3states.h + +clobber: + del libtiff.lib + del *.obj + del g3states.h + + + + diff --git a/contrib/winnt/fax3sm.c b/contrib/winnt/fax3sm.c new file mode 100644 index 00000000..1d0f34a3 --- /dev/null +++ b/contrib/winnt/fax3sm.c @@ -0,0 +1,1046 @@ +/* WARNING, this file was automatically generated by the + mkg3states program */ +#include "tiff.h" +#include "tif_fax3.h" + const TIFFFaxTabEnt TIFFFaxMainTable[128] = { +12,7,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0,1,4,0,3,1,0,5,3,1,3,1,0, +2,3,0,3,1,0,4,3,1,3,1,0,5,6,2,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0, +1,4,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0,5,7,3,3,1,0,5,3,1,3,1,0, +2,3,0,3,1,0,4,3,1,3,1,0,1,4,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0, +4,6,2,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0,1,4,0,3,1,0,5,3,1,3,1,0, +2,3,0,3,1,0,4,3,1,3,1,0,6,7,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0, +1,4,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0,5,6,2,3,1,0,5,3,1,3,1,0, +2,3,0,3,1,0,4,3,1,3,1,0,1,4,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0, +4,7,3,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0,1,4,0,3,1,0,5,3,1,3,1,0, +2,3,0,3,1,0,4,3,1,3,1,0,4,6,2,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0, +1,4,0,3,1,0,5,3,1,3,1,0,2,3,0,3,1,0,4,3,1,3,1,0 +}; +const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = { +12,11,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6, +7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5, +7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1472,7,4,5,7,8,43,7,6,17,9,9,1216,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5, +7,8,41,7,6,16,9,9,960,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,704,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15, +9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,11,11,1792,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,832,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6, +7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1600,7,4,5, +7,8,44,7,6,17,9,9,1344,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14, +7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1088,7,4,6, +7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15, +7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1536,7,4,5,7,8,43,7,6,17,9,9,1280,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7, +7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,1024,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,768,7,4,6, +7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +11,11,1856,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,896,7,4,6, +7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5, +7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1728,7,4,5,7,8,44,7,6,17,9,9,1408,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5, +7,8,42,7,6,16,9,9,1152,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15, +9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6, +7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1472,7,4,5, +7,8,43,7,6,17,9,9,1216,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14, +7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,960,7,4,6, +7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,9,704,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,11,12,2112,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,40,7,6,16,9,9,832,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15, +7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1600,7,4,5,7,8,44,7,6,17,9,9,1344,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7, +7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1088,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6, +7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6, +7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5, +7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1536,7,4,5,7,8,43,7,6,17,9,9,1280,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5, +7,8,41,7,6,16,9,9,1024,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,768,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15, +9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,11,12,2368,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,896,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6, +7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1728,7,4,5, +7,8,44,7,6,17,9,9,1408,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14, +7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1152,7,4,6, +7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15, +7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1472,7,4,5,7,8,43,7,6,17,9,9,1216,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7, +7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,960,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,704,7,4,6, +7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +11,12,1984,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,832,7,4,6, +7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5, +7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1600,7,4,5,7,8,44,7,6,17,9,9,1344,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5, +7,8,42,7,6,16,9,9,1088,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15, +9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6, +7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1536,7,4,5, +7,8,43,7,6,17,9,9,1280,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14, +7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,1024,7,4,6, +7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,9,768,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,11,11,1920,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,40,7,6,16,9,9,896,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15, +7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1728,7,4,5,7,8,44,7,6,17,9,9,1408,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7, +7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1152,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6, +7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6, +7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5, +7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1472,7,4,5,7,8,43,7,6,17,9,9,1216,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5, +7,8,41,7,6,16,9,9,960,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,704,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15, +9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,11,12,2240,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,832,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6, +7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1600,7,4,5, +7,8,44,7,6,17,9,9,1344,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14, +7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1088,7,4,6, +7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15, +7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1536,7,4,5,7,8,43,7,6,17,9,9,1280,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7, +7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,1024,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,768,7,4,6, +7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +11,12,2496,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,896,7,4,6, +7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5, +7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1728,7,4,5,7,8,44,7,6,17,9,9,1408,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5, +7,8,42,7,6,16,9,9,1152,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15, +9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,12,11,0,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6, +7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1472,7,4,5, +7,8,43,7,6,17,9,9,1216,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14, +7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,960,7,4,6, +7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,9,704,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,11,11,1792,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,40,7,6,16,9,9,832,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15, +7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1600,7,4,5,7,8,44,7,6,17,9,9,1344,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7, +7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1088,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6, +7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6, +7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5, +7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1536,7,4,5,7,8,43,7,6,17,9,9,1280,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5, +7,8,41,7,6,16,9,9,1024,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,768,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15, +9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,11,11,1856,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,896,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6, +7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1728,7,4,5, +7,8,44,7,6,17,9,9,1408,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14, +7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1152,7,4,6, +7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15, +7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1472,7,4,5,7,8,43,7,6,17,9,9,1216,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7, +7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,960,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,704,7,4,6, +7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +11,12,2176,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,832,7,4,6, +7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5, +7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1600,7,4,5,7,8,44,7,6,17,9,9,1344,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5, +7,8,42,7,6,16,9,9,1088,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15, +9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6, +7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1536,7,4,5, +7,8,43,7,6,17,9,9,1280,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14, +7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,1024,7,4,6, +7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,9,768,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,11,12,2432,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,40,7,6,16,9,9,896,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15, +7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1728,7,4,5,7,8,44,7,6,17,9,9,1408,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7, +7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1152,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6, +7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6, +7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5, +7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1472,7,4,5,7,8,43,7,6,17,9,9,1216,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5, +7,8,41,7,6,16,9,9,960,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,704,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15, +9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,11,12,2048,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,832,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6, +7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1600,7,4,5, +7,8,44,7,6,17,9,9,1344,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14, +7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1088,7,4,6, +7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15, +7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1536,7,4,5,7,8,43,7,6,17,9,9,1280,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7, +7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,1024,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,768,7,4,6, +7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +11,11,1920,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,896,7,4,6, +7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5, +7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1728,7,4,5,7,8,44,7,6,17,9,9,1408,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5, +7,8,42,7,6,16,9,9,1152,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15, +9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,0,0,0,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6,7,7,19,7,5,8,7,8,55,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5,7,8,53,7,5,9,9,8,448,7,4,6, +7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1472,7,4,5, +7,8,43,7,6,17,9,9,1216,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,33,9,5,128,7,8,49,7,6,14, +7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5,7,8,41,7,6,16,9,9,960,7,4,6, +7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,9,704,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15,9,8,320,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,11,12,2304,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5, +7,8,40,7,6,16,9,9,832,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6,7,8,36,9,5,128,7,8,52,7,6,15, +7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1600,7,4,5,7,8,44,7,6,17,9,9,1344,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,30,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14,7,8,62,7,4,4,7,4,2,7,4,7, +7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1088,7,4,6,7,8,32,7,5,8,7,8,58,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,8,640,7,4,6, +7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5, +7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +0,0,0,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14, +7,7,28,7,4,4,7,4,2,7,4,7,7,7,23,7,4,3,7,7,27,7,4,5,7,8,39,7,6,16,9,8,576,7,4,6, +7,7,19,7,5,8,7,8,55,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,8,45,7,4,3,7,5,11,7,4,5, +7,8,53,7,5,9,9,8,448,7,4,6,7,8,35,9,5,128,7,8,51,7,6,15,7,8,63,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,9,9,1536,7,4,5,7,8,43,7,6,17,9,9,1280,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,29,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6, +7,8,33,9,5,128,7,8,49,7,6,14,7,8,61,7,4,4,7,4,2,7,4,7,7,8,47,7,4,3,7,8,59,7,4,5, +7,8,41,7,6,16,9,9,1024,7,4,6,7,8,31,7,5,8,7,8,57,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,7,22,7,4,3,7,5,11,7,4,5,7,7,26,7,5,9,9,9,768,7,4,6,7,8,37,9,5,128,7,7,25,7,6,15, +9,8,320,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6, +7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,11,12,2560,7,4,3,7,5,11,7,4,5, +7,6,12,7,5,9,9,6,1664,7,4,6,7,7,20,9,5,128,7,7,24,7,6,14,7,7,28,7,4,4,7,4,2,7,4,7, +7,7,23,7,4,3,7,7,27,7,4,5,7,8,40,7,6,16,9,9,896,7,4,6,7,7,19,7,5,8,7,8,56,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7,7,8,46,7,4,3,7,5,11,7,4,5,7,8,54,7,5,9,9,8,512,7,4,6, +7,8,36,9,5,128,7,8,52,7,6,15,7,8,0,7,4,4,7,4,2,7,4,7,7,6,13,7,4,3,9,9,1728,7,4,5, +7,8,44,7,6,17,9,9,1408,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7, +7,8,30,7,4,3,7,5,11,7,4,5,7,6,12,7,5,9,9,6,1664,7,4,6,7,8,34,9,5,128,7,8,50,7,6,14, +7,8,62,7,4,4,7,4,2,7,4,7,7,8,48,7,4,3,7,8,60,7,4,5,7,8,42,7,6,16,9,9,1152,7,4,6, +7,8,32,7,5,8,7,8,58,9,5,64,7,5,10,7,4,4,7,4,2,7,4,7,7,7,22,7,4,3,7,5,11,7,4,5, +7,7,26,7,5,9,9,8,640,7,4,6,7,8,38,9,5,128,7,7,25,7,6,15,9,8,384,7,4,4,7,4,2,7,4,7, +7,6,13,7,4,3,7,7,18,7,4,5,7,7,21,7,6,17,9,7,256,7,4,6,7,6,1,7,5,8,9,6,192,9,5,64, +7,5,10,7,4,4,7,4,2,7,4,7 +}; +const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = { +12,11,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,18,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,17,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,11,1792,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,23,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,20,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,25,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,12,128,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,56,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,30,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,11,1856,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,57,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,21,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,54,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,52,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,48,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,12,2112,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,44,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,36,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,12,384,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,28,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,60,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,40,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2368,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,16,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,10,64,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,18,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,17,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,1984,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,50,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,34,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,1664,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,26,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,13,1408,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,32,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,11,1920,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,61,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,42,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,13,1024,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,768,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,62,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2240,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,46,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,38,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,13,512,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,19,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,24,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,22,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,2496,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,16,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,10,64,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,12,11,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,18,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,17,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,11,1792,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,23,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,20,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,25,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,12,192,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,1280,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,31,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,11,1856,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,58,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,21,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,13,896,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,13,640,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,49,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,2176,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,45,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,37,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,12,448,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,29,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,13,1536,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,41,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,12,2432,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,16,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,10,64,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,18,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,17,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2048,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,51,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,35,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,12,320,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,27,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,59,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,33,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,11,1920,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,12,256,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,43,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,1152,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,55,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,63,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,12,2304,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,47,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,39,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,53,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,19,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,24,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,22,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2560,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,16,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,10,64,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,12,11,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,18,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,17,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,11,1792,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,23,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,20,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,25,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,12,128,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,56,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,30,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,11,1856,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,57,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,21,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,54,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,52,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,48,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2112,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,44,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,36,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,12,384,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,28,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,60,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,40,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,2368,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,16,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,10,64,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,18,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,17,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,12,1984,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,50,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,34,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,13,1728,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,26,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,1472,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,32,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,11,1920,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,61,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,42,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,13,1088,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,13,832,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,62,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,2240,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,46,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,38,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,576,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,19,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,24,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,22,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,12,2496,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,16,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,10,64,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +12,11,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,18,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,17,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,11,1792,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,23,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,20,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,25,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,12,192,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,13,1344,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,31,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,11,1856,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,58,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,11,21,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,960,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,13,704,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,49,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,12,2176,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,45,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,37,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,12,448,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,29,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,13,1600,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,41,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2432,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,16,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,10,64,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,18,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,10,17,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,2048,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,51,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,35,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,12,320,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,27,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,59,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,33,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,11,11,1920,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +10,12,256,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,43,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,10,13,1216,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,13,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,9,15,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,55,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,63,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,11,12,2304,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,12,47,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,12,39,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,12,53,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,8,14,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,0,0,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,13,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,19,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,11,24,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,7,11,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,11,22,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +11,12,2560,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,9,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,10,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,10,16,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,10,0,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,10,10,64,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,6,9,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2,8,7,11,8,2,3,8,3,1,8,2,2, +8,4,6,8,2,3,8,3,4,8,2,2,8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2, +8,8,14,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2,8,6,8,8,2,3,8,3,1,8,2,2, +8,4,5,8,2,3,8,3,4,8,2,2,8,7,12,8,2,3,8,3,1,8,2,2,8,4,6,8,2,3,8,3,4,8,2,2, +8,5,7,8,2,3,8,3,1,8,2,2,8,4,5,8,2,3,8,3,4,8,2,2 +}; diff --git a/contrib/winnt/libtiff.def b/contrib/winnt/libtiff.def new file mode 100644 index 00000000..7ed4e7b6 --- /dev/null +++ b/contrib/winnt/libtiff.def @@ -0,0 +1,72 @@ +LIBRARY libtiff +EXPORTS TIFFOpen + TIFFGetVersion + TIFFClose + TIFFFlush + TIFFFlushData + TIFFFlushdata1 + TIFFGetField + TIFFVGetField + TIFFGetFieldDefaulted + TIFFVGetFieldDefaulted + TIFFReadDirectory + TIFFScanlineSize + TIFFStripSize + TIFFVStripSize + TIFFTileRowSize + TIFFTileSize + TIFFVTileSize + TIFFFileno + TIFFGetMode + TIFFIsTiled + TIFFIsByteSwapped + TIFFCurrentRow + TIFFCurrentDirectory + TIFFCurrentStrip + TIFFCurrentTile + TIFFReadBufferSetup + TIFFLastDirectory + TIFFSetDirectory + TIFFSetSubDirectory + TIFFUnlinkDirectory + TIFFSetField + TIFFVSetField + TIFFWriteDirectory + TIFFPrintDirectory + TIFFReadScanline + TIFFWriteScanline + TIFFReadRGBAImage + TIFFPrintDirectory + TIFFReadScanline + TIFFWriteScanline + TIFFReadRGBAImage + TIFFFdOpen + TIFFClientOpen + TIFFFileName + TIFFError + TIFFWarning + TIFFSetErrorHandler + TIFFSetWarningHandler + TIFFComputeTile + TIFFCheckTile + TIFFNumberOfTiles + TIFFReadTile + TIFFWriteTile + TIFFComputeStrip + TIFFNumberOfStrips + TIFFReadEncodedStrip + TIFFReadRawStrip + TIFFReadEncodedTile + TIFFReadRawTile + TIFFWriteEncodedStrip + TIFFWriteRawStrip + TIFFWriteEncodedTile + TIFFWriteRawTile + TIFFSetWriteOffset + TIFFSwabShort + TIFFSwabLong + TIFFSwabArrayOfShort + TIFFSwabArrayOfLong + TIFFReverseBits + TIFFGetBitRevTable + TIFFModeCCITTFax3 diff --git a/contrib/winnt/libtiff.mak b/contrib/winnt/libtiff.mak new file mode 100644 index 00000000..c5a351e0 --- /dev/null +++ b/contrib/winnt/libtiff.mak @@ -0,0 +1,1947 @@ +# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (ALPHA) Static Library" 0x0604 +# TARGTYPE "Macintosh Static Library" 0x0304 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +!IF "$(CFG)" == "" +CFG=Win32 Debug +!MESSAGE No configuration specified. Defaulting to Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" !=\ + "Macintosh Release" && "$(CFG)" != "Macintosh Debug" && "$(CFG)" != "APXrel" &&\ + "$(CFG)" != "APXdeb" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libtiff.mak" CFG="Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "Macintosh Release" (based on "Macintosh Static Library") +!MESSAGE "Macintosh Debug" (based on "Macintosh Static Library") +!MESSAGE "APXrel" (based on "Win32 (ALPHA) Static Library") +!MESSAGE "APXdeb" (based on "Win32 (ALPHA) Static Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Win32 Release" + +!IF "$(CFG)" == "Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "WinRel" +# PROP BASE Intermediate_Dir "WinRel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "WinRel" +# PROP Intermediate_Dir "WinRel" +OUTDIR=.\WinRel +INTDIR=.\WinRel + +ALL : $(OUTDIR)/""libtiff.lib"" $(OUTDIR)/""libtiff.bsc"" + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c +# ADD CPP /nologo /MT /W3 /GX /YX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c +CPP_PROJ=/nologo /MT /W3 /GX /YX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D\ + "_WINDOWS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"libtiff.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinRel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"libtiff.bsc" +BSC32_SBRS= \ + $(INTDIR)/"tif_jpeg.sbr" \ + $(INTDIR)/"tif_dirinfo.sbr" \ + $(INTDIR)/"tif_win32.sbr" \ + $(INTDIR)/"tif_flush.sbr" \ + $(INTDIR)/"tif_thunder.sbr" \ + $(INTDIR)/"tif_compress.sbr" \ + $(INTDIR)/"tif_print.sbr" \ + $(INTDIR)/"tif_dirread.sbr" \ + $(INTDIR)/"tif_getimage.sbr" \ + $(INTDIR)/"tif_fax3.sbr" \ + $(INTDIR)/"tif_version.sbr" \ + $(INTDIR)/"tif_codec.sbr" \ + $(INTDIR)/"tif_dir.sbr" \ + $(INTDIR)/"tif_predict.sbr" \ + $(INTDIR)/"tif_close.sbr" \ + $(INTDIR)/"tif_dumpmode.sbr" \ + $(INTDIR)/"tif_aux.sbr" \ + $(INTDIR)/"tif_error.sbr" \ + $(INTDIR)/"tif_lzw.sbr" \ + $(INTDIR)/"tif_zip.sbr" \ + $(INTDIR)/"tif_read.sbr" \ + $(INTDIR)/"tif_packbits.sbr" \ + $(INTDIR)/"tif_swab.sbr" \ + $(INTDIR)/"tif_dirwrite.sbr" \ + $(INTDIR)/"tif_open.sbr" \ + $(INTDIR)/"tif_warning.sbr" \ + $(INTDIR)/"tif_tile.sbr" \ + $(INTDIR)/"tif_strip.sbr" \ + $(INTDIR)/"tif_next.sbr" \ + $(INTDIR)/"tif_write.sbr" \ + $(INTDIR)/"fax3sm.sbr" + +$(OUTDIR)/"libtiff.bsc" : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LIB32=lib.exe +# ADD BASE LIB32 /NOLOGO +# ADD LIB32 /NOLOGO +LIB32_FLAGS=/NOLOGO /OUT:$(OUTDIR)\"libtiff.lib" +DEF_FLAGS= +DEF_FILE= +LIB32_OBJS= \ + $(INTDIR)/"tif_jpeg.obj" \ + $(INTDIR)/"tif_dirinfo.obj" \ + $(INTDIR)/"tif_win32.obj" \ + $(INTDIR)/"tif_flush.obj" \ + $(INTDIR)/"tif_thunder.obj" \ + $(INTDIR)/"tif_compress.obj" \ + $(INTDIR)/"tif_print.obj" \ + $(INTDIR)/"tif_dirread.obj" \ + $(INTDIR)/"tif_getimage.obj" \ + $(INTDIR)/"tif_fax3.obj" \ + $(INTDIR)/"tif_version.obj" \ + $(INTDIR)/"tif_codec.obj" \ + $(INTDIR)/"tif_dir.obj" \ + $(INTDIR)/"tif_predict.obj" \ + $(INTDIR)/"tif_close.obj" \ + $(INTDIR)/"tif_dumpmode.obj" \ + $(INTDIR)/"tif_aux.obj" \ + $(INTDIR)/"tif_error.obj" \ + $(INTDIR)/"tif_lzw.obj" \ + $(INTDIR)/"tif_zip.obj" \ + $(INTDIR)/"tif_read.obj" \ + $(INTDIR)/"tif_packbits.obj" \ + $(INTDIR)/"tif_swab.obj" \ + $(INTDIR)/"tif_dirwrite.obj" \ + $(INTDIR)/"tif_open.obj" \ + $(INTDIR)/"tif_warning.obj" \ + $(INTDIR)/"tif_tile.obj" \ + $(INTDIR)/"tif_strip.obj" \ + $(INTDIR)/"tif_next.obj" \ + $(INTDIR)/"tif_write.obj" \ + $(INTDIR)/"fax3sm.obj" + +$(OUTDIR)/"libtiff.lib" : $(OUTDIR) $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDebug" +# PROP BASE Intermediate_Dir "WinDebug" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "WinDebug" +# PROP Intermediate_Dir "WinDebug" +OUTDIR=.\WinDebug +INTDIR=.\WinDebug + +ALL : $(OUTDIR)/""dlibtiff.lib"" $(OUTDIR)/""libtiff.bsc"" + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /GX /Z7 /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c +# ADD CPP /nologo /MT /W3 /GX /Z7 /YX /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FAs /FR /c +CPP_PROJ=/nologo /MT /W3 /GX /Z7 /YX /Od /I "." /I ".." /D "WIN32" /D "_DEBUG"\ + /D "_WINDOWS" /FAs /Fa$(INTDIR)/ /FR$(INTDIR)/ /Fp$(OUTDIR)/"libtiff.pch"\ + /Fo$(INTDIR)/ /c +CPP_OBJS=.\WinDebug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"libtiff.bsc" +BSC32_SBRS= \ + $(INTDIR)/"tif_jpeg.sbr" \ + $(INTDIR)/"tif_dirinfo.sbr" \ + $(INTDIR)/"tif_win32.sbr" \ + $(INTDIR)/"tif_flush.sbr" \ + $(INTDIR)/"tif_thunder.sbr" \ + $(INTDIR)/"tif_compress.sbr" \ + $(INTDIR)/"tif_print.sbr" \ + $(INTDIR)/"tif_dirread.sbr" \ + $(INTDIR)/"tif_getimage.sbr" \ + $(INTDIR)/"tif_fax3.sbr" \ + $(INTDIR)/"tif_version.sbr" \ + $(INTDIR)/"tif_codec.sbr" \ + $(INTDIR)/"tif_dir.sbr" \ + $(INTDIR)/"tif_predict.sbr" \ + $(INTDIR)/"tif_close.sbr" \ + $(INTDIR)/"tif_dumpmode.sbr" \ + $(INTDIR)/"tif_aux.sbr" \ + $(INTDIR)/"tif_error.sbr" \ + $(INTDIR)/"tif_lzw.sbr" \ + $(INTDIR)/"tif_zip.sbr" \ + $(INTDIR)/"tif_read.sbr" \ + $(INTDIR)/"tif_packbits.sbr" \ + $(INTDIR)/"tif_swab.sbr" \ + $(INTDIR)/"tif_dirwrite.sbr" \ + $(INTDIR)/"tif_open.sbr" \ + $(INTDIR)/"tif_warning.sbr" \ + $(INTDIR)/"tif_tile.sbr" \ + $(INTDIR)/"tif_strip.sbr" \ + $(INTDIR)/"tif_next.sbr" \ + $(INTDIR)/"tif_write.sbr" \ + $(INTDIR)/"fax3sm.sbr" + +$(OUTDIR)/"libtiff.bsc" : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LIB32=lib.exe +# ADD BASE LIB32 /NOLOGO +# ADD LIB32 /NOLOGO /OUT:"WinDebug\dlibtiff.lib" +LIB32_FLAGS=/NOLOGO /OUT:"WinDebug\dlibtiff.lib" +DEF_FLAGS= +DEF_FILE= +LIB32_OBJS= \ + $(INTDIR)/"tif_jpeg.obj" \ + $(INTDIR)/"tif_dirinfo.obj" \ + $(INTDIR)/"tif_win32.obj" \ + $(INTDIR)/"tif_flush.obj" \ + $(INTDIR)/"tif_thunder.obj" \ + $(INTDIR)/"tif_compress.obj" \ + $(INTDIR)/"tif_print.obj" \ + $(INTDIR)/"tif_dirread.obj" \ + $(INTDIR)/"tif_getimage.obj" \ + $(INTDIR)/"tif_fax3.obj" \ + $(INTDIR)/"tif_version.obj" \ + $(INTDIR)/"tif_codec.obj" \ + $(INTDIR)/"tif_dir.obj" \ + $(INTDIR)/"tif_predict.obj" \ + $(INTDIR)/"tif_close.obj" \ + $(INTDIR)/"tif_dumpmode.obj" \ + $(INTDIR)/"tif_aux.obj" \ + $(INTDIR)/"tif_error.obj" \ + $(INTDIR)/"tif_lzw.obj" \ + $(INTDIR)/"tif_zip.obj" \ + $(INTDIR)/"tif_read.obj" \ + $(INTDIR)/"tif_packbits.obj" \ + $(INTDIR)/"tif_swab.obj" \ + $(INTDIR)/"tif_dirwrite.obj" \ + $(INTDIR)/"tif_open.obj" \ + $(INTDIR)/"tif_warning.obj" \ + $(INTDIR)/"tif_tile.obj" \ + $(INTDIR)/"tif_strip.obj" \ + $(INTDIR)/"tif_next.obj" \ + $(INTDIR)/"tif_write.obj" \ + $(INTDIR)/"fax3sm.obj" + +$(OUTDIR)/"dlibtiff.lib" : $(OUTDIR) $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Macintosh Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "MacRel" +# PROP BASE Intermediate_Dir "MacRel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "MacRel" +# PROP Intermediate_Dir "MacRel" +OUTDIR=.\MacRel +INTDIR=.\MacRel + +ALL : $(OUTDIR)/""libtiff.lib"" $(OUTDIR)/""libtiff.bsc"" + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +CPP=cl.exe +# ADD BASE CPP /nologo /AL /W3 /GX /YX /O2 /D "_WINDOWS" /D "_MAC" /D "_68K_" /D "NDEBUG" /FR /c +# ADD CPP /nologo /AL /W3 /GX /YX /O2 /D "_WINDOWS" /D "_MAC" /D "_68K_" /D "NDEBUG" /FR /c +CPP_PROJ=/nologo /AL /W3 /GX /YX /O2 /D "_WINDOWS" /D "_MAC" /D "_68K_" /D\ + "NDEBUG" /FR$(INTDIR)/ /Fp$(OUTDIR)/"libtiff.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\MacRel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"libtiff.bsc" +BSC32_SBRS= \ + $(INTDIR)/"tif_jpeg.sbr" \ + $(INTDIR)/"tif_dirinfo.sbr" \ + $(INTDIR)/"tif_win32.sbr" \ + $(INTDIR)/"tif_flush.sbr" \ + $(INTDIR)/"tif_thunder.sbr" \ + $(INTDIR)/"tif_compress.sbr" \ + $(INTDIR)/"tif_print.sbr" \ + $(INTDIR)/"tif_dirread.sbr" \ + $(INTDIR)/"tif_getimage.sbr" \ + $(INTDIR)/"tif_fax3.sbr" \ + $(INTDIR)/"tif_version.sbr" \ + $(INTDIR)/"tif_codec.sbr" \ + $(INTDIR)/"tif_dir.sbr" \ + $(INTDIR)/"tif_predict.sbr" \ + $(INTDIR)/"tif_close.sbr" \ + $(INTDIR)/"tif_dumpmode.sbr" \ + $(INTDIR)/"tif_aux.sbr" \ + $(INTDIR)/"tif_error.sbr" \ + $(INTDIR)/"tif_lzw.sbr" \ + $(INTDIR)/"tif_zip.sbr" \ + $(INTDIR)/"tif_read.sbr" \ + $(INTDIR)/"tif_packbits.sbr" \ + $(INTDIR)/"tif_swab.sbr" \ + $(INTDIR)/"tif_dirwrite.sbr" \ + $(INTDIR)/"tif_open.sbr" \ + $(INTDIR)/"tif_warning.sbr" \ + $(INTDIR)/"tif_tile.sbr" \ + $(INTDIR)/"tif_strip.sbr" \ + $(INTDIR)/"tif_next.sbr" \ + $(INTDIR)/"tif_write.sbr" \ + $(INTDIR)/"fax3sm.sbr" + +$(OUTDIR)/"libtiff.bsc" : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LIB32=lib.exe +# ADD BASE LIB32 /NOLOGO +# ADD LIB32 /NOLOGO +LIB32_FLAGS=/NOLOGO /OUT:$(OUTDIR)\"libtiff.lib" +DEF_FLAGS= +DEF_FILE= +LIB32_OBJS= \ + $(INTDIR)/"tif_jpeg.obj" \ + $(INTDIR)/"tif_dirinfo.obj" \ + $(INTDIR)/"tif_win32.obj" \ + $(INTDIR)/"tif_flush.obj" \ + $(INTDIR)/"tif_thunder.obj" \ + $(INTDIR)/"tif_compress.obj" \ + $(INTDIR)/"tif_print.obj" \ + $(INTDIR)/"tif_dirread.obj" \ + $(INTDIR)/"tif_getimage.obj" \ + $(INTDIR)/"tif_fax3.obj" \ + $(INTDIR)/"tif_version.obj" \ + $(INTDIR)/"tif_codec.obj" \ + $(INTDIR)/"tif_dir.obj" \ + $(INTDIR)/"tif_predict.obj" \ + $(INTDIR)/"tif_close.obj" \ + $(INTDIR)/"tif_dumpmode.obj" \ + $(INTDIR)/"tif_aux.obj" \ + $(INTDIR)/"tif_error.obj" \ + $(INTDIR)/"tif_lzw.obj" \ + $(INTDIR)/"tif_zip.obj" \ + $(INTDIR)/"tif_read.obj" \ + $(INTDIR)/"tif_packbits.obj" \ + $(INTDIR)/"tif_swab.obj" \ + $(INTDIR)/"tif_dirwrite.obj" \ + $(INTDIR)/"tif_open.obj" \ + $(INTDIR)/"tif_warning.obj" \ + $(INTDIR)/"tif_tile.obj" \ + $(INTDIR)/"tif_strip.obj" \ + $(INTDIR)/"tif_next.obj" \ + $(INTDIR)/"tif_write.obj" \ + $(INTDIR)/"fax3sm.obj" + +$(OUTDIR)/"libtiff.lib" : $(OUTDIR) $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "MacDebug" +# PROP BASE Intermediate_Dir "MacDebug" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "MacDebug" +# PROP Intermediate_Dir "MacDebug" +OUTDIR=.\MacDebug +INTDIR=.\MacDebug + +ALL : $(OUTDIR)/""libtiff.lib"" $(OUTDIR)/""libtiff.bsc"" + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +CPP=cl.exe +# ADD BASE CPP /nologo /AL /Q68m /W3 /GX /Z7 /YX /Od /D "_WINDOWS" /D "_MAC" /D "_68K_" /D "_DEBUG" /FR /c +# ADD CPP /nologo /AL /Q68m /W3 /GX /Z7 /YX /Od /D "_WINDOWS" /D "_MAC" /D "_68K_" /D "_DEBUG" /FR /c +CPP_PROJ=/nologo /AL /Q68m /W3 /GX /Z7 /YX /Od /D "_WINDOWS" /D "_MAC" /D\ + "_68K_" /D "_DEBUG" /FR$(INTDIR)/ /Fp$(OUTDIR)/"libtiff.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\MacDebug/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"libtiff.bsc" +BSC32_SBRS= \ + $(INTDIR)/"tif_jpeg.sbr" \ + $(INTDIR)/"tif_dirinfo.sbr" \ + $(INTDIR)/"tif_win32.sbr" \ + $(INTDIR)/"tif_flush.sbr" \ + $(INTDIR)/"tif_thunder.sbr" \ + $(INTDIR)/"tif_compress.sbr" \ + $(INTDIR)/"tif_print.sbr" \ + $(INTDIR)/"tif_dirread.sbr" \ + $(INTDIR)/"tif_getimage.sbr" \ + $(INTDIR)/"tif_fax3.sbr" \ + $(INTDIR)/"tif_version.sbr" \ + $(INTDIR)/"tif_codec.sbr" \ + $(INTDIR)/"tif_dir.sbr" \ + $(INTDIR)/"tif_predict.sbr" \ + $(INTDIR)/"tif_close.sbr" \ + $(INTDIR)/"tif_dumpmode.sbr" \ + $(INTDIR)/"tif_aux.sbr" \ + $(INTDIR)/"tif_error.sbr" \ + $(INTDIR)/"tif_lzw.sbr" \ + $(INTDIR)/"tif_zip.sbr" \ + $(INTDIR)/"tif_read.sbr" \ + $(INTDIR)/"tif_packbits.sbr" \ + $(INTDIR)/"tif_swab.sbr" \ + $(INTDIR)/"tif_dirwrite.sbr" \ + $(INTDIR)/"tif_open.sbr" \ + $(INTDIR)/"tif_warning.sbr" \ + $(INTDIR)/"tif_tile.sbr" \ + $(INTDIR)/"tif_strip.sbr" \ + $(INTDIR)/"tif_next.sbr" \ + $(INTDIR)/"tif_write.sbr" \ + $(INTDIR)/"fax3sm.sbr" + +$(OUTDIR)/"libtiff.bsc" : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LIB32=lib.exe +# ADD BASE LIB32 /NOLOGO +# ADD LIB32 /NOLOGO +LIB32_FLAGS=/NOLOGO /OUT:$(OUTDIR)\"libtiff.lib" +DEF_FLAGS= +DEF_FILE= +LIB32_OBJS= \ + $(INTDIR)/"tif_jpeg.obj" \ + $(INTDIR)/"tif_dirinfo.obj" \ + $(INTDIR)/"tif_win32.obj" \ + $(INTDIR)/"tif_flush.obj" \ + $(INTDIR)/"tif_thunder.obj" \ + $(INTDIR)/"tif_compress.obj" \ + $(INTDIR)/"tif_print.obj" \ + $(INTDIR)/"tif_dirread.obj" \ + $(INTDIR)/"tif_getimage.obj" \ + $(INTDIR)/"tif_fax3.obj" \ + $(INTDIR)/"tif_version.obj" \ + $(INTDIR)/"tif_codec.obj" \ + $(INTDIR)/"tif_dir.obj" \ + $(INTDIR)/"tif_predict.obj" \ + $(INTDIR)/"tif_close.obj" \ + $(INTDIR)/"tif_dumpmode.obj" \ + $(INTDIR)/"tif_aux.obj" \ + $(INTDIR)/"tif_error.obj" \ + $(INTDIR)/"tif_lzw.obj" \ + $(INTDIR)/"tif_zip.obj" \ + $(INTDIR)/"tif_read.obj" \ + $(INTDIR)/"tif_packbits.obj" \ + $(INTDIR)/"tif_swab.obj" \ + $(INTDIR)/"tif_dirwrite.obj" \ + $(INTDIR)/"tif_open.obj" \ + $(INTDIR)/"tif_warning.obj" \ + $(INTDIR)/"tif_tile.obj" \ + $(INTDIR)/"tif_strip.obj" \ + $(INTDIR)/"tif_next.obj" \ + $(INTDIR)/"tif_write.obj" \ + $(INTDIR)/"fax3sm.obj" + +$(OUTDIR)/"libtiff.lib" : $(OUTDIR) $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "APXrel" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "APXrel" +# PROP BASE Intermediate_Dir "APXrel" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "APXrel" +# PROP Intermediate_Dir "APXrel" +OUTDIR=.\APXrel +INTDIR=.\APXrel + +ALL : $(OUTDIR)/"libtiff.lib" $(OUTDIR)/"libtiff.bsc" + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +CPP=cl.exe +# ADD BASE CPP /nologo /ML /Gt0 /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /YX /O2 /I ".." /I "." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c +CPP_PROJ=/nologo /MT /Gt0 /W3 /GX /YX /O2 /I ".." /I "." /D "WIN32" /D "NDEBUG"\ + /D "_WINDOWS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"libtiff.pch" /Fo$(INTDIR)/ /c +CPP_OBJS=.\APXrel/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"libtiff.bsc" +BSC32_SBRS= \ + $(INTDIR)/"tif_jpeg.sbr" \ + $(INTDIR)/"tif_dirinfo.sbr" \ + $(INTDIR)/"tif_win32.sbr" \ + $(INTDIR)/"tif_flush.sbr" \ + $(INTDIR)/"tif_thunder.sbr" \ + $(INTDIR)/"tif_compress.sbr" \ + $(INTDIR)/"tif_print.sbr" \ + $(INTDIR)/"tif_dirread.sbr" \ + $(INTDIR)/"tif_getimage.sbr" \ + $(INTDIR)/"tif_fax3.sbr" \ + $(INTDIR)/"tif_version.sbr" \ + $(INTDIR)/"tif_codec.sbr" \ + $(INTDIR)/"tif_dir.sbr" \ + $(INTDIR)/"tif_predict.sbr" \ + $(INTDIR)/"tif_close.sbr" \ + $(INTDIR)/"tif_dumpmode.sbr" \ + $(INTDIR)/"tif_aux.sbr" \ + $(INTDIR)/"tif_error.sbr" \ + $(INTDIR)/"tif_lzw.sbr" \ + $(INTDIR)/"tif_zip.sbr" \ + $(INTDIR)/"tif_read.sbr" \ + $(INTDIR)/"tif_packbits.sbr" \ + $(INTDIR)/"tif_swab.sbr" \ + $(INTDIR)/"tif_dirwrite.sbr" \ + $(INTDIR)/"tif_open.sbr" \ + $(INTDIR)/"tif_warning.sbr" \ + $(INTDIR)/"tif_tile.sbr" \ + $(INTDIR)/"tif_strip.sbr" \ + $(INTDIR)/"tif_next.sbr" \ + $(INTDIR)/"tif_write.sbr" \ + $(INTDIR)/"fax3sm.sbr" + +$(OUTDIR)/"libtiff.bsc" : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LIB32=lib.exe +# ADD BASE LIB32 /NOLOGO +# ADD LIB32 /NOLOGO +LIB32_FLAGS=/NOLOGO /OUT:$(OUTDIR)\"libtiff.lib" +DEF_FLAGS= +DEF_FILE= +LIB32_OBJS= \ + $(INTDIR)/"tif_jpeg.obj" \ + $(INTDIR)/"tif_dirinfo.obj" \ + $(INTDIR)/"tif_win32.obj" \ + $(INTDIR)/"tif_flush.obj" \ + $(INTDIR)/"tif_thunder.obj" \ + $(INTDIR)/"tif_compress.obj" \ + $(INTDIR)/"tif_print.obj" \ + $(INTDIR)/"tif_dirread.obj" \ + $(INTDIR)/"tif_getimage.obj" \ + $(INTDIR)/"tif_fax3.obj" \ + $(INTDIR)/"tif_version.obj" \ + $(INTDIR)/"tif_codec.obj" \ + $(INTDIR)/"tif_dir.obj" \ + $(INTDIR)/"tif_predict.obj" \ + $(INTDIR)/"tif_close.obj" \ + $(INTDIR)/"tif_dumpmode.obj" \ + $(INTDIR)/"tif_aux.obj" \ + $(INTDIR)/"tif_error.obj" \ + $(INTDIR)/"tif_lzw.obj" \ + $(INTDIR)/"tif_zip.obj" \ + $(INTDIR)/"tif_read.obj" \ + $(INTDIR)/"tif_packbits.obj" \ + $(INTDIR)/"tif_swab.obj" \ + $(INTDIR)/"tif_dirwrite.obj" \ + $(INTDIR)/"tif_open.obj" \ + $(INTDIR)/"tif_warning.obj" \ + $(INTDIR)/"tif_tile.obj" \ + $(INTDIR)/"tif_strip.obj" \ + $(INTDIR)/"tif_next.obj" \ + $(INTDIR)/"tif_write.obj" \ + $(INTDIR)/"fax3sm.obj" + +$(OUTDIR)/"libtiff.lib" : $(OUTDIR) $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "APXdeb" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "APXdeb" +# PROP BASE Intermediate_Dir "APXdeb" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "APXdeb" +# PROP Intermediate_Dir "APXdeb" +OUTDIR=.\APXdeb +INTDIR=.\APXdeb + +ALL : $(OUTDIR)/"dlibtiff.lib" $(OUTDIR)/"libtiff.bsc" + +$(OUTDIR) : + if not exist $(OUTDIR)/nul mkdir $(OUTDIR) + +CPP=cl.exe +# ADD BASE CPP /nologo /ML /Gt0 /W3 /GX /Z7 /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /Z7 /YX /Od /I ".." /I "." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c +CPP_PROJ=/nologo /MT /Gt0 /W3 /GX /Z7 /YX /Od /I ".." /I "." /D "WIN32" /D\ + "_DEBUG" /D "_WINDOWS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"libtiff.pch" /Fo$(INTDIR)/\ + /c +CPP_OBJS=.\APXdeb/ + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o$(OUTDIR)/"libtiff.bsc" +BSC32_SBRS= \ + $(INTDIR)/"tif_jpeg.sbr" \ + $(INTDIR)/"tif_dirinfo.sbr" \ + $(INTDIR)/"tif_win32.sbr" \ + $(INTDIR)/"tif_flush.sbr" \ + $(INTDIR)/"tif_thunder.sbr" \ + $(INTDIR)/"tif_compress.sbr" \ + $(INTDIR)/"tif_print.sbr" \ + $(INTDIR)/"tif_dirread.sbr" \ + $(INTDIR)/"tif_getimage.sbr" \ + $(INTDIR)/"tif_fax3.sbr" \ + $(INTDIR)/"tif_version.sbr" \ + $(INTDIR)/"tif_codec.sbr" \ + $(INTDIR)/"tif_dir.sbr" \ + $(INTDIR)/"tif_predict.sbr" \ + $(INTDIR)/"tif_close.sbr" \ + $(INTDIR)/"tif_dumpmode.sbr" \ + $(INTDIR)/"tif_aux.sbr" \ + $(INTDIR)/"tif_error.sbr" \ + $(INTDIR)/"tif_lzw.sbr" \ + $(INTDIR)/"tif_zip.sbr" \ + $(INTDIR)/"tif_read.sbr" \ + $(INTDIR)/"tif_packbits.sbr" \ + $(INTDIR)/"tif_swab.sbr" \ + $(INTDIR)/"tif_dirwrite.sbr" \ + $(INTDIR)/"tif_open.sbr" \ + $(INTDIR)/"tif_warning.sbr" \ + $(INTDIR)/"tif_tile.sbr" \ + $(INTDIR)/"tif_strip.sbr" \ + $(INTDIR)/"tif_next.sbr" \ + $(INTDIR)/"tif_write.sbr" \ + $(INTDIR)/"fax3sm.sbr" + +$(OUTDIR)/"libtiff.bsc" : $(OUTDIR) $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LIB32=lib.exe +# ADD BASE LIB32 /NOLOGO +# ADD LIB32 /NOLOGO /OUT:"APXdeb\dlibtiff.lib" +LIB32_FLAGS=/NOLOGO /OUT:"APXdeb\dlibtiff.lib" +DEF_FLAGS= +DEF_FILE= +LIB32_OBJS= \ + $(INTDIR)/"tif_jpeg.obj" \ + $(INTDIR)/"tif_dirinfo.obj" \ + $(INTDIR)/"tif_win32.obj" \ + $(INTDIR)/"tif_flush.obj" \ + $(INTDIR)/"tif_thunder.obj" \ + $(INTDIR)/"tif_compress.obj" \ + $(INTDIR)/"tif_print.obj" \ + $(INTDIR)/"tif_dirread.obj" \ + $(INTDIR)/"tif_getimage.obj" \ + $(INTDIR)/"tif_fax3.obj" \ + $(INTDIR)/"tif_version.obj" \ + $(INTDIR)/"tif_codec.obj" \ + $(INTDIR)/"tif_dir.obj" \ + $(INTDIR)/"tif_predict.obj" \ + $(INTDIR)/"tif_close.obj" \ + $(INTDIR)/"tif_dumpmode.obj" \ + $(INTDIR)/"tif_aux.obj" \ + $(INTDIR)/"tif_error.obj" \ + $(INTDIR)/"tif_lzw.obj" \ + $(INTDIR)/"tif_zip.obj" \ + $(INTDIR)/"tif_read.obj" \ + $(INTDIR)/"tif_packbits.obj" \ + $(INTDIR)/"tif_swab.obj" \ + $(INTDIR)/"tif_dirwrite.obj" \ + $(INTDIR)/"tif_open.obj" \ + $(INTDIR)/"tif_warning.obj" \ + $(INTDIR)/"tif_tile.obj" \ + $(INTDIR)/"tif_strip.obj" \ + $(INTDIR)/"tif_next.obj" \ + $(INTDIR)/"tif_write.obj" \ + $(INTDIR)/"fax3sm.obj" + +$(OUTDIR)/"dlibtiff.lib" : $(OUTDIR) $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ENDIF + +################################################################################ +# Begin Group "Source Files" + +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_jpeg.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_jpeg.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_jpeg.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_jpeg.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_jpeg.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_jpeg.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_jpeg.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_dirinfo.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_dirinfo.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_dirinfo.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_dirinfo.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_dirinfo.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_dirinfo.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_dirinfo.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_win32.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_win32.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_win32.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_win32.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_win32.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_win32.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_win32.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_flush.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_flush.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_flush.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_flush.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_flush.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_flush.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_flush.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_thunder.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_thunder.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_thunder.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_thunder.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_thunder.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_thunder.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_thunder.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_compress.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_compress.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_compress.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_compress.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_compress.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_compress.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_compress.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_print.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_print.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_print.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_print.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_print.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_print.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_print.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_dirread.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_dirread.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_dirread.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_dirread.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_dirread.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_dirread.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_dirread.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_getimage.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_getimage.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_getimage.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_getimage.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_getimage.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_getimage.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_getimage.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_fax3.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_fax3.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_fax3.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_fax3.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_fax3.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_fax3.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_fax3.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_version.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_version.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_version.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_version.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_version.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_version.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_version.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_codec.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_codec.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_codec.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_codec.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_codec.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_codec.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_codec.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_dir.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_dir.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_dir.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_dir.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_dir.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_dir.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_dir.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_predict.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_predict.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_predict.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_predict.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_predict.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_predict.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_predict.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_close.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_close.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_close.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_close.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_close.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_close.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_close.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_dumpmode.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_dumpmode.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_dumpmode.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_dumpmode.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_dumpmode.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_dumpmode.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_dumpmode.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_aux.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_aux.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_aux.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_aux.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_aux.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_aux.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_aux.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_error.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_error.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_error.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_error.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_error.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_error.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_error.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_lzw.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_lzw.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_lzw.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_lzw.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_lzw.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_lzw.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_lzw.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_zip.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_zip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_zip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_zip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_zip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_zip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_zip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_read.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_read.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_read.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_read.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_read.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_read.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_read.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_packbits.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_packbits.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_packbits.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_packbits.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_packbits.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_packbits.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_packbits.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_swab.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_swab.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_swab.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_swab.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_swab.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_swab.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_swab.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_dirwrite.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_dirwrite.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_dirwrite.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_dirwrite.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_dirwrite.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_dirwrite.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_dirwrite.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_open.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_open.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_open.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_open.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_open.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_open.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_open.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_warning.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_warning.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_warning.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_warning.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_warning.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_warning.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_warning.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\libtiff.def +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_tile.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_tile.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_tile.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_tile.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_tile.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_tile.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_tile.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_strip.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_strip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_strip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_strip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_strip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_strip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_strip.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_next.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_next.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_next.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_next.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_next.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_next.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_next.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE="\tiff\tiff-v3.4beta024\libtiff\tif_write.c" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"tif_write.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"tif_write.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"tif_write.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"tif_write.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"tif_write.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"tif_write.obj" : $(SOURCE) $(INTDIR) + $(CPP) $(CPP_PROJ) $(SOURCE) + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fax3sm.c +DEP_FAX3S=\ + "\tiff\tiff-v3.4beta024\libtiff\tiff.h"\ + "\tiff\tiff-v3.4beta024\libtiff\tif_fax3.h" + +!IF "$(CFG)" == "Win32 Release" + +$(INTDIR)/"fax3sm.obj" : $(SOURCE) $(DEP_FAX3S) $(INTDIR) + +!ELSEIF "$(CFG)" == "Win32 Debug" + +$(INTDIR)/"fax3sm.obj" : $(SOURCE) $(DEP_FAX3S) $(INTDIR) + +!ELSEIF "$(CFG)" == "Macintosh Release" + +$(INTDIR)/"fax3sm.obj" : $(SOURCE) $(DEP_FAX3S) $(INTDIR) + +!ELSEIF "$(CFG)" == "Macintosh Debug" + +$(INTDIR)/"fax3sm.obj" : $(SOURCE) $(DEP_FAX3S) $(INTDIR) + +!ELSEIF "$(CFG)" == "APXrel" + +$(INTDIR)/"fax3sm.obj" : $(SOURCE) $(DEP_FAX3S) $(INTDIR) + +!ELSEIF "$(CFG)" == "APXdeb" + +$(INTDIR)/"fax3sm.obj" : $(SOURCE) $(DEP_FAX3S) $(INTDIR) + +!ENDIF + +# End Source File +# End Group +# End Project +################################################################################ diff --git a/contrib/winnt/libtiff.vcp b/contrib/winnt/libtiff.vcp new file mode 100644 index 0000000000000000000000000000000000000000..4c63936d895a9a7dc1299c4db02156f4649b0ae7 GIT binary patch literal 17408 zcmeHOO-x(a6+SS)I3@-rq#34@N#3|o3sqtaMy*L^qyXl}DZ!Qv4XP}Gf1a_4v0c9h z7&4VuwJf?|HWiC5GP`NjN>N*>v+SaaEV{@ti!NAn!KPBAb}@^#>38mZ4-A2DL7K$_ zKk5D4d(XM|oOAE}&VA>;_aHv*e}|gLOVmj9P>AXJLV6^nU|UGnRmKg>)0o2Nr@JU!sstnfYwix0HPR`gJFbL@T95 zJ#B_c>1lnbTu7Qa(dW#EgKvi|yNJ9X&P5cCGQng%RlyCIBaat1gS7eiAZ`8JPk+br zUvX;wKH9~d%U=GWkN%B2m;GhFpGXUeviX1X(`7t!+0JJH>cTUZb-M@X7Vccu@p6Ft zxO3T;fA&+;--4oSpK7Kbb9UdDKmpeZW_y&eYr-%Ig1BuD-uqb#G zo=OZwXG5dIOfwe>$HG%%5np8Zf#84ESf$cJNjqyj@!^=1ykHj6Nm!sd6;%InKX^gQPSU+GNN5ou0O3pp8(}n=Q?T8hf4NkInjx|+)1{OT8n{N zvOcBuBtQ4z9{*O&c97h%uIzwV*=s1L(83O!hn$fRDRN~ zhY_CL(H8vK#=Sj!AK$pTF7hpv;g42{-BgVU%-nJ@qgT*VK(nCx39(mGu_J?Y*Uc4r zh4xhF6YM{)VLkAPBK?s7668#%OPKUNxK6Lmg_{Dl(D(P`Q1^;k-B*6GD^SU|N|0VL{Js!8f ze>Ww!+At2V?mulit#nz;%lhRaT7b9wO&w)lj9)w!y>rp4tSyK7Au!K%e_7?!zdn@D_T{o4oG-zwvCExuEehzoH0NAh#I zC^!_~8jZywa`jKbUOC9Y@s;E1Iqp3|*273Io$4;^!TlvoMf3`34oX?3qpy+HGx>B4 zl|CIeD;ybpG8)y&HXiBL)sieSr zn|}-Z9Is=%xAV}Sfo{A}FsOJ&KWVM)H(36JFt^BjuiXl;}EDPzW z<%NSK?>$VW^F^~{_K+UM7Z@(rt4}P=yN$Ka0rQug78IFQK64Qr8{R8s51VnaFKJAQt79{`s#Tbdc57{pci|UMbdd((3X?w$Em#O zsFy00zA{#^G47!8r{tybmDNh#bd;A;=_`DY;HXu)%IeSBxOdVJtoaB&qi0X$U=j7+ z;5g}QOZcG%D^!ZGIo-MRn|9#Svh~6v#3|k-HVXppxEt8aG1wf za?+G}C!?1e@JaSaNQalm=*9HfNU3Nh^F>{Jwa2K#M~g&_7T$95r(T7^*hHT(n8wBF?{Zr5zsu?GaeD0Tb=1rJIq2U^Qh(m9+%fy` zP34R+iE^gz@bx1t`T5g!*1y@Rpa0f)J{Umx^xaQD&+X-)KlAHz568-u+#dJaET-Mn zv|HWr$V`ms@fhCkaF}`|8fE=)n~TOG4|;6kkrtn>}-!) z;}ja`k+);p*<$(df0pJ2`Pg`mSNrr+&3j;b*$Z)K19ZhIw+})bpqr$zY3s+iwLk~`AJ< tiff.alpha +else + echo "define ALPHA 001" >tiff.alpha +fi diff --git a/dist/newversion b/dist/newversion new file mode 100644 index 00000000..a693dffd --- /dev/null +++ b/dist/newversion @@ -0,0 +1,32 @@ +#! /bin/sh +# $Header: /cvs/maptools/cvsroot/libtiff/dist/Attic/newversion,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# TIFF Software +# +# Copyright (c) 1994-1996 Sam Leffler +# Copyright (c) 1994-1996 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +rm -f tiff.version +awk ' +$1 ~ /.*beta/ { print "define TIFF_VNUM " $0 } +$1 !~ /.*beta/{ print "define TIFF_VNUM \"" $0 " (release)\"" } +' ../VERSION > tiff.version diff --git a/dist/tiff.alpha b/dist/tiff.alpha new file mode 100644 index 00000000..316b4d7b --- /dev/null +++ b/dist/tiff.alpha @@ -0,0 +1 @@ +define ALPHA 037 diff --git a/dist/tiff.spec b/dist/tiff.spec new file mode 100644 index 00000000..38c78acc --- /dev/null +++ b/dist/tiff.spec @@ -0,0 +1,68 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/dist/Attic/tiff.spec,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# TIFF Software +# +# Copyright (c) 1994-1997 Sam Leffler +# Copyright (c) 1994-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +define CUR_MAJ_VERS 1006 # Major Version number +define CUR_MIN_VERS 001 # Minor Version number +define CUR_VERS ${CUR_MAJ_VERS}${CUR_MIN_VERS}${ALPHA} +define TIFF_NAME "TIFF" + +include tiff.version +include tiff.alpha + +product tiff + id "${TIFF_NAME} Tools, Version ${TIFF_VNUM}" + inplace + + image sw + id "${TIFF_NAME} Software" + version "${CUR_VERS}" + subsys tools default + id "${TIFF_NAME} Tools & Library DSO" + exp "tiff.sw.tools" + endsubsys + subsys dev + id "${TIFF_NAME} Developement Software" + exp "tiff.sw.dev" + endsubsys + endimage + + image man + id "${TIFF_NAME} Documentation" + version "${CUR_VERS}" + subsys tools default + id "${TIFF_NAME} Tools Manual Pages" + exp "tiff.man.tools" + endsubsys + subsys dev + id "${TIFF_NAME} Library Manual Pages" + exp "tiff.man.dev" + endsubsys + subsys html + id "${TIFF_NAME} HTML Materials" + exp "tiff.man.html" + endsubsys + endimage +endproduct diff --git a/dist/tiff.version b/dist/tiff.version new file mode 100644 index 00000000..c89a3244 --- /dev/null +++ b/dist/tiff.version @@ -0,0 +1 @@ +define TIFF_VNUM 3.4beta diff --git a/html/Makefile.in b/html/Makefile.in new file mode 100644 index 00000000..6f0cfc8b --- /dev/null +++ b/html/Makefile.in @@ -0,0 +1,104 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/html/Makefile.in,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# @WARNING@ +# +# Tag Image File Format Library Manual Pages +# +# Copyright (c) 1991-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +DEPTH = .. + +SRCDIR = ${DEPTH}/@SRCDIR@/html +VPATH = ../@SRCDIR@/html + +PORT = ${DEPTH}/port + +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# CCOMPILER: @CCOMPILER@ +# +SHELL = @SCRIPT_SH@ +NULL = +ECHO = echo +MV = mv +RM = rm -f +INSTALL = @INSTALL@ + +HTML = @DIR_HTML@ + +HTMLFILES=\ + bugs.html \ + build.html \ + contrib.html \ + document.html \ + images.html \ + index.html \ + internals.html \ + intro.html \ + libtiff.html \ + misc.html \ + support.html \ + tools.html \ + v3.4beta007.html \ + v3.4beta016.html \ + v3.4beta018.html \ + v3.4beta024.html \ + v3.4beta028.html \ + v3.4beta029.html \ + v3.4beta031.html \ + v3.4beta032.html \ + v3.4beta033.html \ + v3.4beta034.html \ + v3.4beta035.html \ + v3.4beta036.html \ + ${NULL} +IMAGES=\ + images/back.gif \ + images/bali.jpg \ + images/cat.gif \ + images/cover.jpg \ + images/cramps.gif \ + images/jello.jpg \ + images/jim.gif \ + images/note.gif \ + images/oxford.gif \ + images/quad.jpg \ + images/ring.gif \ + images/smallliz.jpg \ + images/strike.gif \ + images/warning.gif \ + ${NULL} +TARGETS= + +all: ${TARGETS} + +install: all + ${INSTALL} -m 755 -dir -idb tiff.man.html ${HTML} ${HTML}/images + for i in ${HTMLFILES} ${IMAGES}; do \ + ${INSTALL} -idb tiff.man.html -m 444 -F ${HTML} \ + -src ${SRCDIR}/$$i -O $$i; \ + done + +clean:; diff --git a/html/bugs.html b/html/bugs.html new file mode 100644 index 00000000..2269d7eb --- /dev/null +++ b/html/bugs.html @@ -0,0 +1,66 @@ + + + +Bugs and the TIFF Mailing List + + + +

+ +Bugs and the TIFF Mailing List +

+ +
+This documentation is best viewed using a graphical browser that supports +the latest HTML directives for formatting documents. In particular, +this document was authored +for viewing with version 1.1 or newer of the +Netscape Navigator. +
+ +
+ +

+This software is free. The only thing that I ask in return is that you +tell me when you find a problem or fix a bug. I also gladly accept +software contributions, although I hesitate to include such software in +my regular stuff if I am personally unable to test it. + +

+A mailing list for users of this software is located on sgi.com. +If you want to join this mailing list or have a list-related request +such as getting your name removed from it, send a request to +

+For example, to subscribe, send the line +
    +subscribe
    +
+in the body of your message. The line help will return a list of +the commands understood by the mailing list management software. + +

+Submissions (including bug reports) should be directed to: +

+When corresponding about this software please always specify what +version you have and what system you are running on. + +

+If all else fails, I can be reached by sending mail to the address +shown below. +(but beware that I'm more likely to respond to mail sent to the +mailing list than mail sent directly to me). + +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/build.html b/html/build.html new file mode 100644 index 00000000..fff599f1 --- /dev/null +++ b/html/build.html @@ -0,0 +1,1153 @@ + + + +Building the TIFF Software Distribution + + + +

+ +Building the Software Distribution +

+ + + +
+ +This chapter contains step-by-step instructions on how to configure +and build the TIFF software distribution. +The software is most easily built on a UNIX system, but with a little +bit of work it can easily be built and used on other non-UNIX platforms. + +

Building on a UNIX System

+ +To build the software on a UNIX system +you need to first run the configure shell script +that is located in the top level of the source directory. +This script probes the target system for necessary tools and functions +and constructs a build environment in which the software may be +compiled. +Once configuration is done, you simply run make + to build the software +and then make install to do the installation; for example: + +
    +hyla% cd tiff-v3.4beta099
    +hyla% ./configure
    +    ...lots of messages...
    +hyla% make
    +    ...lots of messages...
    +hyla# make install
    +
+ +In general, the software is designed such that the following should +be ``make-able'' in each directory: + +
    +make [all]	build stuff
    +make install	build&install stuff
    +make clean	remove .o files and cruft, but not executables
    +make clobber	remove everything that can be recreated
    +make distclean	remove absolutely everything that can be recreated
    +
+ +Note that after running "make clobber" or +"make distclean" the configure script must +be run again to create the Makefiles and other make-related files. + +


Build Trees

+ +There are two schemes for configuring and building the software. +If you intend to build the software for only one target system, you +can configure the software so that it is built in the same directories +as the source code. + +
    +hyla% cd tiff-v3.4beta099
    +hyla% ls
    +COPYRIGHT       VERSION         config.sub      dist            man
    +Makefile.in     config.guess    configure       html            port
    +README          config.site     contrib         libtiff         tools
    +hyla% ./configure
    +
+ +

+Otherwise, you can configure a build tree that +is parallel to the source tree hierarchy but which contains only +configured files and files created during the build procedure. + +

    +hyla% cd tiff-v3.4beta099
    +hyla% mkdir obj obj/mycpu
    +hyla% cd obj/mycpu
    +hyla% ../../configure
    +
+ +This second scheme is useful for: + +
    +
  • building multiple targets from a single source tree +
  • building from a read-only source tree (e.g. if you receive + the distribution on CD-ROM) +
+ +


Configuration Files

+ +The configuration process is critical to the proper compilation, +installation, and operation of the software. +The configure script runs a series of tests to +decide whether or not the target system +supports required functionality and, if it does not, whether it +can emulate or workaround the missing functions. +This procedure is fairly complicated and, due to the nonstandard +nature of most UNIX systems, prone to error. +The first time that you configure the software for use you should +check the output from the configure script and look for anything +that does not make sense for your system. +A sample configure run is shown below together with an explanation +of some of the work that is done. + +

+A second function of the configure script is to set the default +configuration parameters for the software. +Of particular note are the directories where the software is to be +installed. +By default the software is installed in the /usr/local hierarchy. +To change this behaviour the appropriate parameters can be +specified either: +

    +
  • on the command line to configure, +
  • in a site-wide configuration file, or +
  • in a target-specific configuration file. +
+configure reads any site-wide configure file first, and +then any target-specific configuration file. +This permits target-specific definitions to override +site-wide definitions. + +

+Site-wide configuration files are named +config.site and are automatically searched for first +in any directory specified on the command line to configure +(using the -site option), or if that fails, in +the directory in in which the configure script is located. + +

+Target-specific configuration files are named config.local +and are looked for first in the top-level configuration directory, +or, if that fails, in the directory in which the configure script +is located. + +

+Configuration files are just shell scripts that define +shell variables that control the configuration process. +For example, the following file might be used on a BSDI system to +configure the software for installation in the /usr/contrib area. + +

+#
+# Parameters suitable for BSDI 1.1
+#
+DIR_BIN="/usr/contrib/bin"		# directory for client apps
+DIR_LIB="/usr/contrib/lib"		# directory for libraries
+DIR_MAN="/usr/contrib/man"		# directory for manual pages
+
+ +

+For a complete list of the possible configuration parameters look +at the sample config.site file provided in the distribution; the +section below describes some of the more important parameters. + +


Configuring Optional Packages/Support

+ +The TIFF software comes with several packages that are installed only +as needed, or only if specifically configured at the time +the configure script is run. Packages can be configured in a +config.site or config.local file, or by using a +-with-<PACKAGE> option when invoking configure; +e.g. configure -with-AFM. + +
+
DSO Support +
The DSO support controls whether or not to +configure the software +to build a Dynamic Shared Object for the TIFF library. +Use of DSOs can significantly reduce the disk space needed for +users of the TIFF software. +If DSOs are not used then the code is statically linked into +each application that uses it. +By default this support is configured only if the system appears +to suport DSOs in a way that fits into the normal build scheme +(auto). +If DSO support is explicitly enabled and there is no +support for using DSOs in the expected way then DSOs are not used. + +

+

JPEG Support +
The JPEG package enables support for the handling +of TIFF images with JPEG-encoded data. +Support for JPEG-encoded data requires the Independent JPEG Group (IJG) +libjpeg distribution; this software is available at +ftp.uu.net:/graphics/jpeg/. +If JPEG support is enabled the DIRS_LIBINC and DIR_JPEGLIB +parameters should also be set (see below). +By default JPEG support is not configured. + +

+

ZIP Support +
The ZIP support enables support for the handling +of TIFF images with deflate-encoded data. +Support for deflate-encoded data requires the freely available +zlib distribution written by Jean-loup Gailly and Mark Adler; +this software is available at +ftp.uu.net:/pub/archiving/zip/zlib/ +(or try quest.jpl.nasa.gov:/beta/zlib/). +If ZIP support is enabled the DIRS_LIBINC and DIR_GZLIB +parameters should also be set (see below). +By default this package is not configured. + +
+ +


A Sample Configuration Session

+ +This section shows a sample configuration session and describes +the work done. The session is shown indented in a fixed width +font with user-supplied input in a bold font. +Comments are shown in a normal or italic font. +This session was collected on a 486 machine running BSDI 1.1. + +
    
    +wullbrandt% mkdir tiff
    +wullbrandt% cd tiff
    +wullbrandt% ln -s /hosts/oxford/usr/people/sam/tiff src
    +
+ +A build tree separate from the source tree is used here. +In fact, in this case the distribution is accessed from +a read-only NFS-mounted filesystem. + +
    
    +wullbrandt% src/configure
    +Configuring TIFF Software v3.4beta015.
    +
    +Reading site-wide parameters from ../tiff-v3.4beta015/config.site.
    +Reading local parameters from config.local.
    +Gosh, aren't you lucky to have a i386-unknown-bsdi1.1 system!
    +
+ +Note that configure announces the distribution version and the +deduced target configuration (i386-unknown-bsdi1.1 here). + +
    
    +Using /usr/local/bin/gcc for a C compiler (set CC to override).
    +Looks like /usr/local/bin/gcc supports the -g option.
    +Using " -g" for C compiler options.
    +
+ +configure checked the normal shell search path for potential +ANSI C compilers. The compiler is selected according to it properly +compiling a small ANSI C test program. A specific compiler may be requested +by setting the CC environment variable to the appropriate +pathname, by supplying the parameter on the command line, e.g. +-with-CC=gcc, or by setting CC in a configuration +file. + +

+ +Note that an ANSI C compiler is required to build the software. +If a C compiler requires options to enable ANSI C compilation, they +can be specified with the ENVOPTS parameter. + +

+Once a compiler is selected configure checks to see +if the compiler accepts a -g option to enable the generation + of debugging symbols, and +if the compiler includes an ANSI C preprocessor. + +

    
    +Using /usr/ucb/make to configure the software.
    +
+ +Next various system-specific libraries that may or may not be needed +are checked for (none are needed in this case). +If your system requires a library that is not +automatically included it can be specified by setting the +MACHDEPLIBS parameter. + +

Creating port.h. +The port.h file is included by all the C code +in the library (but not the tools). +It includes definitions for functions and type +definitions that are missing from system include files, #defines +to enable or disable system-specific functionality, and other +odds and ends. + +

    
    +Creating libtiff/port.h with necessary definitions.
    +... using LSB2MSB bit order for your i386 cpu
    +... using big-endian byte order for your i386 cpu
    +... configure use of mmap for memory-mapped files
    +... O_RDONLY is in <fcntl.h>
    +... using double for promoted floating point parameters
    +... enabling use of inline functions
    +Done creating libtiff/port.h.
    +
+ +This file can take a long time to create so configure +generates the file only when it is needed, either because the +file does not exist or because a different target or compiler +is to be used. +Note that running "make distclean" in the top-level directory +of the build tree will remove the port.h file (along +with all the other files generated by configure). + +

Selecting emulated library functions. +Certain library functions used by the tools are not present on all systems +and can be emulated using other system functionality. +configure checks for the presence of such functions and if they are +missing, will configure emulation code from the port directory +to use instead. Building the TIFF +software on unsupported systems may require +adding to the code to the port directory. + +

    
    +Checking system libraries for functionality to emulate.
    +Done checking system libraries.
    +
+ +If a routine must be emulated and configure does not automatically +check for it, the routine name can be specified using the PORTFUNCS +parameter. To add emulation support for a new function foo, +create a file port/foo.c that contains the emulation code +and then set PORTFUNCS=foo in a configuration file or modify +the configure script to automatically check for the missing function. + +
    
    +Checking for Dynamic Shared Object (DSO) support.
    +Done checking for DSO support.
    +
+ +If the DSO package is enabled (DSO=auto or +DSO=yes), then +configure will verify the system and compiler are capable of +constructing SVR4-style DSO's in the expected way. Note that +while a system may support DSO's the compiler may not be +capable of generating the required position-independent +code and/or the compiler may not pass the needed options +through to the loader. + +

Selecting utility programs. +configure locates various system utility programs that are +used during installation of the software. + +

    
    +Selecting programs used during installation.
    +Looks like mv supports the -f option to force a move.
    +Looks like /bin/ln supports the -s option to create a symbolic link.
    +Done selecting programs.
    +
+ +

Selecting default configuration parameters. +The remainder of the work done by configure involves setting up +configuration parameters that control the placement and +setup of files during the installation procedure. + +

    
    +Selecting default TIFF configuration parameters.
    +
    +Looks like manual pages go in /usr/contrib/man.
    +Looks like manual pages should be installed with bsd-nroff-gzip-0.gz.
    +
    +TIFF configuration parameters are:
    +
    +[ 1] Directory for tools:               /usr/contrib/bin
    +[ 2] Directory for libraries:           /usr/contrib/lib
    +[ 3] Directory for include files:       /usr/contrib/include
    +[ 4] Directory for manual pages:        /usr/contrib/man
    +[ 5] Manual page installation scheme:   bsd-nroff-gzip-0.gz
    +
    +Are these ok [yes]? 
    +
+ + + +At this point you can interactively modify any of the +displayed parameters. Hitting a carriage return or typing +yes will accept the current parameters. Typing one +of the number displayed along the left hand side causes +configure to prompt for a new value of the specified parameter. +Typing anything else causes configure to prompt for a new +value for each parameter. +In general hitting carriage return will accept the current +value and typing anything that is unacceptable will cause a +help message to be displayed. +A description of each of the configuration parameters is given below. + +

+Once acceptable parameters are setup configure will generate +all the files that depend on these parameters. Note that certain +files may or may not be created based on the configuration of +optional packages and/or the functions supported by target system. + +

    
    +Creating Makefile from ../tiff-v3.4beta015/Makefile.in
    +Creating libtiff/Makefile from ../tiff-v3.4beta015/libtiff/Makefile.in
    +Creating man/Makefile from ../tiff-v3.4beta015/man/Makefile.in
    +Creating tools/Makefile from ../tiff-v3.4beta015/tools/Makefile.in
    +Creating port/install.sh from ../tiff-v3.4beta015/port/install.sh.in
    +Done.
    +
+ +


Shared Library Support

+ +It is desirable to make the TIFF library be a shared object +on systems that have support for shared libraries. +Unfortunately the rules to use to build a shared library +vary between operating systems and even compilers. +The distributed software includes support for building a shared +version of the library on a number of different systems. +This support is split between rules in the file +libtiff/Makefile.in that construct the shared library +and checks done by the configure script to verify that +the expected rules are supported by compilation tools for +the target system. + +

+To add new support for building a shared library both these files +must be updated. +In the configure script search for the section where the autoconfiguration +setting of the DSO parameter is handled and +add a new case for the target system that sets the +DSOSUF, +DSOLD, +DSOOPTS, +and +LIBCOPTS +options as appropriate for the system. +DSOSUF specifies the filename suffix used for the shared +library (e.g. ``.so'' for Dynamic Shared Objects on most SVR4-based +systems). +DSOLD specifies the program to use to build the shared library +from a compiled object file; typically ``${LD}'' though on some systems +it is better to use the C compiler directly so system-dependent options and +libraries are automatically supplied. +DSOOPTS are options that must be specified to DSOLD +when building the shared library. +LIBCOPTS are options to pass to the C compiler when constructing +a relocatable object file to include in a shared library; e.g. ``-K PIC'' +on a Sun system. +The DSO parameter must also be set to a unique label that identifies +the target system and compilation tools. +This label is used to select +a target in libtiff/Makefile.in to do the actual work in building +the shared library. +Finally, to complete support for the shared library added the appropriate +rules to libtiff/Makefile.in under the target specified in the +configure script. + + + + +


Configuration Parameters

+ +This section gives a brief description of the less obvious +configuration parameters. Consult the distributed config.site +for a complete list of parameters. +The list here is sorted alphabetically. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AROPTSThe options passed to ar when creating an archive. +Note that configure will automatically check to see if ar +supports an s to create a symbol table instead of +using ranlib.
DIR_BINThe directory where client applications should be installed; by +default this is /usr/local/bin.
DIR_GZLIBThe pathname of the directory containing the zlib library +(when ZIP or PixarLog compression support is enabled); +e.g. ``../src/zlib''.
DIR_JPEGLIBThe pathname of the directory containing the JPEG library +(when JPEG support is enabled); e.g. ``/usr/local/lib''.
DIR_LIBThe directory to install libraries and DSO's; by default +this is /usr/local/lib.
DIR_MANThe top-most directory of the manual area where manual +pages should be installed.
DIRS_LIBINCA space-separated list of directories in which to search for +include files when building the library and tools. +If JPEG or ZIP support is configured this parameter should include +the directories where the associated include files are located.
DIST_ALPHAThe alpha version number for the distribution; e.g. if this +is version 3.4beta031 then the the major number is 31.
DIST_MAJORThe major version number for the distribution; e.g. if this +is version 3.4beta031 then the the major number is 3.
DIST_MINORThe minor version number for the distribution; e.g. if this +is version 3.4beta031 then the the major number is 4.
DSOSUFWhen DSO's are built, the filename suffix for a DSO. +If this is set to "a" then statically linked archives are used.
DSOSUF_VERSIONWhen DSO's are built, a version-specific filename suffix for a DSO. +If this is set to something other than the value of DSO then +the file libtiff.DSOSUF_VERSION will be installed and +a link to it named libtiff.DSOSUF will automatically +be created. (Note that this means that rule for building the target +DSO must generate a file named libtiff.DSOSUF_VERSION.)
ENVOPTSOptions to pass to CC to force ANSI C compilation.
FILLORDERThe order of bits in a byte on the server machine; +either LSB2MSB or MSB2LSB. +This is normally selected according to the target system.
GCOPTSSpecial options to pass the C compiler. If this parameter +is set, then configure may append other options to this list.
INSTALLThe pathname of the install program to use. Note that this program +must emulate the command line interface used by the IRIX install program.
LIBPORTThe pathname of the library that holds code to emulate missing +system functionality. +Normally this parameter is set by configure based on whether or +not emulation code is required for the target. +
LLDOPTS +Extra command line options passed to CC +when linking an executable. +This option is usually set only when DSO support is enabled +(to force the executable to search for the TIFF DSO +in non-standard locations in the filesystem.)
MACHDEPLIBSTarget-dependent libraries that should be used when linking +tools. +Note that if this parameter is specified configure will append to +the list of libraries.
MANSCHEMEThe scheme to use when preparing and installing manual pages. +Schemes are constructed according to: +
    +<organization>-<formatting>-<compression>[-<suffix>] +
+where: +<organization> is either bsd +for BSD-style section organization (e.g. file formats in +section 5) or sysv for System V-style +organization (e.g. file formats in section 4). +<formatting> is either nroff to force +installation of formatted materials (using nroff) or +source to get the nroff source installed. +<compression> is either the name of a program +to compress the manual pages (gipz, compress, pack) or +cat for uncompressed data. +<suffix> is either the file suffix to convert +installed pages to (e.g. 0.gz for gzip-compressed pages under BSD) +or strip to force the normal ".4f" suffix to be converted to ".4" +(or ".5" if using the BSD organization). If no -<suffix> +is specified then filenames are not converted when they are installed.
PORTFUNCSA list of non-standard functions that should be emulated. +Normally this list is constructed by configure based on checks it does. +If this parameter is set, configure will append to the specified list.
SETMAKEIf make does not automatically set $MAKE to +the name of the make program to invoke for subdirectories, then +configure will create an explicit definition. +If this parameter is set, then it will be used instead. +by default bin is used.
+ + +


Building the Software under MS/DOS or Windows

+ + +There is a Makefile for Microsoft C. +There is OS support for MS-DOS and for Windows. +Someone needs to fill this in, but no DOS-weenies seem to +give a damn so this section is blank for now .... + + + + +


Building the Software under MS/DOS with the DJGPP v2 compiler

+ +[From the file contrib/dosdjgpp/README.] + +

+The directory contrib/dosdjgpp +contains the files necessary to build the library and tools +with the DJGPP v2 compiler under MSDOS. + +

+All you have to do is copy the files in the directory +into the respective directories and run +make. If you want, you can use the conf.bat script +to do that for you, make sure that +the file is stored with MSDOS text EOL-convention (CR/LF), otherwise the +command.com will not do anything. + +

+Note that you probably will not be able to build the library with the v1.x +versions of djgpp, due to two problems. First, the top makefile calls a +sub-make for each directory and you are likely to run out of memory, since +each recursive invocation of a djgpp v1.x program requires about 130k, to +avoid that, you can enter the directories manually and call make (well, there +are only two dirs). The 2nd problem is that djgpp 1.x doesn't call the +coff2exe (stubify) program when creating an executable. This means that all +programs compiled are not converted to exe and consequently are not available +for calling directly. For the tools directory, you can just call coff2exe for +each program after make finishes, but in the libtiff directory, a few programs +are created during the make process that have to be called for make to +continue (e.g. mkg3states). Make will probably report an error at each +such stage. To fix that, either add a coff2exe call before each program is +called or call coff2exe manually and rerun make (there 2-3 such programs). + + +


Building the Software on a Macintosh with MPW

+ +The directory contrib/mac-mpw contains support for +compiling the library and tools under the MPW Shell on a +Macintosh system. +This support was contributed by Niles Ritter +(ndr@tazboy.jpl.nasa.gov). + +

+[From the file contrib/mac-mpw/README.] + +

+This directory contains all of the utilities and makefile source +to build the LIBTIFF library and tools from the MPW Shell. The +file BUILD.mpw in this directory is an executable script +which uses all of these files to create the MPW makefiles and +run them. + +

+The .make files are not MPW makefiles as such, +but are when run through the "mactrans" program, which turns +the ascii "%nn" metacharacters into the standard weird MPW +make characters. + +

+This translation trick is necessary to protect the files when +they are put into unix tarfiles, which tend to mangle the +special characters. + + + +


Building the Software on a Macintosh with CodeWarrior

+ +The directory contrib/mac-cw contains support for +compiling the library and tools with MetroWerks CodeWarrior 6.1 +on a Macintosh system. +This support was contributed by Niles Ritter +(ndr@tazboy.jpl.nasa.gov). + +

+[From the file contrib/mac-cw/README.] + +In this directory you will find a Makefile.script Applescript +file, which should be run in order to build the libtiff code +using MetroWerks CodeWarrior. + +Refer to the "metrowerks.note" instructions on building the +library for 68k and PowerPC native code, as well as building +some of the libtiff tools, which are rather unix-like, but +at least give an example of how to link everything together. + + + +


Building the Software on a VMS System

+ +The VMS port was done by Karsten Spang +(krs@kampsax.dk), who also +"sort of" maintains it. +The VMS specific files are not in the main directories. Instead they +are placed under [.CONTRIB.VMS...] in the distribution tree. + +Installation: + +It is assumed that you have unpacked the tar file into a VMS directory +tree, in this text called DISK:[TIFF]. + +
    +
  1. Move the VMS specific files to their proper directories. +
    +$ SET DEFAULT DISK:[TIFF.CONTRIB.VMS]
    +$ RENAME [.LIBTIFF]*.* [-.-.LIBTIFF]
    +$ RENAME [.TOOLS]*.* [-.-.TOOLS]
    +
    +
  2. Compile the library. +
    +$ SET DEFAULT DISK:[TIFF.LIBTIFF]
    +$ @MAKEVMS
    +
    +
  3. Compile the tools. +
    +$ SET DEFAULT DISK:[TIFF.TOOLS]
    +$ @MAKEVMS
    +
    +
  4. Define the programs. +
    +$ DEFINE TIFFSHR DISK:[TIFF.LIBTIFF]TIFFSHR
    +$ FAX2PS    :==$DISK:[TIFF.TOOLS]FAX2PS
    +$ FAX2TIFF  :==$DISK:[TIFF.TOOLS]FAX2TIFF
    +$ GIF2TIFF  :==$DISK:[TIFF.TOOLS]GIF2TIFF
    +$ PAL2RGB   :==$DISK:[TIFF.TOOLS]PAL2RGB
    +$ PPM2TIFF  :==$DISK:[TIFF.TOOLS]PPM2TIFF
    +$ RAS2TIFF  :==$DISK:[TIFF.TOOLS]RAS2TIFF
    +$ RGB2YCBCR :==$DISK:[TIFF.TOOLS]RGB2YCBCR
    +$ THUMBNAIL :==$DISK:[TIFF.TOOLS]THUMBNAIL
    +$ TIFF2BW   :==$DISK:[TIFF.TOOLS]TIFF2BW
    +$ TIFF2PS   :==$DISK:[TIFF.TOOLS]TIFF2PS
    +$ TIFFCMP   :==$DISK:[TIFF.TOOLS]TIFFCMP
    +$ TIFFCP    :==$DISK:[TIFF.TOOLS]TIFFCP
    +$ TIFFDITHER:==$DISK:[TIFF.TOOLS]TIFFDITHER
    +$ TIFFDUMP  :==$DISK:[TIFF.TOOLS]TIFFDUMP
    +$ TIFFINFO  :==$DISK:[TIFF.TOOLS]TIFFINFO
    +$ TIFFMEDIAN:==$DISK:[TIFF.TOOLS]TIFFMEDIAN
    +$ TIFFSPLIT :==$DISK:[TIFF.TOOLS]TIFFSPLIT
    +$ YCBCR     :==$DISK:[TIFF.TOOLS]YCBCR
    +
    +
+ +You will want to add these lines to your LOGIN.COM +file, after changing +the name of the directory that you have used on your machine. + +

+This release has been tested on OpenVMS/VAX 5.5-2, using VAX C 3.2. +A previous release was tested under OpenVMS/AXP ?.? using DEC C ?.?, it is +believed that this release as well works on AXP. +The code contains some GNU C specific things. This does *not* imply, +however, that the VAX/GCC configuration has been tested, *it has not*. + +

+The command procedures (MAKEVMS.COM) for building the +library and tools, +is believed to choose the correct options for the VAX and AXP cases +automatically. + +

+On the AXP, IEEE floating point is used by default. If you want VAX +floating point, remove the /FLOAT=IEEE_FLOAT qualifier, and change +HAVE_IEEEFP=1 to HAVE_IEEEFP=0 in the MAKEVMS.COM +files in both the libtiff and tools directories. + + +

Compiling your own program on a VMS system:

+ +When compiling a source file in which you +"#include ", use the +following command +
+    $ CC/INCLUDE=DISK:[TIFF.LIBTIFF]
+
+This ensures that the header file is found. +On the AXP, also add /FLOAT=IEEE_FLOAT +(if used when building the library). + + +

Linking your own program to the TIFF library on a VMS system:

+ +You can link to the library in two ways: Either using the shareable +library, or using the object library. +On the VAX these possibilities are: + +
    +
  1. Using the shareable TIFF library. +
    +$ LINK MY_PROGRAM,DISK:[TIFF.LIBTIFF]TIFF/OPTIONS,SYS$INPUT:/OPTIONS
    +    SYS$SHARE:VAXCRTL/SHAREABLE
    +
    +
  2. Using the TIFF object library. +
    +$ LINK MY_PROGRAM, -
    +    DISK:[TIFF.LIBTIFF]TIFF/LIBRARY/INCLUDE=(TIF_FAX3SM,TIF_CODEC), -
    +    SYS$INPUT:/OPTIONS
    +    SYS$SHARE:VAXCRTL/SHAREABLE
    +
    +
+ +On AXP (and possibly also using DEC C on VAX) the corresponding commands are +
    +
  1. Using the shareable TIFF library. +
    +$ LINK MY_PROGRAM,DISK:[TIFF.LIBTIFF]TIFF/OPTIONS
    +
    +
  2. Using the TIFF object library. +
    +$ LINK MY_PROGRAM,DISK:[TIFF.LIBTIFF]TIFF/LIBRARY
    +
    +
+ +Method 1 uses the shortest link time and smallest .EXE +files, but it +requires that TIFFSHR is defined as above at link time and +at run time. +Using the compilation procedure above, the tools are linked in this way. + +

+Method 2 gives somewhat longer link time and larger .EXE +files, but does +not require TIFFSHR to be defined. This method is recommended if you +want to run your program on another machine, and for some reason don't +want to have the library on that machine. If you plan to have more than +one program (including the tools) on the machine, it is recommended that +you copy the library to the other machine and use method 1. + + + +


Building the Software on an Acorn RISC OS system

+ +The directory contrib/acorn contains support for compiling the library +under Acorn C/C++ under Acorn's RISC OS 3.10 or above. Subsequent pathnames +will use the Acorn format: The full-stop or period character is a pathname +delimeter, and the slash character is not interpreted; the reverse position +from Unix. Thus "libtiff/tif_acorn.c" becomes "libtiff.tif_acorn/c". + +

+This support was contributed by Peter Greenham. (peter@enlarion.demon.co.uk). + +

+

Installing LibTIFF:

+ +

+LIBTIFF uses several files which have names longer than the normal RISC OS +maximum of ten characters. This complicates matters. Maybe one day Acorn will +address the problem and implement long filenames properly. Until then this +gets messy, especially as I'm trying to do this with obeyfiles and not have +to include binaries in this distribution. + +

+First of all, ensure you have Truncate configured on (type *Configure +Truncate On) + +

+Although it is, of course, preferable to have long filenames, LIBTIFF can be +installed with short filenames, and it will compile and link without +problems. However, getting it there is more problematic. +contrib.acorn.install is an installation obeyfile which will create a normal +Acorn-style library from the source (ie: with c, h and o folders etc.), but +needs the distribution library to have been unpacked into a location which is +capable of supporting long filenames, even if only temporarily. + +

+My recommendation, until Acorn address this problem properly, is to use Jason +Tribbeck's LongFilenames, or any other +working system that gives you long filenames, like a nearby NFS server for +instance. + +

+If you are using Longfilenames, even if only temporarily to install LIBTIFF, +unpack the TAR into a RAMDisc which has been longfilenamed (ie: *addlongfs +ram) and then install from there to the hard disk. Unfortunately +Longfilenames seems a bit unhappy about copying a bunch of long-named files +across the same filing system, but is happy going between systems. You'll +need to create a ramdisk of about 2Mb. + +

+Now you can run the installation script I've supplied (in contrib.acorn), +which will automate the process of installing LIBTIFF as an Acorn-style +library. The syntax is as follows: + +

+install <source_dir> <dest_dir> + +

+Install will then create <dest_dir> and put the library in there. For +example, having used LongFilenames on the RAMDisk and unpacked the library +into there, you can then type: + +

+Obey RAM::RamDisc0.$.contrib.acorn.install RAM::RamDisc0.$ ADFS::4.$.LIBTIFF +

+ +It doesn't matter if the destination location can cope with long filenames or +not. The filenames will be truncated if necessary (*Configure Truncate On if +you get errors) and all will be well. + +

+

Compiling LibTIFF:

+ +

+Once the LibTIFF folder has been created and the files put inside, making the +library should be just a matter of running 'SetVars' to set the +appropriate system variables, then running 'Makefile'. + +

+OSLib + +

+OSLib +is a comprehensive API for RISC OS machines, written by Jonathan Coxhead of +Acorn Computers (although OSLib is not an official Acorn product). Using the +OSLib SWI veneers produces code which is more compact and more efficient than +code written using _kernel_swi or _swi. The Acorn port of LibTIFF can take +advantage of this if present. Edit the Makefile and go to the Static +dependencies section. The first entry is: + +

+# Static dependencies:
+@.o.tif_acorn:   @.c.tif_acorn
+	cc $(ccflags) -o @.o.tif_acorn @.c.tif_acorn 
+
+

+Change the cc line to: +

+	cc $(ccflags) -DINCLUDE_OSLIB -o @.o.tif_acorn @.c.tif_acorn 
+
+

+Remember, however, that OSLib is only recommended for efficiency's +sake. It is not required. + + + +


Building the Software on Other Systems

+ +This section contains information that might be useful +if you are working on a non-UNIX system that is not directly supported. +All library-related files described below are located in the libtiff +directory. + +

+The library requires two files that are generated on-the-fly. +The file tif_fax3sm.c has the state tables for the +Group 3 and Group 4 decoders. +This file is generated by the mkg3states program +on a UNIX system; for example, + +

    
    +cd libtiff
    +cc -o mkg3states mkg3states.c
    +rm -f tif_fax3sm.c
    +./mkg3states -c const tif_fax3sm.c
    +
+ +The -c option can be used to control whether or not the +resutling tables are generated with a const declaration. +The -s option can be used to specify a C storage class +for the table declarations. +The -b option can be used to force data values to be +explicitly bracketed with ``{}'' (apparently needed for some +MS-Windows compilers); otherwise the structures are emitted in +as compact a format as possible. +Consult the source code for this program if you have questions. + +

+The second file required to build the library, version.h, +contains the version +information returned by the TIFFGetVersion routine. +This file is built on most systems using the +mkversion program and the contents of the +VERSION and tiff.alpha files; for example, + +

    +cd libtiff
    +cc -o mkversion mkversion.c
    +rm -f version.h
    +./mkversion -v ../VERSION -a ../dist/tiff.alpha version.h
    +
+ +

+Otherwise, when building the library on a non-UNIX system be sure to +consult the files tiffcomp.h and tiffconf.h. +The former contains system compatibility definitions while the latter +is provided so that the software configuration can be controlled +on systems that do not support the make facility for building +the software. + +

+Systems without a 32-bit compiler may not be able to handle some +of the codecs in the library; especially the Group 3 and 4 decoder. +If you encounter problems try disabling support for a particular +codec; consult the documentation. + +

+Programs in the tools directory are written to assume an ANSI C +compilation environment. +There may be a few POSIX'isms as well. +The code in the port directory is provided to emulate routines +that may be missing on some systems. +On UNIX systems the configure script automatically figures +out which routines are not present on a system and enables the use +of the equivalent emulation routines from the port directory. +It may be necessary to manually do this work on a non-UNIX system. + + +


Checking out the Software

+ +

+Assuming you have working versions of tiffgt and tiffsv, +you can just +use them to view any of the sample images available for testing +(see the section on obtaining the test images). +Otherwise, you can do a cursory check of the library with +the tiffcp and tiffcmp programs. For example, + +

    +tiffcp -lzw cramps.tif x.tif
    +tiffcmp cramps.tif x.tif
    +
+ +

+(tiffcmp should be silent if the files compare correctly). + + + +


Table of Contents

+ +The following files makup the core library: + +
+libtiff/tiff.h			TIFF spec definitions
+libtiff/tiffcomp.h		non-UNIX OS-compatibility definitions
+libtiff/tiffconf.h		non-UNIX configuration definitions
+libtiff/tiffio.h		public TIFF library definitions
+libtiff/tiffiop.h		private TIFF library definitions
+libtiff/t4.h			CCITT Group 3/4 code tables+definitions
+libtiff/tif_dir.h		private defs for TIFF directory handling
+libtiff/tif_fax3.h		CCITT Group 3/4-related definitions
+libtiff/tif_predict.h		private defs for Predictor tag support
+libtiff/uvcode.h		LogL/LogLuv codec-specific definitions
+libtiff/version.h		version string (generated by Makefile)
+
+libtiff/tif_acorn.c		Acorn-related OS support
+libtiff/tif_apple.c		Apple-related OS support
+libtiff/tif_atari.c		Atari-related OS support
+libtiff/tif_aux.c		auxilary directory-related functions
+libtiff/tif_close.c		close an open TIFF file
+libtiff/tif_codec.c		configuration table of builtin codecs
+libtiff/tif_compress.c		compression scheme support
+libtiff/tif_dir.c		directory tag interface code
+libtiff/tif_dirinfo.c		directory known tag support code
+libtiff/tif_dirread.c		directory reading code
+libtiff/tif_dirwrite.c		directory writing code
+libtiff/tif_dumpmode.c		"no" compression codec
+libtiff/tif_error.c		library error handler
+libtiff/tif_fax3.c		CCITT Group 3 and 4 codec
+libtiff/tif_fax3sm.c		G3/G4 state tables (generated by mkg3states)
+libtiff/tif_flush.c		i/o and directory state flushing
+libtiff/tif_getimage.c		TIFFRGBAImage support
+libtiff/tif_jpeg.c		JPEG codec (interface to the IJG distribution)
+libtiff/tif_luv.c		SGI LogL/LogLuv codec
+libtiff/tif_lzw.c		LZW codec
+libtiff/tif_msdos.c		MSDOS-related OS support
+libtiff/tif_next.c		NeXT 2-bit scheme codec (decoding only)
+libtiff/tif_open.c		open and simply query code
+libtiff/tif_packbits.c		Packbits codec
+libtiff/tif_pixarlog.c		Pixar codec
+libtiff/tif_predict.c		Predictor tag support
+libtiff/tif_print.c		directory printing support
+libtiff/tif_read.c		image data reading support
+libtiff/tif_strip.c		some strip-related code
+libtiff/tif_swab.c		byte and bit swapping support
+libtiff/tif_thunder.c		Thunderscan codec (decoding only)
+libtiff/tif_tile.c		some tile-related code
+libtiff/tif_unix.c		UNIX-related OS support
+libtiff/tif_version.c		library version support
+libtiff/tif_vms.c		VMS-related OS support
+libtiff/tif_warning.c		library warning handler
+libtiff/tif_win3.c		Windows-3.1-related OS support
+libtiff/tif_win32.c		Windows-3.2-related OS support
+libtiff/tif_write.c		image data writing support
+libtiff/tif_zip.c		Deflate codec
+
+libtiff/mkg3states.c		program to generate G3/G4 decoder state tables
+libtiff/mkspans.c		program to generate black-white span tables
+libtiff/mkversion.c		program to generate libtiff/version.h.
+
+ +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/contrib.html b/html/contrib.html new file mode 100644 index 00000000..a5bc58a3 --- /dev/null +++ b/html/contrib.html @@ -0,0 +1,159 @@ + + + +Contributed TIFF Software + + + +

+ +Contributed TIFF Software +

+ + +

+The contrib directory has contributed software that +uses the TIFF library or which is associated with the library +(typically glue and guidance for ports to non-UNIX platforms, or tools that +aren't directly TIFF related). + +
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+contrib/vms + +scripts and files from Karsten Spang for building + the library and tools under VMS +
+contrib/dbs + +various tools from Dan & Chris Sears, including a simple X-based viewer +
+contrib/ras + +two programs by Patrick Naughton for converting + between Sun rasterfile format and TIFF (these + require libpixrect.a, as opposed to the one in + tools that doesn't) +
+contrib/mac-mpw + +scripts and files from Niles Ritter for building + the library and tools under Macintosh/MPW C. +
+contrib/acorn + +scripts and files from Peter Greenham for building + the library and tools on an Acorn RISC OS system. +
+contrib/win32 + +scripts and files from Scott Wagner for building + the library under Windows NT and Windows 95. +
+contrib/dosdjgpp + +scripts and files from Alexander Lehmann for building + the library under MSDOS with the DJGPP v2 compiler. +
+contrib/tags + +scripts and files from Niles Ritter for adding private + tag support at runtime, without changing libtiff. +
+contrib/mfs + +code from Mike Johnson to read+write images in memory +without modifying the library +
+contrib/pds + +various routines from Conrad Poelman; a TIFF image iterator and + code to support ``private sub-directories'' +
+contrib/iptcutil + + +A utility by Bill Radcliffe to +convert an extracted IPTC Newsphoto caption from a binary blob to +ASCII text, and vice versa. IPTC binary blobs can be extracted from +images via the ImageMagick convert(1) +utility. + + +
+ +

+Don't send me mail asking about this stuff; I frequently know +absolutely nothing about it. Send questions +and/or bug reports directly to the authors. + + + +

+


+ +Last updated: $Date: 1999-07-27 21:50:27 $ + + + diff --git a/html/document.html b/html/document.html new file mode 100644 index 00000000..c63d3ca3 --- /dev/null +++ b/html/document.html @@ -0,0 +1,52 @@ + + + +TIFF Documentation + + + +

+ +TIFF Documentation +

+ +

+A copy of the 6.0 specification is available by public ftp at + +

+ +This is a PostScript version of the final 6.0 specification compressed +with the standard UNIX compress(1) program. +An uncompressed PostScript file is also available as TIFF6.ps in +the same directory. + +
+ +

+Adobe (nee Aldus) provides the 6.0 spec online in +Acrobat format (PDF); this can be found at + +

+ +TIFF Technical Notes can be retrieved from + + + +

+


+ +
+ +Mike Welles / mike@onshore.com. +Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/images.html b/html/images.html new file mode 100644 index 00000000..62b83041 --- /dev/null +++ b/html/images.html @@ -0,0 +1,39 @@ + + + +TIFF Test Images + + + +

+ +TIFF Test Images +

+ +

+Test images are available for most formats supported by the library. +Most of the images included in the test kit are also part of this +documentation (albeit in TIFF rather than GIF or JFIF). +The images are kept in a separate archive that should be located in +the same directory as this software. + +
+ +

+The latest archive of test images is located at +ftp://ftp.sgi.com/graphics/tiff/v3.0pics.tar.Z. + +

+There are two other good sources for TIFF test images: +the contributed software contrib/dbs includes several +programs that generate test images suitable for debugging, and +the tiffcp program can be used to generate a variety +of images with different storage characteristics. + +

+


+ +Last updated: $Date: 1999-07-27 21:50:27 $ + + + diff --git a/html/images/back.gif b/html/images/back.gif new file mode 100644 index 0000000000000000000000000000000000000000..11d0c35f4671f6086d992776c7521efef880e914 GIT binary patch literal 1000 zcmW-gKWN_t5XGNTq-cg9Ar)LgJSnMm(7^~n2LtBPLMf#uf;dDfV&p`m?p24{>frr~ zj#5jgaPU*9dUG`BP%BCY|D16tMMZQGTts+&^S$x7d+*@$Zf*VXhnF|zFo)l;R{|*D zKmY|az_BX=6}TV-C1?T1QBkPE6`?3aD>&|pLmlo2M>*QTQB(pN@IVAA&;gE4QqY1I zqELk{aI}|(HoOsyYIK9+O+qN)L=Z(Z!M#IGU@LiP$p$s=4DY6KAgm0ih7bV{dodS`T2XLqs_Okpb1nZYb( zGszsnGUQ^2z(9KdJ1`t@4P+n`p$c6X!Vi zYS4obtY8N@CP0c>^kNjN*hP-9kft`h8O>^TlVer}|G{cd9R!Bip*__7dmpg(3)ue+ z{`%?P<&PIWfBm*QCRcvQ_jk_D-re{7^Y*1LpE$5IdH%T<-kiQMyY%RPYggxYE=-Tt zV;7%2x^lkeUpuY0-@1Qh@!;j%bCZqx7M34)dH2SJUv~~~UpzCre*NaL6DN*MCi`aY z+V|G&fhqGaP`COGkWCYXVa~7tKVMnqX(W`jHzDUmFbH=%iJrQ z1LZ>t>ys`0;;DyTI`ZK5rN3{kZ~ne^_SDw3(?5Rt!L|36Hm>f@T>tabcaN-07FRdF R{^R?Pp8n+BUk)u`<$t1E;KBd^ literal 0 HcmV?d00001 diff --git a/html/images/bali.jpg b/html/images/bali.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1f5c146dd5ed78b6f0f227773214b78aecd57c81 GIT binary patch literal 26152 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 MpU}Qe9|!pSAJtj5%m4rY literal 0 HcmV?d00001 diff --git a/html/images/cover.jpg b/html/images/cover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8698cfb064736d498501de801fcd727b8952bd3c GIT binary patch literal 20189 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 literal 0 HcmV?d00001 diff --git a/html/images/dave.gif b/html/images/dave.gif new file mode 100644 index 0000000000000000000000000000000000000000..c36d447772a630e171de8e8fad5e7ce2cc1cf98e GIT binary patch literal 8220 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 HK=1zmtoJ7? literal 0 HcmV?d00001 diff --git a/html/images/info.gif b/html/images/info.gif new file mode 100644 index 0000000000000000000000000000000000000000..783d63153ec9268f7e17f3887a844c2a8741e3ce GIT binary patch literal 131 zcmZ?wbhEHbRA5kG_{hMJl$4Z^knsQie+GtUia%Kx8Gt|sM1bTOnL=9nSDt>$zj%&F zZ+E`$&d0nJj~sf{IOnFX>g(4$lFfWt?d~d{b^7T#FEq2Z&FGFqlI!W hi^EyjTy^5q9{u&HSRnS|fz|5kZ?^q@tHHov4FK7YGsge` literal 0 HcmV?d00001 diff --git a/html/images/jello.jpg b/html/images/jello.jpg new file mode 100644 index 0000000000000000000000000000000000000000..df99e663ef3b35d30b6031435bb3e3d6d57faeab GIT binary patch literal 13744 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 literal 0 HcmV?d00001 diff --git a/html/images/jim.gif b/html/images/jim.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a18a031fac72973e00b7fee7055774cbc6a43f9 GIT binary patch literal 14493 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≥o<2q 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 literal 0 HcmV?d00001 diff --git a/html/images/note.gif b/html/images/note.gif new file mode 100644 index 0000000000000000000000000000000000000000..7177d68a19ff69dadbbc166fe9386fdff45bcba4 GIT binary patch literal 264 zcmZ?wbh9u|RA5kG_{`4$1Px%^0Hzv%yao_BaNxjyp!k1=|6mG816e?z0~7@6RA69c z*(-3;b2Y2P?X%hj3LGU%#OEbPGM&?0HAPI?FIHNU$EI7SR^tZCh6lDalJnP{c%tfj zYU;+Dhqo43+$}k^sVh!<)yD3_4u_+kJ(tRQYGGX{n6Z1R^~WzaRIPXx*%w87O4c#g zi#Ihf)b)0VS9LKk_w^f2oH1qAG{df$ZF3rD%yV7H;j(yTyQSokmE3bG*LAIyTfZvb ynPYR+R%wYnAx)@c*dw)d`I6$C1UaA#rTRf8E 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 literal 0 HcmV?d00001 diff --git a/html/images/quad.jpg b/html/images/quad.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4b7df170beb5da5b9be8b5d00efe19c9d9f4435c GIT binary patch literal 23904 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 literal 0 HcmV?d00001 diff --git a/html/images/ring.gif b/html/images/ring.gif new file mode 100644 index 0000000000000000000000000000000000000000..2a614f4929e4cfbc14e656f576e320e1ee601e45 GIT binary patch literal 4275 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 RUk}#s0~@9TMlvwK^#83(8SVf8 literal 0 HcmV?d00001 diff --git a/html/images/smallliz.jpg b/html/images/smallliz.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8eb827f8ad56ff57e9324c5e2fcd07947aca0c49 GIT binary patch literal 16463 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 V9|w>FnA)HW1c~_VCk_EP{x9Pz_gw%0 literal 0 HcmV?d00001 diff --git a/html/images/warning.gif b/html/images/warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..f51eb4b1a7b7f392b183e183ec2d93aab7d3090b GIT binary patch literal 287 zcmV+)0pR{eNk%w1VJHA70P+9;=jZ2cZf?H5zWe|H{{R300000000000A^8LW00062 zEC2ui04M+`000Bz2)f+N_DFSAmXsV{#*oJWIwOJ|OFii%yF#J7% z?sfYSfViQp$QksMJQ>pGyg`|rs_Ys=7BN zq^_xzt7fP!iL*hxLbX0Icy*7uWw0Hxn;d(N$#=tpw8qOJ%GF%XpIE=t$i1gmKjY-( l=I2P+= + + +TIFF Software + + + +

+ +TIFF Software +
+

+ +Latest Release:
v3.5
+Latest Software: v3.5
+Master FTP Site: ftp.onshore.com , directory pub/libtiff
+Home Page: + http://www.libtiff.org
+FAQ Page: forthcoming
+ + +
+
+
+
+ +

+This software provides support for the Tag Image File Format (TIFF), +a widely used format for storing image data. The latest version of +the TIFF specification is available on-line +in several different formats, +as are a number of TIFF Technical Notes (TTN's). + +

+Included in this software distribution is a library, libtiff, for +reading and writing TIFF, a small collection of tools for doing simple +manipulations of TIFF images on UNIX systems, +and documentation on the library and +tools. A small assortment of TIFF-related software for UNIX +that has been contributed by others is also included. + +

+The library, along with associated tool programs, should handle most of +your needs for reading and writing TIFF images on 32- and 64-bit +machines. This software can also be used on older 16-bit systems +though it may require some effort and you may need to leave out some of +the compression support. + +

The software was orginally authored and maintained by moved on to bigger +and better things , and the code was orphaned for a while. Mike Welles is the person responsible for +version 3.5., and is the current maintainer of the +distribution. + +

+ +The following sections are included in this documentation: + +

+ +A PostScript version of this documentation is available on-line at +the master FTP site listed above. + +

+


+ +$Id: index.html,v 1.1 1999-07-27 21:50:27 mike Exp $ + + + + diff --git a/html/internals.html b/html/internals.html new file mode 100644 index 00000000..f4430232 --- /dev/null +++ b/html/internals.html @@ -0,0 +1,655 @@ + + + +Modifying The TIFF Library + + + +

+ +Modifying The TIFF Library +

+ + +

+This chapter provides information about the internal structure of +the library, how to control the configuration when building it, and +how to add new support to the library. +The following sections are found in this chapter: + +

+ + +


Library Configuration

+ +Information on compiling the library is given +elsewhere in this documentation. +This section describes the low-level mechanisms used to control +the optional parts of the library that are configured at build +time. Control is based on +a collection of C defines that are specified either on the compiler +command line or in a configuration file such as port.h +(as generated by the configure script for UNIX systems) +or tiffconf.h. + +

+Configuration defines are split into three areas: +

    +
  • those that control which compression schemes are + configured as part of the builtin codecs, +
  • those that control support for groups of tags that + are considered optional, and +
  • those that control operating system or machine-specific support. +
+ +

+If the define COMPRESSION_SUPPORT is not defined +then a default set of compression schemes is automatically +configured: +

    +
  • CCITT Group 3 and 4 algorithms (compression codes 2, 3, 4, and 32771), +
  • the Macintosh PackBits algorithm (compression 32773), +
  • a Lempel-Ziv & Welch (LZW) algorithm (compression 5), +
  • a 4-bit run-length encoding scheme from ThunderScan (compression 32809), +
  • a 2-bit encoding scheme used by NeXT (compression 32766), and +
  • two experimental schemes intended for images with high dynamic range +(compression 34676 and 34677). +
+ +To override this behaviour define COMPRESSION_SUPPORT +and then one or more additional defines to enable configuration of +the appropriate codecs (see the table below); e.g. + +
    +#define	COMPRESSION_SUPPORT
    +#define	CCITT_SUPPORT
    +#define	PACKBITS_SUPPORT
    +
+ +Several other compression schemes are configured separately from +the default set because they depend on ancillary software +packages that are not distributed with libtiff. + +

+Support for JPEG compression is controlled by JPEG_SUPPORT. +The JPEG codec that comes with libtiff is designed for +use with release 5 or later of the Independent JPEG Group's freely +available software distribution. +This software can be retrieved from the directory +ftp.uu.net:/graphics/jpeg/. + + +

+NOTE: +Enabling JPEG support automatically enables support for +the TIFF 6.0 colorimetry and YCbCr-related tags. + +

+Experimental support for the deflate algorithm is controlled by +DEFLATE_SUPPORT. +The deflate codec that comes with libtiff is designed +for use with version 0.99 or later of the freely available +libz library written by Jean-loup Gailly and Mark Adler. +The data format used by this library is described +in the files +zlib-3.1.doc, +and +deflate-1.1.doc, +available in the directory +ftp.uu.net:/pub/archiving/zip/doc. +The library can be retried from the directory +ftp.uu.net:/pub/archiving/zip/zlib/ +(or try quest.jpl.nasa.gov:/beta/zlib/). + +

+NOTE: +The deflate algorithm is experimental. Do not expect +to exchange files using this compression scheme; +it is included only because the similar, and more common, +LZW algorithm is claimed to be governed by licensing restrictions. + + +

+By default tiffconf.h defines +COLORIMETRY_SUPPORT, +YCBCR_SUPPORT, +and +CMYK_SUPPORT. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DefineDescription
CCITT_SUPPORTCCITT Group 3 and 4 algorithms (compression codes 2, 3, 4, + and 32771)
PACKBITS_SUPPORTMacintosh PackBits algorithm (compression 32773)
LZW_SUPPORTLempel-Ziv & Welch (LZW) algorithm (compression 5)
THUNDER_SUPPORT4-bit +run-length encoding scheme from ThunderScan (compression 32809)
NEXT_SUPPORT2-bit encoding scheme used by NeXT (compression 32766)
OJPEG_SUPPORTobsolete JPEG scheme defined in the 6.0 spec (compression 6)
JPEG_SUPPORTcurrent JPEG scheme defined in TTN2 (compression 7)
ZIP_SUPPORTexperimental Deflate scheme (compression 32946)
PIXARLOG_SUPPORTPixar's compression scheme for high-resolution color images (compression 32909)
SGILOG_SUPPORTSGI's compression scheme for high-resolution color images (compression 34676 and 34677)
COLORIMETRY_SUPPORTsupport for the TIFF 6.0 colorimetry tags
YCBCR_SUPPORTsupport for the TIFF 6.0 YCbCr-related tags
CMYK_SUPPORTsupport for the TIFF 6.0 CMYK-related tags
ICC_SUPPORTsupport for the ICC Profile tag; see +The ICC Profile Format Specification, +Annex B.3 "Embedding ICC Profiles in TIFF Files"; +available at +http://www.color.org +
+ + +


General Portability Comments

+ +This software is developed on Silicon Graphics UNIX +systems (big-endian, MIPS CPU, 32-bit ints, +IEEE floating point). +The configure shell script generates the appropriate +include files and make files for UNIX systems. +Makefiles exist for non-UNIX platforms that the +code runs on -- this work has mostly been done by other people. + +

+In general, the code is guaranteed to work only on SGI machines. +In practice it is highly portable to any 32-bit or 64-bit system and much +work has been done to insure portability to 16-bit systems. +If you encounter portability problems please return fixes so +that future distributions can be improved. + +

+The software is written to assume an ANSI C compilation environment. +If your compiler does not support ANSI function prototypes, const, +and <stdarg.h> then you will have to make modifications to the +software. In the past I have tried to support compilers without const +and systems without <stdarg.h>, but I am +no longer interested in these +antiquated environments. With the general availability of +the freely available GCC compiler, I +see no reason to incorporate modifications to the software for these +purposes. + +

+An effort has been made to isolate as many of the +operating system-dependencies +as possible in two files: tiffcomp.h and +libtiff/tif_<os>.c. The latter file contains +operating system-specific routines to do I/O and I/O-related operations. +The UNIX (tif_unix.c), +Macintosh (tif_apple.c), +and VMS (tif_vms.c) +code has had the most use; +the MS/DOS support (tif_msdos.c) assumes +some level of UNIX system call emulation (i.e. +open, +read, +write, +fstat, +malloc, +free). + +

+Native CPU byte order is determined on the fly by +the library and does not need to be specified. +The HOST_FILLORDER and HOST_BIGENDIAN +definitions are not currently used, but may be employed by +codecs for optimization purposes. + +

+The following defines control general portability: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
BSDTYPESDefine this if your system does NOT define the + usual BSD typedefs: u_char, + u_short, u_int, u_long.
HAVE_IEEEFPDefine this as 0 or 1 according to the floating point + format suported by the machine. If your machine does + not support IEEE floating point then you will need to + add support to tif_machdep.c to convert between the + native format and IEEE format.
HAVE_MMAPDefine this if there is mmap-style support for +mapping files into memory (used only to read data).
HOST_FILLORDERDefine the native CPU bit order: one of FILLORDER_MSB2LSB + or FILLORDER_LSB2MSB
HOST_BIGENDIANDefine the native CPU byte order: 1 if big-endian (Motorola) + or 0 if little-endian (Intel); this may be used + in codecs to optimize code
+ +

+On UNIX systems HAVE_MMAP is defined through the running of +the configure script; otherwise support for memory-mapped +files is disabled. +Note that tiffcomp.h defines HAVE_IEEEFP to be +1 (BSDTYPES is not defined). + + +


Types and Portability

+ +The software makes extensive use of C typedefs to promote portability. +Two sets of typedefs are used, one for communication with clients +of the library and one for internal data structures and parsing of the +TIFF format. There are interactions between these two to be careful +of, but for the most part you should be able to deal with portability +purely by fiddling with the following machine-dependent typedefs: + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint88-bit unsigned integertiff.h
int88-bit signed integertiff.h
uint1616-bit unsigned integertiff.h
int1616-bit signed integertiff.h
uint3232-bit unsigned integertiff.h
int3232-bit signed integertiff.h
dblparam_tpromoted type for floatstiffcomp.h
+ +

+(to clarify dblparam_t, it is the type that float parameters are +promoted to when passed by value in a function call.) + +

+The following typedefs are used throughout the library and interfaces +to refer to certain objects whose size is dependent on the TIFF image +structure: + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
typedef unsigned int ttag_t; directory tag
typedef uint16 tdir_t; directory index
typedef uint16 tsample_t; sample number
typedef uint32 tstrip_t; strip number
typedef uint32 ttile_t; tile number
typedef int32 tsize_t; i/o size in bytes
typedef void* tdata_t; image data ref
typedef void* thandle_t; client data handle
typedef int32 toff_t; file offset (should be off_t)
typedef unsigned char* tidata_t; internal image data
+ +

+Note that tstrip_t, ttile_t, and tsize_t +are constrained to be +no more than 32-bit quantities by 32-bit fields they are stored +in in the TIFF image. Likewise tsample_t is limited by the 16-bit +field used to store the SamplesPerPixel tag. tdir_t +constrains +the maximum number of IFDs that may appear in an image and may +be an arbitrary size (without penalty). ttag_t must be either +int, unsigned int, pointer, or double +because the library uses a varargs +interface and ANSI C restricts the type of the parameter before an +ellipsis to be a promoted type. toff_t is defined as +int32 because +TIFF file offsets are (unsigned) 32-bit quantities. A signed +value is used because some interfaces return -1 on error (sigh). +Finally, note that tidata_t is used internally to the library to +manipulate internal data. User-specified data references are +passed as opaque handles and only cast at the lowest layers where +their type is presumed. + + +


General Comments

+ +The library is designed to hide as much of the details of TIFF from +applications as +possible. In particular, TIFF directories are read in their entirety +into an internal format. Only the tags known by the library are +available to a user and certain tag data may be maintained that a user +does not care about (e.g. transfer function tables). + +


Adding New Tags

+ +To add support for a new directory tag you have three options. If your +tag is specific to a compression algorithm, see below. If you have a lot +of tags you may want to try using Niles Ritter's runtime tag-extension +scheme in the "contrib/tags" directory, which makes the changes +orthogonal to the main libtiff code. Otherwise use +the following guidelines to add support to the ``core library''. + +
    +
  1. Define the tag in tiff.h. +
  2. Add a field to the directory structure in tif_dir.h + and define a FIELD_* bit (also update the definition of + FIELD_CODEC to reflect your addition). +
  3. Add an entry in the TIFFFieldInfo array defined at the top of + tif_dirinfo.c. + Note that you must keep this array sorted by tag + number and that the widest variant entry for a tag should come + first (e.g. LONG before SHORT). +
  4. Add entries in _TIFFVSetField() and _TIFFVGetField() + for the new tag. +
  5. (optional) If the value associated with the tag is not a scalar value + (e.g. the array for TransferFunction) and requires + special processing, + then add the appropriate code to TIFFReadDirectory() and + TIFFWriteDirectory(). You're best off finding a similar tag and + cribbing code. +
  6. Add support to TIFFPrintDirectory() in tif_print.c + to print the tag's value. +
+ +

+If you want to maintain portability, beware of making assumptions +about data types. Use the typedefs (uint16, etc. when dealing with +data on disk and t*_t when stuff is in memory) and be careful about +passing items through printf or similar vararg interfaces. + +


Adding New Builtin Codecs

+ +To add builtin support for a new compression algorithm, you can either +use the "tag-extension" trick to override the handling of the +TIFF Compression tag (see Adding New Tags, above), +or do the following to add support directly to the core library: + +
    +
  1. Define the tag value in tiff.h. +
  2. Edit the file tif_codec.c to add an entry to the + _TIFFBuiltinCODECS array (see how other algorithms are handled). +
  3. Add the appropriate function prototype declaration to + tiffiop.h (close to the bottom). +
  4. Create a file with the compression scheme code, by convention files + are named tif_*.c (except perhaps on some systems where the + tif_ prefix pushes some filenames over 14 chars. +
  5. Edit Makefile.in (and any other Makefiles) + to include the new source file. +
+ +

+A codec, say foo, can have many different entry points: + +

+TIFFInitfoo(tif, scheme)/* initialize scheme and setup entry points in tif */
+fooSetupDecode(tif)	/* called once per IFD after tags has been frozen */
+fooPreDecode(tif, sample)/* called once per strip/tile, after data is read,
+			    but before the first row is decoded */
+fooDecode*(tif, bp, cc, sample)/* decode cc bytes of data into the buffer */
+    fooDecodeRow(...)	/* called to decode a single scanline */
+    fooDecodeStrip(...)	/* called to decode an entire strip */
+    fooDecodeTile(...)	/* called to decode an entire tile */
+fooSetupEncode(tif)	/* called once per IFD after tags has been frozen */
+fooPreEncode(tif, sample)/* called once per strip/tile, before the first row in
+			    a strip/tile is encoded */
+fooEncode*(tif, bp, cc, sample)/* encode cc bytes of user data (bp) */
+    fooEncodeRow(...)	/* called to decode a single scanline */
+    fooEncodeStrip(...)	/* called to decode an entire strip */
+    fooEncodeTile(...)	/* called to decode an entire tile */
+fooPostEncode(tif)	/* called once per strip/tile, just before data is written */
+fooSeek(tif, row)	/* seek forwards row scanlines from the beginning
+			   of a strip (row will always be >0 and <rows/strip */
+fooCleanup(tif)		/* called when compression scheme is replaced by user */
+
+ +

+Note that the encoding and decoding variants are only needed when +a compression algorithm is dependent on the structure of the data. +For example, Group 3 2D encoding and decoding maintains a reference +scanline. The sample parameter identifies which sample is to be +encoded or decoded if the image is organized with PlanarConfig=2 +(separate planes). This is important for algorithms such as JPEG. +If PlanarConfig=1 (interleaved), then sample will always be 0. + + +


Adding New Codec-private Tags

+ +To add tags that are meaningful only when a particular compression +algorithm is used follow these steps: + +
    +
  1. Define the tag in tiff.h. +
  2. Allocate storage for the tag values in the private state block of + the codec. +
  3. Insure the state block is created when the codec is initialized. +
  4. At TIFFInitfoo time override the method pointers in the + TIFF structure + for getting, setting and printing tag values. For example, +
    +    sp->vgetparent = tif->tif_vgetfield;
    +    tif->tif_vgetfield = fooVGetField;	/* hook for codec tags */
    +    sp->vsetparent = tif->tif_vsetfield;
    +    tif->tif_vsetfield = fooVSetField;	/* hook for codec tags */
    +    tif->tif_printdir = fooPrintDir;	/* hook for codec tags */
    +
    + (Actually you may decide not to override the + tif_printdir method, but rather just specify it). +
  5. Create a private TIFFFieldInfo array for your tags and + merge them into the core tags at initialization time using + _TIFFMergeFieldInfo; e.g. +
    +    _TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo));
    +
    + (where N is a macro used liberaly throughout the distributed code). +
  6. Fill in the get and set routines. Be sure to call the parent method + for tags that you are not handled directly. Also be sure to set the + FIELD_* bits for tags that are to be written to the file. Note that + you can create ``pseudo-tags'' by defining tags that are processed + exclusively in the get/set routines and never written to file (see + the handling of TIFFTAG_FAXMODE in tif_fax3.c + for an example of this). +
  7. Fill in the print routine, if appropriate. +
+ +Note that space has been allocated in the FIELD_* bit space for +codec-private tags. Define your bits as FIELD_CODEC+<offset> to +keep them away from the core tags. If you need more tags than there +is room for, just increase FIELD_SETLONGS at the top of +tiffiop.h. + + +


Other Comments

+ +The library handles most I/O buffering. There are two data buffers +when decoding data: a raw data buffer that holds all the data in a +strip, and a user-supplied scanline buffer that compression schemes +place decoded data into. When encoding data the data in the +user-supplied scanline buffer is encoded into the raw data buffer (from +where it is written). Decoding routines should never have to explicitly +read data -- a full strip/tile's worth of raw data is read and scanlines +never cross strip boundaries. Encoding routines must be cognizant of +the raw data buffer size and call TIFFFlushData1() when necessary. +Note that any pending data is automatically flushed when a new strip/tile is +started, so there's no need do that in the tif_postencode routine (if +one exists). Bit order is automatically handled by the library when +a raw strip or tile is filled. If the decoded samples are interpreted +by the decoding routine before they are passed back to the user, then +the decoding logic must handle byte-swapping by overriding the +tif_postdecode +routine (set it to TIFFNoPostDecode) and doing the required work +internally. For an example of doing this look at the horizontal +differencing code in the routines in tif_predict.c. + +

+The variables tif_rawcc, tif_rawdata, and +tif_rawcp in a TIFF structure +are associated with the raw data buffer. tif_rawcc must be non-zero +for the library to automatically flush data. The variable +tif_scanlinesize is the size a user's scanline buffer should be. The +variable tif_tilesize is the size of a tile for tiled images. This +should not normally be used by compression routines, except where it +relates to the compression algorithm. That is, the cc parameter to the +tif_decode* and tif_encode* +routines should be used in terminating +decompression/compression. This ensures these routines can be used, +for example, to decode/encode entire strips of data. + +

+In general, if you have a new compression algorithm to add, work from +the code for an existing routine. In particular, +tif_dumpmode.c +has the trivial code for the "nil" compression scheme, +tif_packbits.c is a +simple byte-oriented scheme that has to watch out for buffer +boundaries, and tif_lzw.c has the LZW scheme that has the most +complexity -- it tracks the buffer boundary at a bit level. +Of course, using a private compression scheme (or private tags) limits +the portability of your TIFF files. + +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/intro.html b/html/intro.html new file mode 100644 index 00000000..f3cdb5f2 --- /dev/null +++ b/html/intro.html @@ -0,0 +1,80 @@ + + + +Introduction to the TIFF Documentation + + + +

+ +Introduction to the TIFF Documentation +

+ + +
+This documentation is best viewed using a graphical browser that supports +the latest HTML directives for formatting documents. In particular, +this document was authored +for viewing with version 1.1 or newer of the +Netscape Navigator. +
+ +
+ +

+The following definitions are used throughout this documentation. +They are consistent with the terminology used in the TIFF 6.0 specification. + +

+
Sample +
The unit of information stored in an image; often called a + channel elsewhere. Sample values are numbers, usually unsigned + integers, but possibly in some other format if the SampleFormat + tag is specified in a TIFF +
Pixel +
A collection of one or more samples that go together. +
Row +
An Nx1 rectangular collection of pixels. +
Tile +
An NxM rectangular organization of data (or pixels). +
Strip +
A tile whose width is the full image width. +
Compression +
A scheme by which pixel or sample data are stored in + an encoded form, specifically with the intent of reducing the + storage cost. +
Codec +
Software that implements the decoding and encoding algorithms + of a compression scheme. + + +

+In order to better understand how TIFF works (and consequently this +software) it is important to recognize the distinction between the +physical organization of image data as it is stored in a TIFF and how +the data is interpreted and manipulated as pixels in an image. TIFF +supports a wide variety of storage and data compression schemes that +can be used to optimize retrieval time and/or minimize storage space. +These on-disk formats are independent of the image characteristics; it +is the responsibility of the TIFF reader to process the on-disk storage +into an in-memory format suitable for an application. Furthermore, it +is the responsibility of the application to properly interpret the +visual characteristics of the image data. TIFF defines a framework for +specifying the on-disk storage format and image characteristics with +few restrictions. This permits significant complexity that can be +daunting. Good applications that handle TIFF work by handling as wide +a range of storage formats as possible, while constraining the +acceptable image characteristics to those that make sense for the +application. + + +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/libtiff.html b/html/libtiff.html new file mode 100644 index 00000000..56ecc52f --- /dev/null +++ b/html/libtiff.html @@ -0,0 +1,730 @@ + + + +Using The TIFF Library + + + +

+ +Using The TIFF Library +

+ +

+libtiff is a set of C functions (a library) that support +the manipulation of TIFF image files. +The library requires an ANSI C compilation environment for building +and presumes an ANSI C environment for use. + +

+libtiff +provides interfaces to image data at several layers of abstraction (and cost). +At the highest level image data can be read into an 8-bit/sample, +ABGR pixel raster format without regard for the underlying data organization, +colorspace, or compression scheme. Below this high-level interface +the library provides scanline-, strip-, and tile-oriented interfaces that +return data decompressed but otherwise untransformed. These interfaces +require that the application first identify the organization of stored +data and select either a strip-based or tile-based API for manipulating +data. At the lowest level the library +provides access to the raw uncompressed strips or tiles, +returning the data exactly as it appears in the file. + +

+The material presented in this chapter is a basic introduction +to the capabilities of the library; it is not an attempt to describe +everything a developer needs to know about the library or about TIFF. +Detailed information on the interfaces to the library are given in +the +UNIX manual pages that accompany this software. + +

+The following sections are found in this chapter: + +

+ + +


How to tell which version you have

+ +The software version can be found by looking at the file named +VERSION +that is located at the top of the source tree; the precise alpha number +is given in the file dist/tiff.alpha. +If you have need to refer to this +specific software, you should identify it as: + +
+    TIFF <version> <alpha>
+
+ +where <version> is whatever you get from +"cat VERSION" and <alpha> is +what you get from "cat dist/tiff.alpha". + +

+Within an application that uses libtiff the TIFFGetVersion +routine will return a pointer to a string that contains software version +information. +The library include file <tiffio.h> contains a C pre-processor +define TIFFLIB_VERSION that can be used to check library +version compatiblity at compile time. + +


Library Datatypes

+ +libtiff defines a portable programming interface through the +use of a set of C type definitions. +These definitions, defined in in the files tiff.h and +tiffio.h, +isolate the libtiff API from the characteristics +of the underlying machine. +To insure portable code and correct operation, applications that use +libtiff should use the typedefs and follow the function +prototypes for the library API. + +


Memory Management

+ +libtiff uses a machine-specific set of routines for managing +dynamically allocated memory. +_TIFFmalloc, _TIFFrealloc, and _TIFFfree +mimic the normal ANSI C routines. +Any dynamically allocated memory that is to be passed into the library +should be allocated using these interfaces in order to insure pointer +compatibility on machines with a segmented architecture. +(On 32-bit UNIX systems these routines just call the normal malloc, +realloc, and free routines in the C library.) + +

+To deal with segmented pointer issues libtiff also provides +_TIFFmemcpy, _TIFFmemset, and _TIFFmemmove +routines that mimic the equivalent ANSI C routines, but that are +intended for use with memory allocated through _TIFFmalloc +and _TIFFrealloc. + +


Error Handling

+ +libtiff handles most errors by returning an invalid/erroneous +value when returning from a function call. +Various diagnostic messages may also be generated by the library. +All error messages are directed to a single global error handler +routine that can be specified with a call to TIFFSetErrorHandler. +Likewise warning messages are directed to a single handler routine +that can be specified with a call to TIFFSetWarningHandler + +


Basic File Handling

+ +The library is modeled after the normal UNIX stdio library. +For example, to read from an existing TIFF image the +file must first be opened: + +
    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("foo.tif", "r"); + ... do stuff ... + TIFFClose(tif); +} +
+ +The handle returned by TIFFOpen is opaque, that is +the application is not permitted to know about its contents. +All subsequent library calls for this file must pass the handle +as an argument. + +

+To create or overwrite a TIFF image the file is also opened, but with +a "w" argument: + +

    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("foo.tif", "w"); + ... do stuff ... + TIFFClose(tif); +} +
+ +If the file already exists it is first truncated to zero length. + +

+ +Note that unlike the stdio library TIFF image files may not be +opened for both reading and writing; +there is no support for altering the contents of a TIFF file. + + +

+libtiff buffers much information associated with writing a +valid TIFF image. Consequently, when writing a TIFF image it is necessary +to always call TIFFClose or TIFFFlush to flush any +buffered information to a file. Note that if you call TIFFClose +you do not need to call TIFFFlush. + +


TIFF Directories

+ +TIFF supports the storage of multiple images in a single file. +Each image has an associated data structure termed a directory +that houses all the information about the format and content of the +image data. +Images in a file are usually related but they do not need to be; it +is perfectly alright to store a color image together with a black and +white image. +Note however that while images may be related their directories are +not. +That is, each directory stands on its own; their is no need to read +an unrelated directory in order to properly interpret the contents +of an image. + +

+libtiff provides several routines for reading and writing +directories. In normal use there is no need to explicitly +read or write a directory: the library automatically reads the first +directory in a file when opened for reading, and directory information +to be written is automatically accumulated and written when writing +(assuming TIFFClose or TIFFFlush are called). + +

+For a file open for reading the TIFFSetDirectory routine can +be used to select an arbitrary directory; directories are referenced by +number with the numbering starting at 0. Otherwise the +TIFFReadDirectory and TIFFWriteDirectory routines can +be used for sequential access to directories. +For example, to count the number of directories in a file the following +code might be used: + +

    +#include "tiffio.h" +main(int argc, char* argv[]) +{ + TIFF* tif = TIFFOpen(argv[1], "r"); + if (tif) { + int dircount = 0; + do { + dircount++; + } while (TIFFReadDirectory(tif)); + printf("%d directories in %s\n", dircount, argv[1]); + TIFFClose(tif); + } + exit(0); +} +
+ +

+Finally, note that there are several routines for querying the +directory status of an open file: +TIFFCurrentDirectory returns the index of the current +directory and +TIFFLastDirectory returns an indication of whether the +current directory is the last directory in a file. +There is also a routine, TIFFPrintDirectory, that can +be called to print a formatted description of the contents of +the current directory; consult the manual page for complete details. + +


TIFF Tags

+ +Image-related information such as the image width and height, number +of samples, orientation, colorimetric information, etc. +are stored in each image +directory in fields or tags. +Tags are identified by a number that is usually a value registered +with the Aldus (now Adobe) Corporation. +Beware however that some vendors write +TIFF images with tags that are unregistered; in this case interpreting +their contents is usually a waste of time. + +

+libtiff reads the contents of a directory all at once +and converts the on-disk information to an appropriate in-memory +form. While the TIFF specification permits an arbitrary set of +tags to be defined and used in a file, the library only understands +a limited set of tags. +Any unknown tags that are encountered in a file are ignored. +There is a mechanism to extend the set of tags the library handles +without modifying the library itself; +this is described elsewhere. + +

+libtiff provides two interfaces for getting and setting tag +values: TIFFGetField and TIFFSetField. +These routines use a variable argument list-style interface to pass +parameters of different type through a single function interface. +The get interface takes one or more pointers to memory locations +where the tag values are to be returned and also returns one or +zero according to whether the requested tag is defined in the directory. +The set interface takes the tag values either by-reference or +by-value. +The TIFF specification defines +default values for some tags. +To get the value of a tag, or its default value if it is undefined, +the TIFFGetFieldDefaulted interface may be used. + +

+The manual pages for the tag get and set routines specifiy the exact data types +and calling conventions required for each tag supported by the library. + +


TIFF Compression Schemes

+ +libtiff includes support for a wide variety of +data compression schemes. +In normal operation a compression scheme is automatically used when +the TIFF Compression tag is set, either by opening a file +for reading, or by setting the tag when writing. + +

+Compression schemes are implemented by software modules termed codecs +that implement decoder and encoder routines that hook into the +core library i/o support. +Codecs other than those bundled with the library can be registered +for use with the TIFFRegisterCODEC routine. +This interface can also be used to override the core-library +implementation for a compression scheme. + +


Byte Order

+ +The TIFF specification says, and has always said, that +a correct TIFF +reader must handle images in big-endian and little-endian byte order. +libtiff conforms in this respect. +Consequently there is no means to force a specific +byte order for the data written to a TIFF image file (data is +written in the native order of the host CPU unless appending to +an existing file, in which case it is written in the byte order +specified in the file). + + +


Data Placement

+ +The TIFF specification requires that all information except an +8-byte header can be placed anywhere in a file. +In particular, it is perfectly legitimate for directory information +to be written after the image data itself. +Consequently TIFF is inherently not suitable for passing through a +stream-oriented mechanism such as UNIX pipes. +Software that require that data be organized in a file in a particular +order (e.g. directory information before image data) does not +correctly support TIFF. +libtiff provides no mechanism for controlling the placement +of data in a file; image data is typically written before directory +information. + +


TIFFRGBAImage Support

+ +libtiff provides a high-level interface for reading image +data from a TIFF file. This interface handles the details of +data organization and format for a wide variety of TIFF files; +at least the large majority of those files that one would normally +encounter. Image data is, by default, returned as ABGR +pixels packed into 32-bit words (8 bits per sample). Rectangular +rasters can be read or data can be intercepted at an intermediate +level and packed into memory in a format more suitable to the +application. +The library handles all the details of the format of data stored on +disk and, in most cases, if any colorspace conversions are required: +bilevel to RGB, greyscale to RGB, CMYK to RGB, YCbCr to RGB, 16-bit +samples to 8-bit samples, associated/unassociated alpha, etc. + +

+There are two ways to read image data using this interface. If +all the data is to be stored in memory and manipulated at once, +then the routine TIFFReadRGBAImage can be used: + +

    +#include "tiffio.h" +main(int argc, char* argv[]) +{ + TIFF* tif = TIFFOpen(argv[1], "r"); + if (tif) { + uint32 w, h; + size_t npixels; + uint32* raster; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + npixels = w * h; + raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); + if (raster != NULL) { + if (TIFFReadRGBAImage(tif, w, h, raster, 0)) { + ...process raster data... + } + _TIFFfree(raster); + } + TIFFClose(tif); + } + exit(0); +} +
+ +Note above that _TIFFmalloc is used to allocate memory for +the raster passed to TIFFReadRGBAImage; this is important +to insure the ``appropriate type of memory'' is passed on machines +with segmented architectures. + +

+Alternatively, TIFFReadRGBAImage can be replaced with a +more low-level interface that permits an application to have more +control over this reading procedure. The equivalent to the above +is: + +

    +#include "tiffio.h" +main(int argc, char* argv[]) +{ + TIFF* tif = TIFFOpen(argv[1], "r"); + if (tif) { + TIFFRGBAImage img; + char emsg[1024]; + + if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) { + size_t npixels; + uint32* raster; + + npixels = img.width * img.height; + raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); + if (raster != NULL) { + if (TIFFRGBAImageGet(&img, raster, img.width, img.width)) { + ...process raster data... + } + _TIFFfree(raster); + } + TIFFRGBAImageEnd(&img); + } else + TIFFError(argv[1], emsg); + TIFFClose(tif); + } + exit(0); +} +
+ +However this usage does not take advantage of the more fine-grained +control that's possible. That is, by using this interface it is +possible to: + +
    +
  • repeatedly fetch (and manipulate) an image without opening + and closing the file +
  • interpose a method for packing raster pixel data according to + application-specific needs (or write the data at all) +
  • interpose methods that handle TIFF formats that are not already + handled by the core library +
+ +The first item means that, for example, image viewers that want to +handle multiple files can cache decoding information in order to +speedup the work required to display a TIFF image. + +

+The second item is the main reason for this interface. By interposing +a ``put method'' (the routine that is called to pack pixel data in +the raster) it is possible share the core logic that understands how +to deal with TIFF while packing the resultant pixels in a format that +is optimized for the application. This alternate format might be very +different than the 8-bit per sample ABGR format the library writes by +default. For example, if the application is going to display the image +on an 8-bit colormap display the put routine might take the data and +convert it on-the-fly to the best colormap indices for display. + +

+The last item permits an application to extend the library +without modifying the core code. +By overriding the code provided an application might add support +for some esoteric flavor of TIFF that it needs, or it might +substitute a packing routine that is able to do optimizations +using application/environment-specific information. + +

+The TIFF image viewer found in tools/sgigt.c is an example +of an application that makes use of the TIFFRGBAImage +support. + +


Scanline-based Image I/O

+ +The simplest interface provided by libtiff is a +scanline-oriented interface that can be used to read TIFF +images that have their image data organized in strips +(trying to use this interface to read data written in tiles +will produce errors.) +A scanline is a one pixel high row of image data whose width +is the width of the image. +Data is returned packed if the image data is stored with samples +packed together, or as arrays of separate samples if the data +is stored with samples separated. +The major limitation of the scanline-oriented interface, other +than the need to first identify an existing file as having a +suitable organization, is that random access to individual +scanlines can only be provided when data is not stored in a +compressed format, or when the number of rows in a strip +of image data is set to one (RowsPerStrip is one). + +

+Two routines are provided for scanline-based i/o: +TIFFReadScanline +and +TIFFWriteScanline. +For example, to read the contents of a file that +is assumed to be organized in strips, the following might be used: + +

    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("myfile.tif", "r"); + if (tif) { + uint32 imagelength; + tdata_t buf; + uint32 row; + + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); + buf = _TIFFmalloc(TIFFScanlineSize(tif)); + for (row = 0; row < imagelength; row++) + TIFFReadScanline(tif, buf, row); + _TIFFfree(buf); + TIFFClose(tif); + } +} +
+ +TIFFScanlineSize returns the number of bytes in +a decoded scanline, as returned by TIFFReadScanline. +Note however that if the file had been create with samples +written in separate planes, then the above code would only +read data that contained the first sample of each pixel; +to handle either case one might use the following instead: + +
    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("myfile.tif", "r"); + if (tif) { + uint32 imagelength; + tdata_t buf; + uint32 row; + + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); + TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config); + buf = _TIFFmalloc(TIFFScanlineSize(tif)); + if (config == PLANARCONFIG_CONTIG) { + for (row = 0; row < imagelength; row++) + TIFFReadScanline(tif, buf, row); + } else if (config == PLANARCONFIG_SEPARATE) { + uint16 s, nsamples; + + TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &nsamples); + for (s = 0; s < nsamples; s++) + for (row = 0; row < imagelength; row++) + TIFFReadScanline(tif, buf, row, s); + } + _TIFFfree(buf); + TIFFClose(tif); + } +} +
+ +Beware however that if the following code were used instead to +read data in the case PLANARCONFIG_SEPARATE, + +
    + for (row = 0; row < imagelength; row++) + for (s = 0; s < nsamples; s++) + TIFFReadScanline(tif, buf, row, s); +
+ +then problems would arise if RowsPerStrip was not one +because the order in which scanlines are requested would require +random access to data within strips (something that is not supported +by the library when strips are compressed). + +


Strip-oriented Image I/O

+ +The strip-oriented interfaces provided by the library provide +access to entire strips of data. Unlike the scanline-oriented +calls, data can be read or written compressed or uncompressed. +Accessing data at a strip (or tile) level is often desirable +because there are no complications with regard to random access +to data within strips. + +

+A simple example of reading an image by strips is: + +

    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("myfile.tif", "r"); + if (tif) { + tdata_t buf; + tstrip_t strip; + + buf = _TIFFmalloc(TIFFStripSize(tif)); + for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) + TIFFReadEncodedStrip(tif, strip, buf, (tsize_t) -1); + _TIFFfree(buf); + TIFFClose(tif); + } +} +
+ +Notice how a strip size of -1 is used; TIFFReadEncodedStrip +will calculate the appropriate size in this case. + +

+The above code reads strips in the order in which the +data is physically stored in the file. If multiple samples +are present and data is stored with PLANARCONFIG_SEPARATE +then all the strips of data holding the first sample will be +read, followed by strips for the second sample, etc. + +

+Finally, note that the last strip of data in an image may have fewer +rows in it than specified by the RowsPerStrip tag. A +reader should not assume that each decoded strip contains a full +set of rows in it. + +

+The following is an example of how to read raw strips of data from +a file: + +

    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("myfile.tif", "r"); + if (tif) { + tdata_t buf; + tstrip_t strip; + uint32* bc; + uint32 stripsize; + + TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc); + stripsize = bc[0]; + buf = _TIFFmalloc(stripsize); + for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { + if (bc[strip] > stripsize) { + buf = _TIFFrealloc(buf, bc[strip]); + stripsize = bc[strip]; + } + TIFFReadRawStrip(tif, strip, buf, bc[strip]); + } + _TIFFfree(buf); + TIFFClose(tif); + } +} +
+ +As above the strips are read in the order in which they are +physically stored in the file; this may be different from the +logical ordering expected by an application. + +


Tile-oriented Image I/O

+ +Tiles of data may be read and written in a manner similar to strips. +With this interface, an image is +broken up into a set of rectangular areas that may have dimensions +less than the image width and height. All the tiles +in an image have the same size, and the tile width and length must each +be a multiple of 16 pixels. Tiles are ordered left-to-right and +top-to-bottom in an image. As for scanlines, samples can be packed +contiguously or separately. When separated, all the tiles for a sample +are colocated in the file. That is, all the tiles for sample 0 appear +before the tiles for sample 1, etc. + +

+Tiles and strips may also be extended in a z dimension to form +volumes. Data volumes are organized as "slices". That is, all the +data for a slice is colocated. Volumes whose data is organized in +tiles can also have a tile depth so that data can be organized in +cubes. + +

+There are actually two interfaces for tiles. +One interface is similar to scanlines, to read a tiled image, +code of the following sort might be used: + +

    +main() +{ + TIFF* tif = TIFFOpen("myfile.tif", "r"); + if (tif) { + uint32 imageWidth, imageLength; + uint32 tileWidth, tileLength; + uint32 x, y; + tdata_t buf; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileLength); + buf = _TIFFmalloc(TIFFTileSize(tif)); + for (y = 0; y < imageLength; y += tileLength) + for (x = 0; x < imageWidth; x += tileWidth) + TIFFReadTile(tif, buf, x, y, 0); + _TIFFfree(buf); + TIFFClose(tif); + } +} +
+ +(once again, we assume samples are packed contiguously.) + +

+Alternatively a direct interface to the low-level data is provided +a la strips. Tiles can be read with +TIFFReadEncodedTile or +TIFFReadRawTile, +and written with +TIFFWriteEncodedTile or +TIFFWriteRawTile. +For example, to read all the tiles in an image: + +

    +#include "tiffio.h" +main() +{ + TIFF* tif = TIFFOpen("myfile.tif", "r"); + if (tif) { + tdata_t buf; + ttile_t tile; + + buf = _TIFFmalloc(TIFFTileSize(tif)); + for (tile = 0; tile < TIFFNumberOfTiles(tif); tile++) + TIFFReadEncodedTile(tif, tile, buf, (tsize_t) -1); + _TIFFfree(buf); + TIFFClose(tif); + } +} +
+ + + +


Other Stuff

+ +

+Some other stuff will almost certainly go here... + +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/misc.html b/html/misc.html new file mode 100644 index 00000000..b31b02e4 --- /dev/null +++ b/html/misc.html @@ -0,0 +1,95 @@ + + + +Acknowledgments and Other Issues + + + +

+ +Acknowledgments and Other Issues +

+ +

+Silicon Graphics has seen fit to allow me to give this work away. It +is free. There is no support or guarantee of any sort as to its +operations, correctness, or whatever. If you do anything useful with +all or parts of it you need to honor the copyright notices. I would +also be interested in knowing about it and, hopefully, be acknowledged. + +
+ + +

Acknowledgements

+ +The LZW algorithm is derived from the compress program (the proper +attribution is included in the source code). The Group 3 fax stuff +originated as code from Jef Poskanzer, but has since been rewritten +several times. The latest version uses an algorithm from Frank +Cringle -- consult libtiff/mkg3states.c and +libtiff/tif_fax3.h for further information. +The JPEG support was written by Tom Lane and is dependent on the +excellent work of Tom Lane and the Independent JPEG Group (IJG) +who distribute their work under friendly licensing similar to this +software. +Many other people have by now helped with bug fixes and code; a +few of the more persistent contributors have been: + +
+    Bjorn P. Brox		Dan McCoy
+    J.T. Conklin		Richard Minner
+    Frank D. Cringle		Richard Mlynarik
+    Soren Pingel Dalsgaard	Niles Ritter
+    Steve Johnson		Karsten Spang
+    Tom Lane
+
+ +(my apology to anyone that was inadvertently not listed.) + +

Warning

+ +It appears that Unisys is actively pursuing copyright control on the +LZW compression algorithm. In particular, users of the LZW compression +within the TIFF framework. For this reason the TIFF 6.0 spec states +that LZW compression is not recommended. It is unclear at this time +what compression algorithm will be used in place of it. I have no idea +what this means to you or to this library. I make no warranty or +guarantees with regard to the LZW support in this library. + + +

Use and Copyright

+ +

+Copyright (c) 1988-1997 Sam Leffler
+Copyright (c) 1991-1997 Silicon Graphics, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and 
+its documentation for any purpose is hereby granted without fee, provided
+that (i) the above copyright notices and this permission notice appear in
+all copies of the software and related documentation, and (ii) the names of
+Sam Leffler and Silicon Graphics may not be used in any advertising or
+publicity relating to the software without the specific, prior written
+permission of Sam Leffler and Silicon Graphics.
+
+THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+
+IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+OF THIS SOFTWARE.
+
+ +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/support.html b/html/support.html new file mode 100644 index 00000000..ce2012e5 --- /dev/null +++ b/html/support.html @@ -0,0 +1,684 @@ + + + +TIFF 6.0 Specification Coverage + + + +

+ +TIFF 6.0 Specification Coverage +

+ + +

+The library is capable of dealing with images that are written to +follow the 5.0 or 6.0 TIFF spec. There is also considerable support +for some of the more esoteric portions of the 6.0 TIFF spec. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Core requirements + +Both "MM" and "II" byte orders are handled. +Both packed and separated planar configuration of samples. +Any number of samples per pixel (memory permitting). +Any image width and height (memory permitting). +Multiple subfiles can be read and written. +Editing is not supported in that related subfiles (e.g. +a reduced resolution version of an image) are not automatically +updated. +

+Tags handled: +ExtraSamples, +ImageWidth, +ImageLength, +NewSubfileType, +ResolutionUnit. +Rowsperstrip, +StripOffsets, +StripByteCounts, +XResolution, +YResolution, +

Tiled ImagesTileWidth, + TileLength, + TileOffsets, + TileByteCounts +
Image Colorimetry InformationWhitePoint, + PrimaryChromaticities, + TransferFunction, + ReferenceBlackWhite +
Class B for bilevel imagesSamplesPerPixel = 1
+ BitsPerSample = 1
+ Compression = 1 (none), 2 (CCITT 1D), or 32773 (PackBits)
+ PhotometricInterpretation = 0 (Min-is-White), 1 (Min-is-Black)
+
Class G for grayscale imagesSamplesPerPixel = 1
+ BitsPerSample = 4, 8
+ Compression = 1 (none) 5 (LZW)
+ PhotometricInterpretation = 0 (Min-is-White), 1 (Min-is-Black)
+
Class P for palette color imagesSamplesPerPixel = 1
+ BitsPerSample = 1-8
+ Compression = 1 (none) 5 (LZW)
+ PhotometricInterpretation = 3 (Palette RGB)
+ ColorMap +
Class R for RGB full color imagesSamplesPerPixel = 3
+ BitsPerSample = <8,8,8>
+ PlanarConfiguration = 1, 2
+ Compression = 1 (none) 5 (LZW)
+ PhotometricInterpretation = 2 (RGB)
+
Class F for facsimile(Class B tags plus...)
+ Compression = 3 (CCITT Group 3), 4 (CCITT Group 4)
+ FillOrder = 1 (MSB), 2 (LSB)
+ Group3Options = 1 (2d encoding), 4 (zero fill), 5 (2d+fill)
+ ImageWidth = 1728, 2048, 2482
+ NewSubFileType = 2
+ ResolutionUnit = 2 (Inch), 3 (Centimeter)
+ PageNumber, + XResolution, + YResolution, + Software, + BadFaxLines, + CleanFaxData, + ConsecutiveBadFaxLines, + DateTime, + DocumentName, + ImageDescription, + Orientation +
Class S for separated imagesSamplesPerPixel = 4
+ PlanarConfiguration = 1, 2
+ Compression = 1 (none), 5 (LZW)
+ PhotometricInterpretation = 5 (Separated)
+ InkSet = 1 (CMYK)
+ DotRange, + InkNames, + DotRange, + TargetPrinter +
Class Y for YCbCr imagesSamplesPerPixel = 3
+ BitsPerSample = <8,8,8>
+ PlanarConfiguration = 1, 2
+ Compression = 1 (none), 5 (LZW), 7 (JPEG)
+ PhotometricInterpretation = 6 (YCbCr)
+ YCbCrCoefficients, + YCbCrSubsampling, + YCbCrPositioning
+ (colorimetry info from Appendix H; see above) +
Class "JPEG" for JPEG images (per TTN2)PhotometricInterpretation = 1 (grayscale), 2 (RGB), 5 (CMYK), 6 (YCbCr)
+ (Class Y tags if YCbCr)
+ (Class S tags if CMYK)
+ Compression = 7 (JPEG)
+
+ +

+In addition, the library supports some optional compression algorithms +that are, in some cases, of dubious value. + +

+    Compression = 32766	NeXT 2-bit encoding
+    Compression = 32809	ThunderScan 4-bit encoding
+    Compression = 32909	Pixar companded 11-bit ZIP encoding
+    Compression = 32946	PKZIP-style Deflate encoding (experimental)
+    Compression = 34676	SGI 32-bit Log Luminance encoding (experimental)
+    Compression = 34677	SGI 24-bit Log Luminance encoding (experimental)
+
+ +Note that there is no support for the JPEG-related tags defined +in the 6.0 specification; the JPEG support is based on the post-6.0 +proposal given in TIFF Technical Note #2. + +

+ + + + + +
+ +For more information on the experimental Log Luminance encoding +consult the materials available at +http://www.sgi.com/Technology/pixformat. + +
+ +

+The following table shows the tags that are recognized +and how they are used by the library. If no use is indicated, +then the library +reads and writes the tag, but does not use it internally. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tag Name Value R/W Library's Use (Comments)
NewSubFileType254R/Wnone (called SubFileType in <tiff.h>)
SubFileType255R/Wnone (called OSubFileType in <tiff.h>)
ImageWidth256R/Wlots
ImageLength257R/Wlots
BitsPerSample258R/Wlots
Compression259R/Wto select appropriate codec
PhotometricInterpretation262R/Wlots
Thresholding263R/W 
CellWidth264 parsed but ignored
CellLength265 parsed but ignored
FillOrder266R/Wcontrol bit order
DocumentName269R/W 
ImageDescription270R/W 
Make271R/W 
Model272R/W 
StripOffsets273R/Wdata i/o
Orientation274R/W 
SamplesPerPixel277R/Wlots
RowsPerStrip278R/Wdata i/o
StripByteCounts279R/Wdata i/o
MinSampleValue280R/W 
MaxSampleValue281R/W 
XResolution282R/W 
YResolution283R/Wused by Group 3 2d encoder
PlanarConfiguration284R/Wdata i/o
PageName285R/W 
XPosition286R/W 
YPosition286R/W 
FreeOffsets288 parsed but ignored
FreeByteCounts289 parsed but ignored
GrayResponseUnit290 parsed but ignored
GrayResponseCurve291 parsed but ignored
Group3Options292R/Wused by Group 3 codec
Group4Options293R/W 
ResolutionUnit296R/Wused by Group 3 2d encoder
PageNumber297R/W 
ColorResponseUnit300 parsed but ignored
TransferFunction301R/W 
Software305R/W 
DateTime306R/W 
Artist315R/W 
HostComputer316R/W 
Predictor317R/Wused by LZW codec
WhitePoint318R/W 
PrimaryChromacities319R/W 
ColorMap320R/W 
TileWidth322R/Wdata i/o
TileLength323R/Wdata i/o
TileOffsets324R/Wdata i/o
TileByteCounts324R/Wdata i/o
BadFaxLines326R/W 
CleanFaxData327R/W 
ConsecutiveBadFaxLines328R/W 
SubIFD330R/Wsubimage descriptor support
InkSet332R/W 
InkNames333R/W 
DotRange336R/W 
TargetPrinter337R/W 
ExtraSamples338R/Wlots
SampleFormat339R/W 
SMinSampleValue340R/W 
SMaxSampleValue341R/W 
JPEGTables347R/Wused by JPEG codec
YCbCrCoefficients529R/Wused by TIFFReadRGBAImage support
YCbCrSubsampling530R/Wtile/strip size calculations
YCbCrPositioning531R/W 
ReferenceBlackWhite532R/W 
Matteing32995Rnone (obsoleted by ExtraSamples tag)
DataType32996Rnone (obsoleted by SampleFormat tag)
ImageDepth32997R/Wtile/strip calculations
TileDepth32998R/Wtile/strip calculations
StoNits37439R/W 
+ +

+The Matteing and DataType +tags have been obsoleted by the 6.0 +ExtraSamples and SampleFormat tags. +Consult the documentation on the +ExtraSamples tag and Associated Alpha for elaboration. Note however +that if you use Associated Alpha, you are expected to save data that is +pre-multipled by Alpha. If this means nothing to you, check out +Porter & Duff's paper in the '84 SIGGRAPH proceedings: "Compositing Digital +Images". + +

+The ImageDepth +tag is a non-standard, but registered tag that specifies +the Z-dimension of volumetric data. The combination of ImageWidth, +ImageLength, and ImageDepth, +defines a 3D volume of pixels that are +further specified by BitsPerSample and +SamplesPerPixel. The TileDepth +tag (also non-standard, but registered) can be used to specified a +subvolume "tiling" of a volume of data. + +

+The Colorimetry, and CMYK tags are additions that appear in TIFF 6.0. +Consult the TIFF 6.0 specification included in the doc directory +and online. + +

+The JPEG-related tag is specified in +TIFF Technical Note #2 which defines +a revised JPEG-in-TIFF scheme (revised over that appendix that was +part of the TIFF 6.0 specification). + + + +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/tools.html b/html/tools.html new file mode 100644 index 00000000..dea1b64c --- /dev/null +++ b/html/tools.html @@ -0,0 +1,178 @@ + + + +TIFF Tools Overview + + + +

+ +TIFF Tools Overview +

+ +

+This software distribution comes with a small collection of programs +for converting non-TIFF format images to TIFF and for manipulating +and interogating the contents of TIFF images. +Several of these tools are useful in their own right. +Many of them however are more intended to serve as programming +examples for using the TIFF library. + +

Device-dependent Programs

+ +There are two device-dependent programs that serve as simple examples +for writing programs to display and save TIFF images. + + +

+ + + + + + + + + + + + +
tiffgt    Display the contents of one or +more TIFF images on a Silicon Graphics system using +the Silicon Graphics IRIS GL. +The software makes extensive use of the TIFFRGBAImage +facilities described elsewhere.
tiffsvA program to save all or part of a screen dump on a Silicon +Graphics system. +As for tiffgt this code, while written to use the IRIS GL, +can be easily tailored to other devices.
+ +

Device-independent Programs

+ +The remaining programs should be device-independent: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
tiffinfoDisplay information about one or more TIFF files.
tiffdumpDisplay the verbatim contents of the TIFF directory in a + file (it's very useful for debugging bogus files that you may get from + someone that claims they support TIFF)
tiffcpCopy, concatenate, and convert TIFF images (e.g. + switching from Compression=5 to Compression=1)
tiff2psConvert TIFF images to PostScript
tiffcmpCompare the contents of two TIFF files (it does + not check all the directory information, but does check all the data)
tiff2bwA simple program to convert a color image to grayscale
ras2tiffA quick hack that converts Sun rasterfile format images to + TIFF -- it's less than complete
rgb2ycbcrConvert an RGB, grayscale, or bilevel TIFF image to a + YCbCr TIFF image; it's mainly provided for testing
gif2tiffA quick hack that converts GIF 87a format images to TIFF
ppm2tiffA quick hack that converts PPM format images to TIFF
fax2tiffConvert raw Group 3 or Group 4 facsimile data to TIFF
pal2rgbConvert a Palette-style image to a full color RGB image by + applying the colormap
tiffditherDither a b&w image into a bilevel image (suitable for + use in creating fax files)
tiffsplitCreate one or more single-image files from a (possibly) + multi-image file
fax2psConvert a Group 3- or Group 4- compressed TIFF to PostScript + that is significantly more compressed than is generated by tiff2ps + (unless tiff2ps writes PS Level II)
thumbnailCopy a bilevel TIFF to one that includes 8-bit greyscale + "thumbnail images" for each page; it is provided as an example of + how one might use the SubIFD tag + (and the library support for it)
tiffmedianA version of Paul Heckbert's median cut program + that reads an RGB TIFF image, and creates a TIFF palette file as a + result; it's useful for converting full-color RGB images to 8-bit + color for your friends that have cheapo 8-bit framebuffers.
sgi2tiffA program to convert SGI image files to TIFF. This + program is only useful on SGI machines as it uses -limage.
+ +

+Check out the manual pages for details about the above programs. + + +

+


+ +
+Sam Leffler / sam@engr.sgi.com. +Last updated: $Date: 1999-07-27 21:50:27 $ +
+ + + diff --git a/html/v3.4beta007.html b/html/v3.4beta007.html new file mode 100644 index 00000000..5a85eeb4 --- /dev/null +++ b/html/v3.4beta007.html @@ -0,0 +1,111 @@ + + + +Changes in TIFF v3.4beta007 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • bit order was corrected for Pentium systems +
  • a new define, HOST_BIGENDIAN, was added for code that + wants to statically use information about native cpu byte order +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • the G3/G4 decoder was replaced by a new one that is faster and + has smaller state tables +
  • Niles Ritter's client tag extension hooks were added +
  • a new routine TIFFCurrentDirOffset was added for + applications that want to find out the file offset of a TIFF directory +
  • the calculation of the number of strips in an image was corected + for images with certain esoteric configurations +
  • a potential memory leak (very unlikely) was plugged +
  • the TIFFReadRGBAImage support was completely rewritten + and new, more flexible support was added for reading images into + a fixed-format raster +
  • YCbCr to RGB conversion done in the TIFFReadRGBAImage support + was optimized +
  • a bug in JPEG support calculation of strip size was corrected +
  • the LZW decoder was changed to initialize the code table to zero + to lessen potential problems that arise when invalid data is decoded +
  • tiffcomp.h is now aware of OS/2 +
  • some function prototypes in tiffio.h and tiffiop.h + that contained parameter + names have been changed to avoid complaints from certain compilers +
+ +


+ +CHANGES IN THE PORTABILITY SUPPORT: + +
    +
  • Makefile.in has been corrected to use the parameters + chosen by the configure script +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • fax2ps has been rewritten and moved over from the user + contributed software +
  • an uninitialized variable in pal2rgb has been fixed +
  • ras2tiff now converts 24-bit RGB raster data so that + samples are written in the proper order +
  • tiff2ps has been updated to include fixes + and enhancements from Alberto Accomazzi +
  • tiffcp now has a -o option to select a directory + by file offset +
  • tiffinfo is now capable of displaying the raw undecoded + image data in a file +
  • tiffgt has been rewritten to use the new TIFFRGBAImage + support and to handle multiple files +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta016.html b/html/v3.4beta016.html new file mode 100644 index 00000000..db629eca --- /dev/null +++ b/html/v3.4beta016.html @@ -0,0 +1,121 @@ + + + +Changes in TIFF v3.4beta016 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • support was added for configuring the Deflate codec +
  • support was added for the HTML documentation +
  • codecs that are not configured for inclusion in the library + are no longer compiled +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • support was added for registering new codecs external to the library + and for overriding the codecs that are builtin to the library +
  • emulation support for the old DataType tag was improved +
  • suppport was added for the SMinSampleValue + and SMaxSampleValue tags +
  • the library no longer ignores TileWidth and TileLength + tags whose values are not a multiple of 16 (per the spec); this + permits old, improperly written, images to be read +
  • the support for the Predictor tag was placed in a reusable + module so that it can be shared by multiple codecs +
  • experimental compression support was added for the Deflate algorithm + (using the freely available zlib package) +
  • a new routine, TIFFWriteBufferSetup was added a la the + routine TIFFReadBufferSetup +
  • the DSO version of the library is now statically linked with the + JPEG and Deflate libraries; this means applications that link against + the DSO do not also need to link against these ancillary libraries +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • all the tools now use common code to process compress-oriented arguments +
  • tiffdump should now compile on a Macintosh with MPW +
+ +


+ +CHANGES IN THE MANUAL PAGES: + +
    +
  • everything was updated +
+ +


+ +CHANGES IN THE DOCUMENTATION: + +
    +
  • everything was updated +
+ +


+ +CHANGES IN CONTRIBUTED SOFTWARE: + +
    +
  • contrib/dbs/xtiff was made to compile +
  • contrib/mac-mpw is new support for compiling the software on + a Macintosh under MPW; consult the documentation + for details +
  • contrib/tags is information on how to use the tag extenion + facilities; consult + contrib/tags/README for details +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta018.html b/html/v3.4beta018.html new file mode 100644 index 00000000..22164e1c --- /dev/null +++ b/html/v3.4beta018.html @@ -0,0 +1,83 @@ + + + +Changes in TIFF v3.4beta018 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • configure now recognizes IRIX 6.x systems +
  • configure now uses ENVOPTS when searching for an ANSI + C compiler; this fixes a problem configuring the software under + HP/UX with the native C compiler +
  • configure now correctly recognizes memory-mapped files are supported + under AIX +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • make install now properly installs the include files +
  • some portability fixes from Bjorn Brox +
  • the G3/G4 codec now warns about decoded rows that are longer than + the image/tile width +
  • changes from Frank Cringle to make the library work with the + gcc-specific bounds checking software +
  • miscellaneous fixes to TIFFPrintDirectory +
  • bug fix to correct a problem where TIFFWriteRawStrip + could not be used to automatically grow an image's length +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • fixes from Frank Cringle to update fax2tiff +
  • portability fixes to tiff2bw and tiffcmp +
  • tiffdump now uses the byte swapping routines in the library +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta024.html b/html/v3.4beta024.html new file mode 100644 index 00000000..e8486a25 --- /dev/null +++ b/html/v3.4beta024.html @@ -0,0 +1,138 @@ + + + +Changes in TIFF v3.4beta024 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • It is now possible to setup the software to build only the + library; configure reconizes this is the intent when the + VERSION, tiff.alpha, and tif_version.c + files are in the local directory (i.e. ``.'') +
  • configure no longer tries to setup HTML materials +
  • include file directories needed in building the library are now + specified with a DIRS_LIBINC config parameter +
  • configure no longer checks for alternate compilers if CC + is set; if the specified compiler is not found or is not appropriate + the configuration procedure aborts +
  • the port.h file generated by configure is now used only by + the library and as such as have been moved to the libtiff + directory +
  • there is beginning support for building DSO's on systems other than IRIX +
  • configure now verifies the JPEG and zlib directory pathnames by + checking for well-known include files in these directories +
  • configure no longer creates the dist directory needed only + on SGI machines (for building SGI binary distributions) +
  • a bug was fixed whereby configure would incorrectly set + ENVOPTS when building the software with gcc under AIX +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • two new typedefs were added to tiff.h: int8 + and uint8 for signed and unsigned 8-bit quantities, + respectively; these are currently used only by + programs in the tools directory +
  • the BadFaxLines, CleanFaxData, and + ConsecutiveBadFaxLines tags are now supported with + Group 4 compression +
  • byte order is now correctly identified on 64-bit machines +
  • a bug was fixed in the PackBits decoder where input data would + appear short when a no-op run was present +
  • a bug was fixed in calculations with very wide strips +
  • TIFFWriteEncodedStrip and TIFFWriteRawStrip + were extended to support dynamically growing the number of + strips in an image (must set ImageLength prior to + making calls though) +
  • TIFFDefaultTileSize now rounds tile width and height + up to a multiple of 16 pixels, as required by the TIFF 6.0 specification +
  • the file version.h is now built by a new mkversion + program; this was done for portability to non-UNIX systems +
  • support was added for the Acorn RISC OS (from Peter Greenham) +
  • the builtin codec table is now made const when compiling + under VMS so that libtiff can be built as a shared library +
  • support for the PowerPC Mac (from Ruedi Boesch) +
  • support for Window NT/Window 95 (from Scott Wagner) +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • the tools no longer include port.h +
  • various portability fixes; mostly to eliminate implicit assumptions + about how long int32 data types are +
  • PostScript Level II additions to tiff2ps from Bjorn Brox +
  • sgi2tiff now handles RGBA images +
+ +


+ +CHANGES IN THE MANUAL PAGES: + +
    +
  • the documentation has been updated to reflect the current state of + the software +
  • some routines have been moved to different manual pages + to group like-routines together +
+ +


+ +CHANGES IN THE CONTRIBUTED SOFTWARE: + +
    +
  • support was added for the Acorn RISC OS (from Peter Greenham) +
  • support for Windows NT/Windows 95 contributed for a previous + version of this software was sort of incorporated (it's broken + right now) (from Scott Wagner) +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta028.html b/html/v3.4beta028.html new file mode 100644 index 00000000..ddf7fe30 --- /dev/null +++ b/html/v3.4beta028.html @@ -0,0 +1,145 @@ + + + +Changes in TIFF v3.4beta028 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • a -noninteractive flag was added to configure to + control whether or not it prints and prompts for configuration information +
  • various typos and fixes were made in configure for the the + library-only build support (this and other configure fixes from + Richard Mlynarik <mly@adoc.xerox.com>) +
  • bugs were fixed in the handling of pathnames supplied for external + packages; e.g. DIR_JPEG +
  • the handling of SETMAKE is now done properly +
  • the default prototype function declaration for pow was corrected +
  • a bug was fixed in libtiff/Makefile.in that caused installation + to fail on systems without DSO support +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • Acorn RISC O/S support that was accidentally left out of the + left out of the previous distribution is present (from Peter Greenham) +
  • complaints about unknown and/or unsupported codecs have been + delayed until they are invoked; this permits applications to open + images and look at tags even if the image data is compressed with + an unknown/unsupported compression scheme +
  • bugs in handling unknown tags have been corrected; applications + that use multiple codecs, each with codec-specific tags, no longer + generate confusing error messages +
  • a missing pseudo-tag definition in the CCITT G3 codec was fixed + (this problem caused core dumps in the tiffcp program) +
  • pseudo-tags are now treated specially; they are always considered + to be set (i.e. they do not use bits in the FIELD_* bit-vectors). +
  • the use of strip chopping can now be controlled on a per-file basis + through a mode parameter supplied when opening a file (``C'' to + enable strip chopping and ``c'' to disable) +
  • two bugs were fixed in the writing of opposite-endian byte-order + files +
  • support was added for three new fax-related tags registered to + SGI: FaxRecvParams, FaxRecvTime, and FaxSubAddress +
  • the bit order of image data read and written can now be controlled + on a per-file basis through a mode parameter supplied when opening + a file (``B'' to force MSB2LSB bit order, ``L'' for LSB2MSB bit + order, and ``H'' for the bit order of the native CPU) +
  • the byte order of image and tag data written to newly-created files + can now be controlled on a per-file basis through a mode parameter + supplied when openening a file (``b'' to force Big-Endian byte order + and ``l'' to force Little-Endian byte order) +
  • the use memory-mapped files for images opened read-only can now + be controlled on a per-file basis through a mode parameter supplied + when opening a file (``M'' to enable use of memory-mapped files + and ``m'' to disable use) +
  • the use of the WIN32 define in tiffiop.h has + been replaced by __WIN32__ +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • fax2ps now does a save and restore + around each page of PostScript; this fixes a problem with VM + overflow when printing a many-page document on some printers +
  • a bug in the handling of 3-channel images by ras2tiff + was fixed +
  • tiffcp has new options to control the byte order of + newly created files: -B for Big-Endian byte order, -L + for Little-Endian byte order; a -M option to disable the + use of memory-mapped files, and a -C option to disable the + use of strip chopping +
  • bugs were fixed in tiffcp's handling of codec-specific tags +
+ +


+ +CHANGES IN THE MANUAL PAGES: + +
    +
  • the TIFFOpen page has been updated to reflect the new + optional open mode parameters +
+ +


+ +CHANGES IN THE CONTRIBUTED SOFTWARE: + +
    +
  • contrib/win95 contains information and code from Philippe Tenenhaus + <100423.3705@compuserve.com> + about using the software under Windows 95 +
  • contrib/winnt contains information and code from Dave Dyer + <ddyer@triple-i.com> + about using the software under Windows NT +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta029.html b/html/v3.4beta029.html new file mode 100644 index 00000000..33d6c084 --- /dev/null +++ b/html/v3.4beta029.html @@ -0,0 +1,85 @@ + + + +Changes in TIFF v3.4beta029 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • configure now relativizes pathname references given in + -L options (as frequently specified when configuring + ancillary packages) +
  • problems related to configuring the software on Ultrix 4.4 have + been corrected +
  • the shell to use in Makefiles and scripts can now be set with the + SCRIPT_SH configuration parameter +
  • comments in config.site now correctly indicate how to setup the + use of ancillary packages +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • mods for building the software on a Mac using the + MetroWerks CodeWarrior compilers +
  • a bug in the CCITT T.4/T.6 decoder was fixed where the last codeword in + a strip/tile might not be decoded; this was seen only when decoding + multi-strip images +
  • a bug in the CCITT RLE codecs was fixed whereby the pseudo tags were not + being properly registered +
+ +


+ +CHANGES IN THE CONTRIBUTED SOFTWARE: + +
    +
  • contrib/mac-cw contains information and code from Niles Ritter + <ndr@tazboy.jpl.nasa.gov> + about building the software with the MetroWerks CodeWarrior compilers + on Macintosh systems +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta031.html b/html/v3.4beta031.html new file mode 100644 index 00000000..346147f0 --- /dev/null +++ b/html/v3.4beta031.html @@ -0,0 +1,93 @@ + + + +Changes in TIFF v3.4beta031 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • configure now captures significantly more information + in the config.log file and provides more information when + it is unable to setup a configuration +
  • support was added for building shared libraries on more systems: + AIX, HPUX, Solaris, and Linux. +
  • a new configuration parameter LIBCOPTS was added for + passing arguments to the C compiler to use when building only + the library; this is part of the enhanced support for building + shared libraries +
  • include files for optional packages that reside in /usr/include + are now handled correctly +
  • build trees may now be configured using either relative or absolute + pathnames to the source distribution +
  • several new configuration parameters were added, mainly for building + shared libraries: DIST_MAJOR, DIST_MINOR, + DIST_ALPHA, and DSOSUF_VERSION +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • the Deflate support has been revised: it requires version 0.99 of + the zlib software distribution, the output format has changed and + is incompatible with previous versions of this library (each + strip now includes a header read and written by the zlib library) +
  • the codec name printed by the TIFFPrintDirectory routine is now + taken from the codec table instead of from a builtin table; this means + that application-defined codecs are handled correctly +
  • a new symbol was added that contains the library version number; + this can be used to do a compile-time compatibility check of the + library version +
+ +


+ +CHANGES IN THE MANUAL PAGES: + +
    +
  • the creation and installation of manual pages was redone; it now + implements the documented ``configuration scheme'' +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta032.html b/html/v3.4beta032.html new file mode 100644 index 00000000..719a332a --- /dev/null +++ b/html/v3.4beta032.html @@ -0,0 +1,89 @@ + + + +Changes in TIFF v3.4beta032 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • various fixups and subtle improvements to configure + from Richard Mlynarik +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • a new codec from Pixar designed for high-resolution color images; + note that this codec is not configured by default +
  • a bug fix for reading tags with a single FLOAT value +
  • change to the TIFFGetField calling convention: + a tag that has a single value of + type DOUBLE is now retrieved by passing a + ``double*'' instead of a + ``double**'' (this change makes the handling of tags with + DOUBLE values identical to the handling of tags with + FLOAT values) +
  • fix to VMS support for the handling of floating point values +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • tiffdump now handles tags with FLOAT and DOUBLE + values +
+ +


+ +CHANGES IN THE CONTRIBUTED SOFTWARE: + +
    +
  • updates to the Acorn OS support from Peter Greenham +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta033.html b/html/v3.4beta033.html new file mode 100644 index 00000000..f33ff057 --- /dev/null +++ b/html/v3.4beta033.html @@ -0,0 +1,81 @@ + + + +Changes in TIFF v3.4beta033 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • support was added for building the library as a DSO under OSF/1 +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • fixes to the Pixar codec +
  • portability mods for VMS +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • fixes to gif2tiff and ppm2tiff for building under MS/DOS +
  • portability mods to fax2ps and ycbcr for VMS +
+ +


+ +CHANGES IN THE CONTRIBUTED SOFTWARE: + +
    +
  • a new package from Alexander Lehmann + for building the library and tools under MS/DOS with DJGPP v2 +
  • updated VMS support from Karsten Spang +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta034.html b/html/v3.4beta034.html new file mode 100644 index 00000000..06e22e94 --- /dev/null +++ b/html/v3.4beta034.html @@ -0,0 +1,67 @@ + + + +Changes in TIFF v3.4beta034 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • support was added for building the library as a DSO under NetBSD +
  • a bug was fixed in the DSO support for Linux +
  • the handling of version strings has changed slightly to simplify parsing +
  • a new parameter, TIFFLIBREF, was added to control how the + library is referenced when linking programs in the tools directory +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • DSO creation under Solaris now forces the DSO name with a -h option +
  • the interface to the mkversion program was changed + to eliminate the need to parse files +
  • a bug was fixed in the EOL-detection logic of the T.4/T.6 decoder +
  • ANSI IT8 TIFF/IT tag definitions were added to tiff.h +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta035.html b/html/v3.4beta035.html new file mode 100644 index 00000000..6e1758eb --- /dev/null +++ b/html/v3.4beta035.html @@ -0,0 +1,62 @@ + + + +Changes in TIFF v3.4beta035 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • support was added installing the HTML documentation +
  • support was added for building the library as a DSO under FreeBSD +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • the interface to the mkversion program was restored to + the form used prior to v3.4beta034 +
  • several portability problems for 16-bit systems were fixed +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.4beta036.html b/html/v3.4beta036.html new file mode 100644 index 00000000..0ccaaa95 --- /dev/null +++ b/html/v3.4beta036.html @@ -0,0 +1,116 @@ + + + +Changes in TIFF v3.4beta036 + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • support was added for building the library as a DSO under HP-UX with + the native C compiler +
  • tools are now built with explicit pathnames for the DSO under IRIX, + Solaris, and Linux +
  • DSO configuration support for Linux was changed to require that + libc.so only be readable (not executable) +
+ +


+ +CHANGES IN LIBTIFF: + +
    +
  • support was add for ICC: NumberOfInks, and ICCProfile +
  • a memory leak caused by doing TIFFSetDirectory(0) was fixed +
  • a bug was fixed whereby certain multi-directory files were not + properly handled when accessed by mapping the data into memory +
  • the strip chopping support is now always compiled + into the library with the default usage controlled by a + STRIPCHOP_DEFAULT configuration parameter +
  • the strip chopping support no longer chops tiled images +
  • all static strings are now const--for shared libraries +
  • the logic for estimating the strip size of images without + a StripByteCounts tag was improved by handling + PlanarContig images differently from PlanarSeparate +
  • a bug was fixed in the G3 codec when converting the Y resolution + of data specified in metric units +
  • a bug was fixed in the G3/G4 decoder for data where lines terminate + with a v0 code +
  • the TIFFRGBAImage support was changed to scale 16-bit colormap + entries more conservatively to avoid problems with applications + that do not generate fully saturated pixel values +
  • the LZW decoder was changed to use a more conservative scheme when + bounds checking the hash table array; this avoids pitfalls with + systems that load objects into memory in unusual locations +
  • a bug was fixed in TIFFPrintDirectory's handling of the + InkNames tag +
  • TIFFPrintDirectory now understands NumberOfInks + and ICC-related tags +
  • the routines for reading image data now provide more useful information + when a read error is encountered +
  • support was added for compiling with Microsoft Visual C++ 4.0 +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • a bug was fixed in pal2rgb's colormap handling +
  • tiff2ps now includes John Wehle's changes for maintaining + the aspect ratio + of images when scaling and for honoring the deadzone on a page when + generating PostScript Level II +
  • tiff2ps does a better job guarding against the mishandling + of greyscale images +
  • tiff2ps now correctly converts X- and Y-resolution values + specified in metric units +
  • tiffdump has a new -m option to control the maximum + number of indirect + data values printed for a tag (by default 24) +
  • tiffdump understands several new tags +
  • tiffdump now shows any terminating null in ASCII strings +
  • tiffinfo now suppresses strip chopping when interpreting an image; + a new -z option has been added to enable strip chopping +
+ + TIFF home page.
+ +
+ +
+Sam Leffler / sam@engr.sgi.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/v3.5.html b/html/v3.5.html new file mode 100644 index 00000000..80428118 --- /dev/null +++ b/html/v3.5.html @@ -0,0 +1,76 @@ + + + +Changes in TIFF v3.5 + + + + + + + +TIFF CHANGE INFORMATION + + + + +

+This document describes the changes made to the software between the +previous and current versions (see above). +If you don't find something listed here, then it was not done in this +timeframe, or it was not considered important enough to be mentioned. +The following information is located here: +

+ +


+ +CHANGES IN THE SOFTWARE CONFIGURATION: + +
    +
  • None of consequence +
+ +


+ +CHANGES IN LIBTIFF: + + +
    +
  • Support was added for IPTC Newsphoto metadata (TIFFTAGE_IPTCNEWSPHOTO) +
  • Support was added for photoshop caption handling (TIFFTAG_PHOTOSHOP) +
+ +


+ +CHANGES IN THE TOOLS: + +
    +
  • Bill Radcliffe's iptcutil was +added to the "contrib" subdirectory . It can convert an IPTC binary +blob to ASCII text and vice-versa. The blob itself can be extracted +from or added to an image with the ImageMagick convert(1) +utility. +
+ + TIFF home page.
+ +
+ +
+Mike Welles / mike@onshore.com +Last updated $Date: 1999-07-27 21:50:27 $. +
+ + + diff --git a/html/where_is_sam.html b/html/where_is_sam.html new file mode 100644 index 00000000..5f6a75ad --- /dev/null +++ b/html/where_is_sam.html @@ -0,0 +1,35 @@ + + + Where's Sam? + + + + + + +This site came to be without the blessing of Sam Leffler. We couldn't +get ahold of him. We really would have liked to have obtained it. + +

+ +Attempts to track down Sam at SGI were unsuccessful (he moved on +without providing a forwarding address). There were reports of a +sighting at Pixar, but their operators didn't have any record of him. +people.yahoo.com didn't have any current e-mail addresses, and while +Mike did manage to dig up a home number for a Sam Leffler in CA, he +was loathe to call the poor guy at home. So, Sam, if you're reading, +we hope you don't mind us stealing your baby -- it's just that there +was a forked version being shipped with the Imagemagick NT +distribution, and forks are a bad thing. + +

+ +Since SGI hosted the master ftp site for v3.4beta037, we contacted +them instead, and recieved their permission to assume maintenance, +since there wasn't directly a person it was currently assigned to. + + + + + + diff --git a/libtiff/Makefile b/libtiff/Makefile new file mode 100644 index 00000000..34aff889 --- /dev/null +++ b/libtiff/Makefile @@ -0,0 +1,342 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/Makefile,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +SRCDIR = ../libtiff + +# +# VERSION: v3.4beta037 +# DATE: Wed Feb 3 19:53:27 EST 1999 +# TARGET: i586-unknown-linux +# CCOMPILER: /usr/bin/gcc +# +SHELL = /bin/sh +NULL = +CC = /usr/bin/gcc +AR = /usr/bin/ar +AROPTS = rc +RANLIB = /usr/bin/ranlib +INSTALL = ${SHELL} ../port/install.sh + +# +# If JPEG support is to be included and the Independent JPEG +# Software distribution is not installed then DIR_JPEG must +# refer to the directory where the include files reside. +# +# Similarly, if the libgz distribution is not installed, then +# DIR_LIBGZ must refer to the directory where the include files +# are located. Note that recent versions +# +IPATH = -I. -I${SRCDIR} +# +# To enable JPEG support include -DJPEG_SUPPORT here. +# To enable Deflate support add a -DZIP_SUPPORT here. +# Note that where the configure script is used these defines +# are automatically setup when JPEG/ZIP is set to "yes". +# +# Otherwise, consult tiffconf.h for information on controlling +# the configuration of optional library support. +# +CONF_LIBRARY= +COPTS = -g +OPTIMIZER=-O +CFLAGS = ${COPTS} ${OPTIMIZER} ${IPATH} ${CONF_LIBRARY} +# +SRCS = \ + tif_aux.c \ + tif_close.c \ + tif_codec.c \ + tif_compress.c \ + tif_dir.c \ + tif_dirinfo.c \ + tif_dirread.c \ + tif_dirwrite.c \ + tif_dumpmode.c \ + tif_error.c \ + tif_fax3.c \ + tif_fax3sm.c \ + tif_getimage.c \ + tif_jpeg.c \ + tif_flush.c \ + tif_luv.c \ + tif_lzw.c \ + tif_next.c \ + tif_open.c \ + tif_packbits.c \ + tif_pixarlog.c \ + tif_predict.c \ + tif_print.c \ + tif_read.c \ + tif_swab.c \ + tif_strip.c \ + tif_thunder.c \ + tif_tile.c \ + tif_unix.c \ + tif_version.c \ + tif_warning.c \ + tif_write.c \ + tif_zip.c \ + ${NULL} +OBJS = \ + tif_aux.o \ + tif_close.o \ + tif_codec.o \ + tif_compress.o \ + tif_dir.o \ + tif_dirinfo.o \ + tif_dirread.o \ + tif_dirwrite.o \ + tif_dumpmode.o \ + tif_error.o \ + tif_fax3.o \ + tif_fax3sm.o \ + tif_getimage.o \ + tif_jpeg.o \ + tif_flush.o \ + tif_luv.o \ + tif_lzw.o \ + tif_next.o \ + tif_open.o \ + tif_packbits.o \ + tif_pixarlog.o \ + tif_predict.o \ + tif_print.o \ + tif_read.o \ + tif_swab.o \ + tif_strip.o \ + tif_thunder.o \ + tif_tile.o \ + tif_unix.o \ + tif_version.o \ + tif_warning.o \ + tif_write.o \ + tif_zip.o \ + ${NULL} +TARGETS = libtiff.a + +all: ${TARGETS} + if [ nodso != nodso ]; then \ + ${MAKE} nodso; \ + else \ + true; \ + fi + +libtiff.a: ${OBJS} + ${AR} ${AROPTS} libtiff.a $? + ${RANLIB} libtiff.a + +# +# NB: The configure script verifies that the configured +# tools are capable of producing a DSO before enabling +# their creation/use. The following rules are effectively +# duplicated in the configure script to do this verification. +# This means that if you want to add support for building a +# DSO on another system you'll need to modify this file *and* +# configure if you want the right thing to happen automatically +# (should probably be fixed up). +# + +# default IRIX DSO building rule +IRIXdso: ${OBJS} + ${CC} -o libtiff.a -shared -rdata_shared \ + -check_registry ${SRCDIR}/../port/irix/so_locations \ + -quickstart_info \ + ${OBJS} + touch $@ +# special rule for IRIX 5.2 +IRIX52dso: ${OBJS} + ${LD} -elf -o libtiff.a -shared -no_unresolved -all ${OBJS} \ + -lc -lm + touch $@ +# Solaris 2.x +SOLARISdso: ${OBJS} + ${LD} -L/usr/local/lib -G -h libtiff.a -o libtiff.a ${OBJS} + touch $@ +# HP-UX A.09.03 +HPUXdso: ${OBJS} + ${LD} +b/usr/local/lib -b -o libtiff.a ${OBJS} + touch $@ +# AIX 2.3.5 and 4.1.1 +AIXdso: ${OBJS} + rm -f libtiff.syms shr.o + echo "#!" > libtiff.syms + /bin/dump -g libtiff.a | sed -n -e \ + 's/^[ ]*[0-9][0-9]*[ ]*\([^ .][^ ]*\)$$/\1/p' \ + >> libtiff.syms + ${LD} -o shr.o libtiff.a -H512 -T512 -bM\:SRE \ + -bE\:libtiff.syms -lc -lm -L/usr/local/lib + rm -f libtiff.syms libtiff.a + ${AR} ${AROPTS} libtiff.a shr.o + rm -f shr.o + touch $@ +# NetBSD 1.1 or FreeBSD +NETBSDdso FREEBSDdso: ${OBJS} + @rm -f libtiff_pic.a + @${AR} cq libtiff_pic.a `lorder ${OBJS} | tsort -q` + ${RANLIB} libtiff_pic.a + ${LD} -x -Bshareable -Bforcearchive -o libtiff.a libtiff_pic.a + rm -f libtiff_pic.a + touch $@ +# linux ELF shared lib rule +LINUXdso: ${OBJS} + ${CC} -shared -Wl,-soname,libtiff.a \ + -o libtiff.a ${OBJS} + /bin/ln -s libtiff.a libtiff.a + touch $@ +# OSF/1 3.2 shared lib rule +OSFdso: ${OBJS} + ${LD} -o libtiff.a -shared -error_unresolved ${OBJS} -lc -lm + + +${OBJS}: ${SRCDIR}/tiffio.h ${SRCDIR}/tiff.h ${SRCDIR}/tif_dir.h +${OBJS}: ${SRCDIR}/tiffcomp.h ${SRCDIR}/tiffiop.h ${SRCDIR}/tiffconf.h + +ALPHA = .././dist/tiff.alpha +VERSION = .././VERSION + +version.h: ${VERSION} ${ALPHA} ${SRCDIR}/mkversion.c + ${CC} -o mkversion ${CFLAGS} ${SRCDIR}/mkversion.c + rm -f version.h; ./mkversion -v ${VERSION} -a ${ALPHA} version.h +tif_version.o: version.h + +# +# The finite state machine tables used by the G3/G4 decoders +# are generated by the mkg3states program. On systems without +# make these rules have to be manually carried out. +# +tif_fax3sm.c: ${SRCDIR}/mkg3states.c ${SRCDIR}/tif_fax3.h + ${CC} -o mkg3states ${CFLAGS} ${SRCDIR}/mkg3states.c + rm -f tif_fax3sm.c; ./mkg3states -c const tif_fax3sm.c + +tif_aux.o: ${SRCDIR}/tif_aux.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_aux.c +tif_close.o: ${SRCDIR}/tif_close.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_close.c +tif_codec.o: ${SRCDIR}/tif_codec.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_codec.c +tif_compress.o: ${SRCDIR}/tif_compress.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_compress.c +tif_dir.o: ${SRCDIR}/tif_dir.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dir.c +tif_dirinfo.o: ${SRCDIR}/tif_dirinfo.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirinfo.c +tif_dirread.o: ${SRCDIR}/tif_dirread.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirread.c +tif_dirwrite.o: ${SRCDIR}/tif_dirwrite.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirwrite.c +tif_dumpmode.o: ${SRCDIR}/tif_dumpmode.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dumpmode.c +tif_error.o: ${SRCDIR}/tif_error.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_error.c +tif_fax3.o: ${SRCDIR}/tif_fax3.c ${SRCDIR}/t4.h ${SRCDIR}/tif_fax3.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_fax3.c +tif_getimage.o: ${SRCDIR}/tif_getimage.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_getimage.c +tif_jpeg.o: ${SRCDIR}/tif_jpeg.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_jpeg.c +tif_flush.o: ${SRCDIR}/tif_flush.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_flush.c +tif_luv.o: ${SRCDIR}/tif_luv.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_luv.c +tif_lzw.o: ${SRCDIR}/tif_lzw.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_lzw.c +tif_next.o: ${SRCDIR}/tif_next.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_next.c +tif_open.o: ${SRCDIR}/tif_open.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_open.c +tif_packbits.o: ${SRCDIR}/tif_packbits.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_packbits.c +tif_pixarlog.o: ${SRCDIR}/tif_pixarlog.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_pixarlog.c +tif_predict.o: ${SRCDIR}/tif_predict.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_predict.c +tif_print.o: ${SRCDIR}/tif_print.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_print.c +tif_read.o: ${SRCDIR}/tif_read.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_read.c +tif_swab.o: ${SRCDIR}/tif_swab.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_swab.c +tif_strip.o: ${SRCDIR}/tif_strip.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_strip.c +tif_thunder.o: ${SRCDIR}/tif_thunder.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_thunder.c +tif_tile.o: ${SRCDIR}/tif_tile.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_tile.c +tif_unix.o: ${SRCDIR}/tif_unix.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_unix.c +tif_version.o: ${SRCDIR}/tif_version.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_version.c +tif_warning.o: ${SRCDIR}/tif_warning.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_warning.c +tif_write.o: ${SRCDIR}/tif_write.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_write.c +tif_zip.o: ${SRCDIR}/tif_zip.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_zip.c + +tif_apple.o: ${SRCDIR}/tif_apple.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_apple.c +tif_atari.o: ${SRCDIR}/tif_atari.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_atari.c +tif_msdos.o: ${SRCDIR}/tif_msdos.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_msdos.c +tif_vms.o: ${SRCDIR}/tif_vms.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_vms.c +tif_win3.o: ${SRCDIR}/tif_win3.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_win3.c + +INCS = ${SRCDIR}/tiff.h ${SRCDIR}/tiffio.h + +installHdrs: ${INCS} + ${INSTALL} -idb tiff.sw.dev -m 755 -dir /usr/local/include + for i in ${INCS}; do \ + f=`basename $$i`; \ + ${INSTALL} -idb tiff.sw.dev -m 444 -F /usr/local/include \ + -src $$i -O $$f; \ + done +installDSO: nodso + if [ a != a ]; then \ + ${INSTALL} -idb tiff.sw.tools -m 555 -F /usr/local/lib \ + -O libtiff.a; \ + ${INSTALL} -idb tiff.sw.tools -F /usr/local/lib \ + -ln libtiff.a -O libtiff.a; \ + else \ + ${INSTALL} -idb tiff.sw.tools -m 555 -F /usr/local/lib \ + -O libtiff.a; \ + fi +install: all installHdrs + ${INSTALL} -idb tiff.sw.dev -m 755 -dir /usr/local/lib + ${INSTALL} -idb tiff.sw.dev -m 444 -F /usr/local/lib -O libtiff.a + if [ nodso != nodso ]; then \ + ${MAKE} installDSO; \ + else \ + true; \ + fi + +clean: + rm -f ${TARGETS} ${OBJS} core a.out \ + mkg3states tif_fax3sm.c \ + mkversion version.h \ + libtiff.a libtiff.a libtiff.a *dso diff --git a/libtiff/Makefile.in b/libtiff/Makefile.in new file mode 100644 index 00000000..2a61fbc5 --- /dev/null +++ b/libtiff/Makefile.in @@ -0,0 +1,342 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Makefile.in,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +SRCDIR = @LIBSRCDIR@ + +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# CCOMPILER: @CCOMPILER@ +# +SHELL = @SCRIPT_SH@ +NULL = +CC = @CCOMPILER@ +AR = @AR@ +AROPTS = @AROPTS@ +RANLIB = @RANLIB@ +INSTALL = @INSTALL@ + +# +# If JPEG support is to be included and the Independent JPEG +# Software distribution is not installed then DIR_JPEG must +# refer to the directory where the include files reside. +# +# Similarly, if the libgz distribution is not installed, then +# DIR_LIBGZ must refer to the directory where the include files +# are located. Note that recent versions +# +IPATH = -I. -I${SRCDIR} @COPT_LIBINC@ +# +# To enable JPEG support include -DJPEG_SUPPORT here. +# To enable Deflate support add a -DZIP_SUPPORT here. +# Note that where the configure script is used these defines +# are automatically setup when JPEG/ZIP is set to "yes". +# +# Otherwise, consult tiffconf.h for information on controlling +# the configuration of optional library support. +# +CONF_LIBRARY=@CONF_JPEG@ @CONF_ZIP@ +COPTS = @GCOPTS@ +OPTIMIZER=-O +CFLAGS = @ENVOPTS@ @LIBCOPTS@ ${COPTS} ${OPTIMIZER} ${IPATH} ${CONF_LIBRARY} +# +SRCS = \ + tif_aux.c \ + tif_close.c \ + tif_codec.c \ + tif_compress.c \ + tif_dir.c \ + tif_dirinfo.c \ + tif_dirread.c \ + tif_dirwrite.c \ + tif_dumpmode.c \ + tif_error.c \ + tif_fax3.c \ + tif_fax3sm.c \ + tif_getimage.c \ + tif_jpeg.c \ + tif_flush.c \ + tif_luv.c \ + tif_lzw.c \ + tif_next.c \ + tif_open.c \ + tif_packbits.c \ + tif_pixarlog.c \ + tif_predict.c \ + tif_print.c \ + tif_read.c \ + tif_swab.c \ + tif_strip.c \ + tif_thunder.c \ + tif_tile.c \ + tif_unix.c \ + tif_version.c \ + tif_warning.c \ + tif_write.c \ + tif_zip.c \ + ${NULL} +OBJS = \ + tif_aux.o \ + tif_close.o \ + tif_codec.o \ + tif_compress.o \ + tif_dir.o \ + tif_dirinfo.o \ + tif_dirread.o \ + tif_dirwrite.o \ + tif_dumpmode.o \ + tif_error.o \ + tif_fax3.o \ + tif_fax3sm.o \ + tif_getimage.o \ + tif_jpeg.o \ + tif_flush.o \ + tif_luv.o \ + tif_lzw.o \ + tif_next.o \ + tif_open.o \ + tif_packbits.o \ + tif_pixarlog.o \ + tif_predict.o \ + tif_print.o \ + tif_read.o \ + tif_swab.o \ + tif_strip.o \ + tif_thunder.o \ + tif_tile.o \ + tif_unix.o \ + tif_version.o \ + tif_warning.o \ + tif_write.o \ + tif_zip.o \ + ${NULL} +TARGETS = libtiff.a + +all: ${TARGETS} + if [ @DSO@dso != nodso ]; then \ + ${MAKE} @DSO@dso; \ + else \ + true; \ + fi + +libtiff.a: ${OBJS} + ${AR} ${AROPTS} libtiff.a $? + ${RANLIB} libtiff.a + +# +# NB: The configure script verifies that the configured +# tools are capable of producing a DSO before enabling +# their creation/use. The following rules are effectively +# duplicated in the configure script to do this verification. +# This means that if you want to add support for building a +# DSO on another system you'll need to modify this file *and* +# configure if you want the right thing to happen automatically +# (should probably be fixed up). +# + +# default IRIX DSO building rule +IRIXdso: ${OBJS} + ${CC} @ENVOPTS@ -o libtiff.@DSOSUF@ -shared -rdata_shared \ + -check_registry ${SRCDIR}/../port/irix/so_locations \ + -quickstart_info \ + ${OBJS} @LIBJPEG@ @LIBGZ@ + touch $@ +# special rule for IRIX 5.2 +IRIX52dso: ${OBJS} + ${LD} -elf -o libtiff.@DSOSUF@ -shared -no_unresolved -all ${OBJS} \ + @LIBJPEG@ @LIBGZ@ -lc -lm + touch $@ +# Solaris 2.x +SOLARISdso: ${OBJS} + ${LD} -L@DIR_LIB@ -G -h libtiff.@DSOSUF@ -o libtiff.@DSOSUF@ ${OBJS} + touch $@ +# HP-UX A.09.03 +HPUXdso: ${OBJS} + ${LD} +b@DIR_LIB@ -b -o libtiff.@DSOSUF@ ${OBJS} + touch $@ +# AIX 2.3.5 and 4.1.1 +AIXdso: ${OBJS} + rm -f libtiff.syms shr.o + echo "#!" > libtiff.syms + /bin/dump -g libtiff.a | sed -n -e \ + 's/^[ ]*[0-9][0-9]*[ ]*\([^ .][^ ]*\)$$/\1/p' \ + >> libtiff.syms + ${LD} -o shr.o libtiff.a -H512 -T512 -bM\:SRE \ + -bE\:libtiff.syms @LIBJPEG@ @LIBGZ@ -lc -lm -L@DIR_LIB@ + rm -f libtiff.syms libtiff.@DSOSUF@ + ${AR} ${AROPTS} libtiff.@DSOSUF@ shr.o + rm -f shr.o + touch $@ +# NetBSD 1.1 or FreeBSD +NETBSDdso FREEBSDdso: ${OBJS} + @rm -f libtiff_pic.a + @${AR} cq libtiff_pic.a `lorder ${OBJS} | tsort -q` + ${RANLIB} libtiff_pic.a + ${LD} -x -Bshareable -Bforcearchive -o libtiff.@DSOSUF@ libtiff_pic.a + rm -f libtiff_pic.a + touch $@ +# linux ELF shared lib rule +LINUXdso: ${OBJS} + ${CC} -shared -Wl,-soname,libtiff.@DSOSUF@ \ + -o libtiff.@DSOSUF_VERSION@ ${OBJS} @LIBJPEG@ @LIBGZ@ + @LN@ @LN_S@ libtiff.@DSOSUF_VERSION@ libtiff.@DSOSUF@ + touch $@ +# OSF/1 3.2 shared lib rule +OSFdso: ${OBJS} + ${LD} -o libtiff.@DSOSUF@ -shared -error_unresolved ${OBJS} @LIBJPEG@ @LIBGZ@ -lc -lm + + +${OBJS}: ${SRCDIR}/tiffio.h ${SRCDIR}/tiff.h ${SRCDIR}/tif_dir.h +${OBJS}: ${SRCDIR}/tiffcomp.h ${SRCDIR}/tiffiop.h ${SRCDIR}/tiffconf.h + +ALPHA = @ALPHAFILE@ +VERSION = @VERSIONFILE@ + +version.h: ${VERSION} ${ALPHA} ${SRCDIR}/mkversion.c + ${CC} -o mkversion ${CFLAGS} ${SRCDIR}/mkversion.c + rm -f version.h; ./mkversion -v ${VERSION} -a ${ALPHA} version.h +tif_version.o: version.h + +# +# The finite state machine tables used by the G3/G4 decoders +# are generated by the mkg3states program. On systems without +# make these rules have to be manually carried out. +# +tif_fax3sm.c: ${SRCDIR}/mkg3states.c ${SRCDIR}/tif_fax3.h + ${CC} -o mkg3states ${CFLAGS} ${SRCDIR}/mkg3states.c + rm -f tif_fax3sm.c; ./mkg3states -c const tif_fax3sm.c + +tif_aux.o: ${SRCDIR}/tif_aux.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_aux.c +tif_close.o: ${SRCDIR}/tif_close.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_close.c +tif_codec.o: ${SRCDIR}/tif_codec.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_codec.c +tif_compress.o: ${SRCDIR}/tif_compress.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_compress.c +tif_dir.o: ${SRCDIR}/tif_dir.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dir.c +tif_dirinfo.o: ${SRCDIR}/tif_dirinfo.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirinfo.c +tif_dirread.o: ${SRCDIR}/tif_dirread.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirread.c +tif_dirwrite.o: ${SRCDIR}/tif_dirwrite.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dirwrite.c +tif_dumpmode.o: ${SRCDIR}/tif_dumpmode.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_dumpmode.c +tif_error.o: ${SRCDIR}/tif_error.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_error.c +tif_fax3.o: ${SRCDIR}/tif_fax3.c ${SRCDIR}/t4.h ${SRCDIR}/tif_fax3.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_fax3.c +tif_getimage.o: ${SRCDIR}/tif_getimage.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_getimage.c +tif_jpeg.o: ${SRCDIR}/tif_jpeg.c @DEPEND_JPEGLIB@ + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_jpeg.c +tif_flush.o: ${SRCDIR}/tif_flush.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_flush.c +tif_luv.o: ${SRCDIR}/tif_luv.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_luv.c +tif_lzw.o: ${SRCDIR}/tif_lzw.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_lzw.c +tif_next.o: ${SRCDIR}/tif_next.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_next.c +tif_open.o: ${SRCDIR}/tif_open.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_open.c +tif_packbits.o: ${SRCDIR}/tif_packbits.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_packbits.c +tif_pixarlog.o: ${SRCDIR}/tif_pixarlog.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_pixarlog.c +tif_predict.o: ${SRCDIR}/tif_predict.c ${SRCDIR}/tif_predict.h + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_predict.c +tif_print.o: ${SRCDIR}/tif_print.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_print.c +tif_read.o: ${SRCDIR}/tif_read.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_read.c +tif_swab.o: ${SRCDIR}/tif_swab.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_swab.c +tif_strip.o: ${SRCDIR}/tif_strip.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_strip.c +tif_thunder.o: ${SRCDIR}/tif_thunder.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_thunder.c +tif_tile.o: ${SRCDIR}/tif_tile.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_tile.c +tif_unix.o: ${SRCDIR}/tif_unix.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_unix.c +tif_version.o: ${SRCDIR}/tif_version.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_version.c +tif_warning.o: ${SRCDIR}/tif_warning.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_warning.c +tif_write.o: ${SRCDIR}/tif_write.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_write.c +tif_zip.o: ${SRCDIR}/tif_zip.c ${SRCDIR}/tif_predict.h @DEPEND_ZLIB@ + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_zip.c + +tif_apple.o: ${SRCDIR}/tif_apple.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_apple.c +tif_atari.o: ${SRCDIR}/tif_atari.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_atari.c +tif_msdos.o: ${SRCDIR}/tif_msdos.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_msdos.c +tif_vms.o: ${SRCDIR}/tif_vms.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_vms.c +tif_win3.o: ${SRCDIR}/tif_win3.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tif_win3.c + +INCS = ${SRCDIR}/tiff.h ${SRCDIR}/tiffio.h + +installHdrs: ${INCS} + ${INSTALL} -idb tiff.sw.dev -m 755 -dir @DIR_INC@ + for i in ${INCS}; do \ + f=`basename $$i`; \ + ${INSTALL} -idb tiff.sw.dev -m 444 -F @DIR_INC@ \ + -src $$i -O $$f; \ + done +installDSO: @DSO@dso + if [ @DSOSUF_VERSION@ != @DSOSUF@ ]; then \ + ${INSTALL} -idb tiff.sw.tools -m 555 -F @DIR_LIB@ \ + -O libtiff.@DSOSUF_VERSION@; \ + ${INSTALL} -idb tiff.sw.tools -F @DIR_LIB@ \ + -ln libtiff.@DSOSUF_VERSION@ -O libtiff.@DSOSUF@; \ + else \ + ${INSTALL} -idb tiff.sw.tools -m 555 -F @DIR_LIB@ \ + -O libtiff.@DSOSUF@; \ + fi +install: all installHdrs + ${INSTALL} -idb tiff.sw.dev -m 755 -dir @DIR_LIB@ + ${INSTALL} -idb tiff.sw.dev -m 444 -F @DIR_LIB@ -O libtiff.a + if [ @DSO@dso != nodso ]; then \ + ${MAKE} installDSO; \ + else \ + true; \ + fi + +clean: + rm -f ${TARGETS} ${OBJS} core a.out \ + mkg3states tif_fax3sm.c \ + mkversion version.h \ + libtiff.a libtiff.@DSOSUF@ libtiff.@DSOSUF_VERSION@ *dso diff --git a/libtiff/Makefile.lcc b/libtiff/Makefile.lcc new file mode 100644 index 00000000..3ed735ba --- /dev/null +++ b/libtiff/Makefile.lcc @@ -0,0 +1,129 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Makefile.lcc,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# Tag Image File Format Library +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +DESTDIR=. +# +INSTALL=install +NULL= + +IPATH= -I. -I../jpeg +CONF_LIBRARY=\ + ${NULL} +COPTS= -Oloop -cwagshf -d1 -b0 -v -DNDEBUG -rr -j135i +CFLAGS= ${COPTS} ${IPATH} ${CONF_LIBRARY} +# +INCS= tiff.h tiffio.h +SRCS= tif_fax3.c \ + tif_fax4.c \ + tif_aux.c \ + tif_atari.c \ + tif_ccittrle.c \ + tif_close.c \ + tif_compress.c \ + tif_dir.c \ + tif_dirinfo.c \ + tif_dirread.c \ + tif_dirwrite.c \ + tif_dumpmode.c \ + tif_error.c \ + tif_getimage.c \ + tif_jpeg.c \ + tif_flush.c \ + tif_lzw.c \ + tif_next.c \ + tif_open.c \ + tif_packbits.c \ + tif_print.c \ + tif_read.c \ + tif_swab.c \ + tif_strip.c \ + tif_thunder.c \ + tif_tile.c \ + tif_version.c \ + tif_warning.c \ + tif_write.c \ + ${NULL} +OBJS= tif_fax3.o \ + tif_fax4.o \ + tif_aux.o \ + tif_atari.o \ + tif_ccittrle.o \ + tif_close.o \ + tif_compress.o \ + tif_dir.o \ + tif_dirinfo.o \ + tif_dirread.o \ + tif_dirwrite.o \ + tif_dumpmode.o \ + tif_error.o \ + tif_getimage.o \ + tif_jpeg.o \ + tif_flush.o \ + tif_lzw.o \ + tif_next.o \ + tif_open.o \ + tif_packbits.o \ + tif_print.o \ + tif_read.o \ + tif_swab.o \ + tif_strip.o \ + tif_thunder.o \ + tif_tile.o \ + tif_version.o \ + tif_warning.o \ + tif_write.o \ + ${NULL} +ALL= tiffrnb.lib + +all: ${ALL} + +${ALL}: ${OBJS} + ${AR} ${ARFLAGS} $@ r $< + +${OBJS}: tiffio.h tiff.h tiffcomp.h tiffiop.h tiffconf.h +tif_fax3.o: tif_fax3.c g3states.h t4.h tif_fax3.h + +g3states.h: mkg3states.c t4.h + ${CC} -o mkg3states.ttp ${CFLAGS} mkg3states.c + ./mkg3states -c > g3states.h + +install: all installh + -for i in ${ALL}; do \ + ${INSTALL} -c -m 644 $$i ${DESTDIR}/lib/$$i; \ + done + +installh: ${INCS} + -for i in ${INCS}; do \ + h=`basename $$i`; \ + cmp -s $$i ${DESTDIR}/include/$$h || \ + ${INSTALL} -c -m 444 $$i ${DESTDIR}/include/$$h; \ + done + +clean: + rm -f ${ALL} ${OBJS} mkg3states.ttp mkg3states.o g3states.h + +tags: ${SRCS} + ${CTAGS} ${SRCS} diff --git a/libtiff/mkg3states.c b/libtiff/mkg3states.c new file mode 100644 index 00000000..f02b24aa --- /dev/null +++ b/libtiff/mkg3states.c @@ -0,0 +1,436 @@ +/* "$Header: /cvs/maptools/cvsroot/libtiff/libtiff/mkg3states.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* Initialise fax decoder tables + * Decoder support is derived, with permission, from the code + * in Frank Cringle's viewfax program; + * Copyright (C) 1990, 1995 Frank D. Cringle. + */ +#if defined(unix) || defined(__unix) +#include "port.h" +#else +#include +#include +#include +#endif + +#include "tif_fax3.h" + +#define streq(a,b) (strcmp(a,b) == 0) + +/* NB: can't use names in tif_fax3.h 'cuz they are declared const */ +TIFFFaxTabEnt MainTable[128]; +TIFFFaxTabEnt WhiteTable[4096]; +TIFFFaxTabEnt BlackTable[8192]; + +struct proto { + uint16 code; /* right justified, lsb-first, zero filled */ + uint16 val; /* (pixel count)<<4 + code width */ +}; + +static struct proto Pass[] = { +{ 0x0008, 4 }, +{ 0, 0 } +}; + +static struct proto Horiz[] = { +{ 0x0004, 3 }, +{ 0, 0 } +}; + +static struct proto V0[] = { +{ 0x0001, 1 }, +{ 0, 0 } +}; + +static struct proto VR[] = { +{ 0x0006, (1<<4)+3 }, +{ 0x0030, (2<<4)+6 }, +{ 0x0060, (3<<4)+7 }, +{ 0, 0 } +}; + +static struct proto VL[] = { +{ 0x0002, (1<<4)+3 }, +{ 0x0010, (2<<4)+6 }, +{ 0x0020, (3<<4)+7 }, +{ 0, 0 } +}; + +static struct proto Ext[] = { +{ 0x0040, 7 }, +{ 0, 0 } +}; + +static struct proto EOLV[] = { +{ 0x0000, 7 }, +{ 0, 0 } +}; + +static struct proto MakeUpW[] = { +{ 0x001b, 1029 }, +{ 0x0009, 2053 }, +{ 0x003a, 3078 }, +{ 0x0076, 4103 }, +{ 0x006c, 5128 }, +{ 0x00ec, 6152 }, +{ 0x0026, 7176 }, +{ 0x00a6, 8200 }, +{ 0x0016, 9224 }, +{ 0x00e6, 10248 }, +{ 0x0066, 11273 }, +{ 0x0166, 12297 }, +{ 0x0096, 13321 }, +{ 0x0196, 14345 }, +{ 0x0056, 15369 }, +{ 0x0156, 16393 }, +{ 0x00d6, 17417 }, +{ 0x01d6, 18441 }, +{ 0x0036, 19465 }, +{ 0x0136, 20489 }, +{ 0x00b6, 21513 }, +{ 0x01b6, 22537 }, +{ 0x0032, 23561 }, +{ 0x0132, 24585 }, +{ 0x00b2, 25609 }, +{ 0x0006, 26630 }, +{ 0x01b2, 27657 }, +{ 0, 0 } +}; + +static struct proto MakeUpB[] = { +{ 0x03c0, 1034 }, +{ 0x0130, 2060 }, +{ 0x0930, 3084 }, +{ 0x0da0, 4108 }, +{ 0x0cc0, 5132 }, +{ 0x02c0, 6156 }, +{ 0x0ac0, 7180 }, +{ 0x06c0, 8205 }, +{ 0x16c0, 9229 }, +{ 0x0a40, 10253 }, +{ 0x1a40, 11277 }, +{ 0x0640, 12301 }, +{ 0x1640, 13325 }, +{ 0x09c0, 14349 }, +{ 0x19c0, 15373 }, +{ 0x05c0, 16397 }, +{ 0x15c0, 17421 }, +{ 0x0dc0, 18445 }, +{ 0x1dc0, 19469 }, +{ 0x0940, 20493 }, +{ 0x1940, 21517 }, +{ 0x0540, 22541 }, +{ 0x1540, 23565 }, +{ 0x0b40, 24589 }, +{ 0x1b40, 25613 }, +{ 0x04c0, 26637 }, +{ 0x14c0, 27661 }, +{ 0, 0 } +}; + +static struct proto MakeUp[] = { +{ 0x0080, 28683 }, +{ 0x0180, 29707 }, +{ 0x0580, 30731 }, +{ 0x0480, 31756 }, +{ 0x0c80, 32780 }, +{ 0x0280, 33804 }, +{ 0x0a80, 34828 }, +{ 0x0680, 35852 }, +{ 0x0e80, 36876 }, +{ 0x0380, 37900 }, +{ 0x0b80, 38924 }, +{ 0x0780, 39948 }, +{ 0x0f80, 40972 }, +{ 0, 0 } +}; + +static struct proto TermW[] = { +{ 0x00ac, 8 }, +{ 0x0038, 22 }, +{ 0x000e, 36 }, +{ 0x0001, 52 }, +{ 0x000d, 68 }, +{ 0x0003, 84 }, +{ 0x0007, 100 }, +{ 0x000f, 116 }, +{ 0x0019, 133 }, +{ 0x0005, 149 }, +{ 0x001c, 165 }, +{ 0x0002, 181 }, +{ 0x0004, 198 }, +{ 0x0030, 214 }, +{ 0x000b, 230 }, +{ 0x002b, 246 }, +{ 0x0015, 262 }, +{ 0x0035, 278 }, +{ 0x0072, 295 }, +{ 0x0018, 311 }, +{ 0x0008, 327 }, +{ 0x0074, 343 }, +{ 0x0060, 359 }, +{ 0x0010, 375 }, +{ 0x000a, 391 }, +{ 0x006a, 407 }, +{ 0x0064, 423 }, +{ 0x0012, 439 }, +{ 0x000c, 455 }, +{ 0x0040, 472 }, +{ 0x00c0, 488 }, +{ 0x0058, 504 }, +{ 0x00d8, 520 }, +{ 0x0048, 536 }, +{ 0x00c8, 552 }, +{ 0x0028, 568 }, +{ 0x00a8, 584 }, +{ 0x0068, 600 }, +{ 0x00e8, 616 }, +{ 0x0014, 632 }, +{ 0x0094, 648 }, +{ 0x0054, 664 }, +{ 0x00d4, 680 }, +{ 0x0034, 696 }, +{ 0x00b4, 712 }, +{ 0x0020, 728 }, +{ 0x00a0, 744 }, +{ 0x0050, 760 }, +{ 0x00d0, 776 }, +{ 0x004a, 792 }, +{ 0x00ca, 808 }, +{ 0x002a, 824 }, +{ 0x00aa, 840 }, +{ 0x0024, 856 }, +{ 0x00a4, 872 }, +{ 0x001a, 888 }, +{ 0x009a, 904 }, +{ 0x005a, 920 }, +{ 0x00da, 936 }, +{ 0x0052, 952 }, +{ 0x00d2, 968 }, +{ 0x004c, 984 }, +{ 0x00cc, 1000 }, +{ 0x002c, 1016 }, +{ 0, 0 } +}; + +static struct proto TermB[] = { +{ 0x03b0, 10 }, +{ 0x0002, 19 }, +{ 0x0003, 34 }, +{ 0x0001, 50 }, +{ 0x0006, 67 }, +{ 0x000c, 84 }, +{ 0x0004, 100 }, +{ 0x0018, 117 }, +{ 0x0028, 134 }, +{ 0x0008, 150 }, +{ 0x0010, 167 }, +{ 0x0050, 183 }, +{ 0x0070, 199 }, +{ 0x0020, 216 }, +{ 0x00e0, 232 }, +{ 0x0030, 249 }, +{ 0x03a0, 266 }, +{ 0x0060, 282 }, +{ 0x0040, 298 }, +{ 0x0730, 315 }, +{ 0x00b0, 331 }, +{ 0x01b0, 347 }, +{ 0x0760, 363 }, +{ 0x00a0, 379 }, +{ 0x0740, 395 }, +{ 0x00c0, 411 }, +{ 0x0530, 428 }, +{ 0x0d30, 444 }, +{ 0x0330, 460 }, +{ 0x0b30, 476 }, +{ 0x0160, 492 }, +{ 0x0960, 508 }, +{ 0x0560, 524 }, +{ 0x0d60, 540 }, +{ 0x04b0, 556 }, +{ 0x0cb0, 572 }, +{ 0x02b0, 588 }, +{ 0x0ab0, 604 }, +{ 0x06b0, 620 }, +{ 0x0eb0, 636 }, +{ 0x0360, 652 }, +{ 0x0b60, 668 }, +{ 0x05b0, 684 }, +{ 0x0db0, 700 }, +{ 0x02a0, 716 }, +{ 0x0aa0, 732 }, +{ 0x06a0, 748 }, +{ 0x0ea0, 764 }, +{ 0x0260, 780 }, +{ 0x0a60, 796 }, +{ 0x04a0, 812 }, +{ 0x0ca0, 828 }, +{ 0x0240, 844 }, +{ 0x0ec0, 860 }, +{ 0x01c0, 876 }, +{ 0x0e40, 892 }, +{ 0x0140, 908 }, +{ 0x01a0, 924 }, +{ 0x09a0, 940 }, +{ 0x0d40, 956 }, +{ 0x0340, 972 }, +{ 0x05a0, 988 }, +{ 0x0660, 1004 }, +{ 0x0e60, 1020 }, +{ 0, 0 } +}; + +static struct proto EOLH[] = { +{ 0x0000, 11 }, +{ 0, 0 } +}; + +static void +FillTable(TIFFFaxTabEnt *T, int Size, struct proto *P, int State) +{ + int limit = 1 << Size; + + while (P->val) { + int width = P->val & 15; + int param = P->val >> 4; + int incr = 1 << width; + int code; + for (code = P->code; code < limit; code += incr) { + TIFFFaxTabEnt *E = T+code; + E->State = State; + E->Width = width; + E->Param = param; + } + P++; + } +} + +static char* storage_class = ""; +static char* const_class = ""; +static int packoutput = 1; +static char* prebrace = ""; +static char* postbrace = ""; + +void +WriteTable(FILE* fd, const TIFFFaxTabEnt* T, int Size, const char* name) +{ + int i; + char* sep; + + fprintf(fd, "%s %s TIFFFaxTabEnt %s[%d] = {", + storage_class, const_class, name, Size); + if (packoutput) { + sep = "\n"; + for (i = 0; i < Size; i++) { + fprintf(fd, "%s%s%d,%d,%d%s", + sep, prebrace, T->State, T->Width, T->Param, postbrace); + if (((i+1) % 12) == 0) + sep = ",\n"; + else + sep = ","; + T++; + } + } else { + sep = "\n "; + for (i = 0; i < Size; i++) { + fprintf(fd, "%s%s%3d,%3d,%4d%s", + sep, prebrace, T->State, T->Width, T->Param, postbrace); + if (((i+1) % 6) == 0) + sep = ",\n "; + else + sep = ","; + T++; + } + } + fprintf(fd, "\n};\n"); +} + +/* initialise the huffman code tables */ +int +main(int argc, char* argv[]) +{ + FILE* fd; + char* outputfile; + int c; + extern int optind; + extern char* optarg; + + while ((c = getopt(argc, argv, "c:s:bp")) != -1) + switch (c) { + case 'c': + const_class = optarg; + break; + case 's': + storage_class = optarg; + break; + case 'p': + packoutput = 0; + break; + case 'b': + prebrace = "{"; + postbrace = "}"; + break; + case '?': + fprintf(stderr, + "usage: %s [-c const] [-s storage] [-p] [-b] file\n", + argv[0]); + return (-1); + } + outputfile = optind < argc ? argv[optind] : "g3states.h"; + fd = fopen(outputfile, "w"); + if (fd == NULL) { + fprintf(stderr, "%s: %s: Cannot create output file.\n", + argv[0], outputfile); + return (-2); + } + FillTable(MainTable, 7, Pass, S_Pass); + FillTable(MainTable, 7, Horiz, S_Horiz); + FillTable(MainTable, 7, V0, S_V0); + FillTable(MainTable, 7, VR, S_VR); + FillTable(MainTable, 7, VL, S_VL); + FillTable(MainTable, 7, Ext, S_Ext); + FillTable(MainTable, 7, EOLV, S_EOL); + FillTable(WhiteTable, 12, MakeUpW, S_MakeUpW); + FillTable(WhiteTable, 12, MakeUp, S_MakeUp); + FillTable(WhiteTable, 12, TermW, S_TermW); + FillTable(WhiteTable, 12, EOLH, S_EOL); + FillTable(BlackTable, 13, MakeUpB, S_MakeUpB); + FillTable(BlackTable, 13, MakeUp, S_MakeUp); + FillTable(BlackTable, 13, TermB, S_TermB); + FillTable(BlackTable, 13, EOLH, S_EOL); + + fprintf(fd, "/* WARNING, this file was automatically generated by the\n"); + fprintf(fd, " mkg3states program */\n"); + fprintf(fd, "#include \"tiff.h\"\n"); + fprintf(fd, "#include \"tif_fax3.h\"\n"); + WriteTable(fd, MainTable, 128, "TIFFFaxMainTable"); + WriteTable(fd, WhiteTable, 4096, "TIFFFaxWhiteTable"); + WriteTable(fd, BlackTable, 8192, "TIFFFaxBlackTable"); + fclose(fd); + return (0); +} diff --git a/libtiff/mkspans.c b/libtiff/mkspans.c new file mode 100644 index 00000000..43e8f98f --- /dev/null +++ b/libtiff/mkspans.c @@ -0,0 +1,72 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/mkspans.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffcomp.h" + +/* + * Hack program to construct tables used to find + * runs of zeros and ones in Group 3 Fax encoding. + */ + +dumparray(name, runs) + char *name; + unsigned char runs[256]; +{ + register int i; + register char *sep; + printf("static u_char %s[256] = {\n", name); + sep = " "; + for (i = 0; i < 256; i++) { + printf("%s%d", sep, runs[i]); + if (((i + 1) % 16) == 0) { + printf(", /* 0x%02x - 0x%02x */\n", i-15, i); + sep = " "; + } else + sep = ", "; + } + printf("\n};\n"); +} + +main() +{ + unsigned char runs[2][256]; + + memset(runs[0], 0, 256*sizeof (char)); + memset(runs[1], 0, 256*sizeof (char)); + { register int run, runlen, i; + runlen = 1; + for (run = 0x80; run != 0xff; run = (run>>1)|0x80) { + for (i = run-1; i >= 0; i--) { + runs[1][run|i] = runlen; + runs[0][(~(run|i)) & 0xff] = runlen; + } + runlen++; + } + runs[1][0xff] = runs[0][0] = 8; + } + dumparray("bruns", runs[0]); + dumparray("wruns", runs[1]); +} diff --git a/libtiff/mkversion.c b/libtiff/mkversion.c new file mode 100644 index 00000000..bad7c55b --- /dev/null +++ b/libtiff/mkversion.c @@ -0,0 +1,132 @@ +/* "$Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/mkversion.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1995-1997 Sam Leffler + * Copyright (c) 1995-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * Generate a library version string for systems that + * do not have a shell (by default this is done with + * awk and echo from the Makefile). + * + * This was written by Peter Greenham for Acorn systems. + * + * Syntax: mkversion [-v version-file] [-a alpha-file] [] + */ +#include +#include +#include + +static void +usage(void) +{ + fprintf(stderr, + "usage: mkversion [-v version-file] [-a alpha-file] [outfile]\n"); + exit(-1); +} + +static FILE* +openFile(char* filename) +{ + FILE* fd = fopen(filename, "r"); + if (fd == NULL) { + fprintf(stderr, "mkversion: %s: Could not open for reading.\n", + filename); + exit(-1); + } + return (fd); +} + +int +main(int argc, char* argv[]) +{ + char* versionFile = "../VERSION"; + char* alphaFile = "../dist/tiff.alpha"; + char version[128]; + char alpha[128]; + FILE* fd; + char* cp; + + argc--, argv++; + while (argc > 0 && argv[0][0] == '-') { + if (strcmp(argv[0], "-v") == 0) { + if (argc < 1) + usage(); + argc--, argv++; + versionFile = argv[0]; + } else if (strcmp(argv[0], "-a") == 0) { + if (argc < 1) + usage(); + argc--, argv++; + alphaFile = argv[0]; + } else + usage(); + argc--, argv++; + } + fd = openFile(versionFile); + if (fgets(version, sizeof (version)-1, fd) == NULL) { + fprintf(stderr, "mkversion: No version information in %s.\n", + versionFile); + exit(-1); + } + cp = strchr(version, '\n'); + if (cp) + *cp = '\0'; + fclose(fd); + fd = openFile(alphaFile); + if (fgets(alpha, sizeof (alpha)-1, fd) == NULL) { + fprintf(stderr, "mkversion: No alpha information in %s.\n", alphaFile); + exit(-1); + } + fclose(fd); + cp = strchr(alpha, ' '); /* skip to 3rd blank-separated field */ + if (cp) + cp = strchr(cp+1, ' '); + if (cp) { /* append alpha to version */ + char* tp; + for (tp = strchr(version, '\0'), cp++; *tp = *cp; tp++, cp++) + ; + if (tp[-1] == '\n') + tp[-1] = '\0'; + } else { + fprintf(stderr, "mkversion: Malformed alpha information in %s.\n", + alphaFile); + exit(-1); + } + if (argc > 0) { + fd = fopen(argv[0], "w"); + if (fd == NULL) { + fprintf(stderr, "mkversion: %s: Could not open for writing.\n", + argv[0]); + exit(-1); + } + } else + fd = stdout; + fprintf(fd, "#define VERSION \"LIBTIFF, Version %s\\n", version); + fprintf(fd, "Copyright (c) 1988-1996 Sam Leffler\\n"); + fprintf(fd, "Copyright (c) 1991-1996 Silicon Graphics, Inc.\"\n"); + + if (fd != stdout) + fclose(fd); + return (0); +} diff --git a/libtiff/port.h b/libtiff/port.h new file mode 100644 index 00000000..f1b841e3 --- /dev/null +++ b/libtiff/port.h @@ -0,0 +1,32 @@ +/* + * Warning, this file was automatically created by the TIFF configure script + * VERSION: v3.4beta037 + * DATE: Wed Feb 3 19:53:27 EST 1999 + * TARGET: i586-unknown-linux + * CCOMPILER: /usr/bin/gcc-2.7.2.3 + */ +#ifndef _PORT_ +#define _PORT_ 1 +#ifdef __cplusplus +extern "C" { +#endif +#include +#define HOST_FILLORDER FILLORDER_LSB2MSB +#define HOST_BIGENDIAN 0 +#define HAVE_MMAP 1 +#include +#include +#include +#include +#include +typedef double dblparam_t; +#ifdef __STRICT_ANSI__ +#define INLINE __inline__ +#else +#define INLINE inline +#endif +#define GLOBALDATA(TYPE,NAME) extern TYPE NAME +#ifdef __cplusplus +} +#endif +#endif diff --git a/libtiff/t4.h b/libtiff/t4.h new file mode 100644 index 00000000..5035fdcb --- /dev/null +++ b/libtiff/t4.h @@ -0,0 +1,285 @@ +/* $Id: t4.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _T4_ +#define _T4_ +/* + * CCITT T.4 1D Huffman runlength codes and + * related definitions. Given the small sizes + * of these tables it does not seem + * worthwhile to make code & length 8 bits. + */ +typedef struct tableentry { + unsigned short length; /* bit length of g3 code */ + unsigned short code; /* g3 code */ + short runlen; /* run length in bits */ +} tableentry; + +#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ + +/* status values returned instead of a run length */ +#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ +#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ +#define G3CODE_EOF -3 /* end of input data */ +#define G3CODE_INCOMP -4 /* incomplete run code */ + +/* + * Note that these tables are ordered such that the + * index into the table is known to be either the + * run length, or (run length / 64) + a fixed offset. + * + * NB: The G3CODE_INVALID entries are only used + * during state generation (see mkg3states.c). + */ +#ifdef G3CODES +const tableentry TIFFFaxWhiteCodes[] = { + { 8, 0x35, 0 }, /* 0011 0101 */ + { 6, 0x7, 1 }, /* 0001 11 */ + { 4, 0x7, 2 }, /* 0111 */ + { 4, 0x8, 3 }, /* 1000 */ + { 4, 0xB, 4 }, /* 1011 */ + { 4, 0xC, 5 }, /* 1100 */ + { 4, 0xE, 6 }, /* 1110 */ + { 4, 0xF, 7 }, /* 1111 */ + { 5, 0x13, 8 }, /* 1001 1 */ + { 5, 0x14, 9 }, /* 1010 0 */ + { 5, 0x7, 10 }, /* 0011 1 */ + { 5, 0x8, 11 }, /* 0100 0 */ + { 6, 0x8, 12 }, /* 0010 00 */ + { 6, 0x3, 13 }, /* 0000 11 */ + { 6, 0x34, 14 }, /* 1101 00 */ + { 6, 0x35, 15 }, /* 1101 01 */ + { 6, 0x2A, 16 }, /* 1010 10 */ + { 6, 0x2B, 17 }, /* 1010 11 */ + { 7, 0x27, 18 }, /* 0100 111 */ + { 7, 0xC, 19 }, /* 0001 100 */ + { 7, 0x8, 20 }, /* 0001 000 */ + { 7, 0x17, 21 }, /* 0010 111 */ + { 7, 0x3, 22 }, /* 0000 011 */ + { 7, 0x4, 23 }, /* 0000 100 */ + { 7, 0x28, 24 }, /* 0101 000 */ + { 7, 0x2B, 25 }, /* 0101 011 */ + { 7, 0x13, 26 }, /* 0010 011 */ + { 7, 0x24, 27 }, /* 0100 100 */ + { 7, 0x18, 28 }, /* 0011 000 */ + { 8, 0x2, 29 }, /* 0000 0010 */ + { 8, 0x3, 30 }, /* 0000 0011 */ + { 8, 0x1A, 31 }, /* 0001 1010 */ + { 8, 0x1B, 32 }, /* 0001 1011 */ + { 8, 0x12, 33 }, /* 0001 0010 */ + { 8, 0x13, 34 }, /* 0001 0011 */ + { 8, 0x14, 35 }, /* 0001 0100 */ + { 8, 0x15, 36 }, /* 0001 0101 */ + { 8, 0x16, 37 }, /* 0001 0110 */ + { 8, 0x17, 38 }, /* 0001 0111 */ + { 8, 0x28, 39 }, /* 0010 1000 */ + { 8, 0x29, 40 }, /* 0010 1001 */ + { 8, 0x2A, 41 }, /* 0010 1010 */ + { 8, 0x2B, 42 }, /* 0010 1011 */ + { 8, 0x2C, 43 }, /* 0010 1100 */ + { 8, 0x2D, 44 }, /* 0010 1101 */ + { 8, 0x4, 45 }, /* 0000 0100 */ + { 8, 0x5, 46 }, /* 0000 0101 */ + { 8, 0xA, 47 }, /* 0000 1010 */ + { 8, 0xB, 48 }, /* 0000 1011 */ + { 8, 0x52, 49 }, /* 0101 0010 */ + { 8, 0x53, 50 }, /* 0101 0011 */ + { 8, 0x54, 51 }, /* 0101 0100 */ + { 8, 0x55, 52 }, /* 0101 0101 */ + { 8, 0x24, 53 }, /* 0010 0100 */ + { 8, 0x25, 54 }, /* 0010 0101 */ + { 8, 0x58, 55 }, /* 0101 1000 */ + { 8, 0x59, 56 }, /* 0101 1001 */ + { 8, 0x5A, 57 }, /* 0101 1010 */ + { 8, 0x5B, 58 }, /* 0101 1011 */ + { 8, 0x4A, 59 }, /* 0100 1010 */ + { 8, 0x4B, 60 }, /* 0100 1011 */ + { 8, 0x32, 61 }, /* 0011 0010 */ + { 8, 0x33, 62 }, /* 0011 0011 */ + { 8, 0x34, 63 }, /* 0011 0100 */ + { 5, 0x1B, 64 }, /* 1101 1 */ + { 5, 0x12, 128 }, /* 1001 0 */ + { 6, 0x17, 192 }, /* 0101 11 */ + { 7, 0x37, 256 }, /* 0110 111 */ + { 8, 0x36, 320 }, /* 0011 0110 */ + { 8, 0x37, 384 }, /* 0011 0111 */ + { 8, 0x64, 448 }, /* 0110 0100 */ + { 8, 0x65, 512 }, /* 0110 0101 */ + { 8, 0x68, 576 }, /* 0110 1000 */ + { 8, 0x67, 640 }, /* 0110 0111 */ + { 9, 0xCC, 704 }, /* 0110 0110 0 */ + { 9, 0xCD, 768 }, /* 0110 0110 1 */ + { 9, 0xD2, 832 }, /* 0110 1001 0 */ + { 9, 0xD3, 896 }, /* 0110 1001 1 */ + { 9, 0xD4, 960 }, /* 0110 1010 0 */ + { 9, 0xD5, 1024 }, /* 0110 1010 1 */ + { 9, 0xD6, 1088 }, /* 0110 1011 0 */ + { 9, 0xD7, 1152 }, /* 0110 1011 1 */ + { 9, 0xD8, 1216 }, /* 0110 1100 0 */ + { 9, 0xD9, 1280 }, /* 0110 1100 1 */ + { 9, 0xDA, 1344 }, /* 0110 1101 0 */ + { 9, 0xDB, 1408 }, /* 0110 1101 1 */ + { 9, 0x98, 1472 }, /* 0100 1100 0 */ + { 9, 0x99, 1536 }, /* 0100 1100 1 */ + { 9, 0x9A, 1600 }, /* 0100 1101 0 */ + { 6, 0x18, 1664 }, /* 0110 00 */ + { 9, 0x9B, 1728 }, /* 0100 1101 1 */ + { 11, 0x8, 1792 }, /* 0000 0001 000 */ + { 11, 0xC, 1856 }, /* 0000 0001 100 */ + { 11, 0xD, 1920 }, /* 0000 0001 101 */ + { 12, 0x12, 1984 }, /* 0000 0001 0010 */ + { 12, 0x13, 2048 }, /* 0000 0001 0011 */ + { 12, 0x14, 2112 }, /* 0000 0001 0100 */ + { 12, 0x15, 2176 }, /* 0000 0001 0101 */ + { 12, 0x16, 2240 }, /* 0000 0001 0110 */ + { 12, 0x17, 2304 }, /* 0000 0001 0111 */ + { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ + { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ + { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ + { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ + { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ + { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ + { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ + { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ + { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ +}; + +const tableentry TIFFFaxBlackCodes[] = { + { 10, 0x37, 0 }, /* 0000 1101 11 */ + { 3, 0x2, 1 }, /* 010 */ + { 2, 0x3, 2 }, /* 11 */ + { 2, 0x2, 3 }, /* 10 */ + { 3, 0x3, 4 }, /* 011 */ + { 4, 0x3, 5 }, /* 0011 */ + { 4, 0x2, 6 }, /* 0010 */ + { 5, 0x3, 7 }, /* 0001 1 */ + { 6, 0x5, 8 }, /* 0001 01 */ + { 6, 0x4, 9 }, /* 0001 00 */ + { 7, 0x4, 10 }, /* 0000 100 */ + { 7, 0x5, 11 }, /* 0000 101 */ + { 7, 0x7, 12 }, /* 0000 111 */ + { 8, 0x4, 13 }, /* 0000 0100 */ + { 8, 0x7, 14 }, /* 0000 0111 */ + { 9, 0x18, 15 }, /* 0000 1100 0 */ + { 10, 0x17, 16 }, /* 0000 0101 11 */ + { 10, 0x18, 17 }, /* 0000 0110 00 */ + { 10, 0x8, 18 }, /* 0000 0010 00 */ + { 11, 0x67, 19 }, /* 0000 1100 111 */ + { 11, 0x68, 20 }, /* 0000 1101 000 */ + { 11, 0x6C, 21 }, /* 0000 1101 100 */ + { 11, 0x37, 22 }, /* 0000 0110 111 */ + { 11, 0x28, 23 }, /* 0000 0101 000 */ + { 11, 0x17, 24 }, /* 0000 0010 111 */ + { 11, 0x18, 25 }, /* 0000 0011 000 */ + { 12, 0xCA, 26 }, /* 0000 1100 1010 */ + { 12, 0xCB, 27 }, /* 0000 1100 1011 */ + { 12, 0xCC, 28 }, /* 0000 1100 1100 */ + { 12, 0xCD, 29 }, /* 0000 1100 1101 */ + { 12, 0x68, 30 }, /* 0000 0110 1000 */ + { 12, 0x69, 31 }, /* 0000 0110 1001 */ + { 12, 0x6A, 32 }, /* 0000 0110 1010 */ + { 12, 0x6B, 33 }, /* 0000 0110 1011 */ + { 12, 0xD2, 34 }, /* 0000 1101 0010 */ + { 12, 0xD3, 35 }, /* 0000 1101 0011 */ + { 12, 0xD4, 36 }, /* 0000 1101 0100 */ + { 12, 0xD5, 37 }, /* 0000 1101 0101 */ + { 12, 0xD6, 38 }, /* 0000 1101 0110 */ + { 12, 0xD7, 39 }, /* 0000 1101 0111 */ + { 12, 0x6C, 40 }, /* 0000 0110 1100 */ + { 12, 0x6D, 41 }, /* 0000 0110 1101 */ + { 12, 0xDA, 42 }, /* 0000 1101 1010 */ + { 12, 0xDB, 43 }, /* 0000 1101 1011 */ + { 12, 0x54, 44 }, /* 0000 0101 0100 */ + { 12, 0x55, 45 }, /* 0000 0101 0101 */ + { 12, 0x56, 46 }, /* 0000 0101 0110 */ + { 12, 0x57, 47 }, /* 0000 0101 0111 */ + { 12, 0x64, 48 }, /* 0000 0110 0100 */ + { 12, 0x65, 49 }, /* 0000 0110 0101 */ + { 12, 0x52, 50 }, /* 0000 0101 0010 */ + { 12, 0x53, 51 }, /* 0000 0101 0011 */ + { 12, 0x24, 52 }, /* 0000 0010 0100 */ + { 12, 0x37, 53 }, /* 0000 0011 0111 */ + { 12, 0x38, 54 }, /* 0000 0011 1000 */ + { 12, 0x27, 55 }, /* 0000 0010 0111 */ + { 12, 0x28, 56 }, /* 0000 0010 1000 */ + { 12, 0x58, 57 }, /* 0000 0101 1000 */ + { 12, 0x59, 58 }, /* 0000 0101 1001 */ + { 12, 0x2B, 59 }, /* 0000 0010 1011 */ + { 12, 0x2C, 60 }, /* 0000 0010 1100 */ + { 12, 0x5A, 61 }, /* 0000 0101 1010 */ + { 12, 0x66, 62 }, /* 0000 0110 0110 */ + { 12, 0x67, 63 }, /* 0000 0110 0111 */ + { 10, 0xF, 64 }, /* 0000 0011 11 */ + { 12, 0xC8, 128 }, /* 0000 1100 1000 */ + { 12, 0xC9, 192 }, /* 0000 1100 1001 */ + { 12, 0x5B, 256 }, /* 0000 0101 1011 */ + { 12, 0x33, 320 }, /* 0000 0011 0011 */ + { 12, 0x34, 384 }, /* 0000 0011 0100 */ + { 12, 0x35, 448 }, /* 0000 0011 0101 */ + { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */ + { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */ + { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */ + { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */ + { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */ + { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */ + { 13, 0x72, 896 }, /* 0000 0011 1001 0 */ + { 13, 0x73, 960 }, /* 0000 0011 1001 1 */ + { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */ + { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */ + { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */ + { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */ + { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */ + { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */ + { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */ + { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */ + { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */ + { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */ + { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */ + { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */ + { 11, 0x8, 1792 }, /* 0000 0001 000 */ + { 11, 0xC, 1856 }, /* 0000 0001 100 */ + { 11, 0xD, 1920 }, /* 0000 0001 101 */ + { 12, 0x12, 1984 }, /* 0000 0001 0010 */ + { 12, 0x13, 2048 }, /* 0000 0001 0011 */ + { 12, 0x14, 2112 }, /* 0000 0001 0100 */ + { 12, 0x15, 2176 }, /* 0000 0001 0101 */ + { 12, 0x16, 2240 }, /* 0000 0001 0110 */ + { 12, 0x17, 2304 }, /* 0000 0001 0111 */ + { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ + { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ + { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ + { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ + { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ + { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ + { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ + { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ + { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ +}; +#else +extern const tableentry TIFFFaxWhiteCodes[]; +extern const tableentry TIFFFaxBlackCodes[]; +#endif +#endif /* _T4_ */ diff --git a/libtiff/tif_acorn.c b/libtiff/tif_acorn.c new file mode 100644 index 00000000..ce8c14ce --- /dev/null +++ b/libtiff/tif_acorn.c @@ -0,0 +1,519 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_acorn.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library RISC OS specific Routines. + * Developed out of the Unix version. + * Peter Greenham, May 1995 + */ +#include "tiffiop.h" +#include +#include + +/* +Low-level file handling +~~~~~~~~~~~~~~~~~~~~~~~ +The functions in osfcn.h are unavailable when compiling under C, as it's a +C++ header. Therefore they have been implemented here. + +Now, why have I done it this way? + +The definitive API library for RISC OS is Jonathan Coxhead's OSLib, which +uses heavily optimised ARM assembler or even plain inline SWI calls for +maximum performance and minimum runtime size. However, I don't want to make +LIBTIFF need that to survive. Therefore I have also emulated the functions +using macros to _swi() and _swix() defined in the swis.h header, and +borrowing types from kernel.h, which is less efficient but doesn't need any +third-party libraries. + */ + +#ifdef INCLUDE_OSLIB + +#include "osfile.h" +#include "osgbpb.h" +#include "osargs.h" +#include "osfind.h" + +#else + +/* OSLIB EMULATION STARTS */ + +#include "kernel.h" +#include "swis.h" + +/* From oslib:types.h */ +typedef unsigned int bits; +typedef unsigned char byte; +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif +#ifndef SKIP +#define SKIP 0 +#endif + +/* From oslib:os.h */ +typedef _kernel_oserror os_error; +typedef byte os_f; + +/* From oslib:osfile.h */ +#undef OS_File +#define OS_File 0x8 + +/* From oslib:osgbpb.h */ +#undef OS_GBPB +#define OS_GBPB 0xC +#undef OSGBPB_Write +#define OSGBPB_Write 0x2 +#undef OSGBPB_Read +#define OSGBPB_Read 0x4 + +extern os_error *xosgbpb_write (os_f file, + byte *data, + int size, + int *unwritten); +extern int osgbpb_write (os_f file, + byte *data, + int size); + +#define xosgbpb_write(file, data, size, unwritten) \ + (os_error*) _swix(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_IN(4)|_OUT(3), \ + OSGBPB_WriteAt, \ + file, \ + data, \ + size, \ + unwritten) + +#define osgbpb_write(file, data, size) \ + _swi(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_RETURN(3), \ + OSGBPB_Write, \ + file, \ + data, \ + size) + +extern os_error *xosgbpb_read (os_f file, + byte *buffer, + int size, + int *unread); +extern int osgbpb_read (os_f file, + byte *buffer, + int size); + +#define xosgbpb_read(file, buffer, size, unread) \ + (os_error*) _swix(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_OUT(3), \ + OSGBPB_Read, \ + file, \ + buffer, \ + size, \ + unread) + +#define osgbpb_read(file, buffer, size) \ + _swi(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_RETURN(3), \ + OSGBPB_Read, \ + file, \ + buffer, \ + size) + +/* From oslib:osfind.h */ +#undef OS_Find +#define OS_Find 0xD +#undef OSFind_Openin +#define OSFind_Openin 0x40 +#undef OSFind_Openout +#define OSFind_Openout 0x80 +#undef OSFind_Openup +#define OSFind_Openup 0xC0 +#undef OSFind_Close +#define OSFind_Close 0x0 + +#define xosfind_open(reason, file_name, path, file) \ + (os_error*) _swix(OS_Find, _IN(0)|_IN(1)|_IN(2)|_OUT(0), \ + reason, file_name, path, file) + +#define osfind_open(reason, file_name, path) \ + (os_f) _swi(OS_Find, _IN(0)|_IN(1)|_IN(2)|_RETURN(0), \ + reason, file_name, path) + +extern os_error *xosfind_openin (bits flags, + char *file_name, + char *path, + os_f *file); +extern os_f osfind_openin (bits flags, + char *file_name, + char *path); + +#define xosfind_openin(flags, file_name, path, file) \ + xosfind_open(flags | OSFind_Openin, file_name, path, file) + +#define osfind_openin(flags, file_name, path) \ + osfind_open(flags | OSFind_Openin, file_name, path) + +extern os_error *xosfind_openout (bits flags, + char *file_name, + char *path, + os_f *file); +extern os_f osfind_openout (bits flags, + char *file_name, + char *path); + +#define xosfind_openout(flags, file_name, path, file) \ + xosfind_open(flags | OSFind_Openout, file_name, path, file) + +#define osfind_openout(flags, file_name, path) \ + osfind_open(flags | OSFind_Openout, file_name, path) + +extern os_error *xosfind_openup (bits flags, + char *file_name, + char *path, + os_f *file); +extern os_f osfind_openup (bits flags, + char *file_name, + char *path); + +#define xosfind_openup(flags, file_name, path, file) \ + xosfind_open(flags | OSFind_Openup, file_name, path, file) + +#define osfind_openup(flags, file_name, path) \ + osfind_open(flags | OSFind_Openup, file_name, path) + +extern os_error *xosfind_close (os_f file); +extern void osfind_close (os_f file); + +#define xosfind_close(file) \ + (os_error*) _swix(OS_Find, _IN(0)|_IN(1), \ + OSFind_Close, \ + file) + +#define osfind_close(file) \ + (void) _swi(OS_Find, _IN(0)|_IN(1), \ + OSFind_Close, \ + file) + +/* From oslib:osargs.h */ +#undef OS_Args +#define OS_Args 0x9 +#undef OSArgs_ReadPtr +#define OSArgs_ReadPtr 0x0 +#undef OSArgs_SetPtr +#define OSArgs_SetPtr 0x1 +#undef OSArgs_ReadExt +#define OSArgs_ReadExt 0x2 + +extern os_error *xosargs_read_ptr (os_f file, + int *ptr); +extern int osargs_read_ptr (os_f file); + +#define xosargs_read_ptr(file, ptr) \ + (os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_OUT(2), \ + OSArgs_ReadPtr, \ + file, \ + ptr) + +#define osargs_read_ptr(file) \ + _swi(OS_Args, _IN(0)|_IN(1)|_RETURN(2), \ + OSArgs_ReadPtr, \ + file) + +extern os_error *xosargs_set_ptr (os_f file, + int ptr); +extern void osargs_set_ptr (os_f file, + int ptr); + +#define xosargs_set_ptr(file, ptr) \ + (os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_IN(2), \ + OSArgs_SetPtr, \ + file, \ + ptr) + +#define osargs_set_ptr(file, ptr) \ + (void) _swi(OS_Args, _IN(0)|_IN(1)|_IN(2), \ + OSArgs_SetPtr, \ + file, \ + ptr) + +extern os_error *xosargs_read_ext (os_f file, + int *ext); +extern int osargs_read_ext (os_f file); + +#define xosargs_read_ext(file, ext) \ + (os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_OUT(2), \ + OSArgs_ReadExt, \ + file, \ + ext) + +#define osargs_read_ext(file) \ + _swi(OS_Args, _IN(0)|_IN(1)|_RETURN(2), \ + OSArgs_ReadExt, \ + file) + +/* OSLIB EMULATION ENDS */ + +#endif + +#ifndef __osfcn_h +/* Will be set or not during tiffcomp.h */ +/* You get this to compile under C++? Please say how! */ + +extern int open(const char* name, int flags, int mode) +{ + /* From what I can tell, should return <0 for failure */ + os_error* e = (os_error*) 1; /* Cheeky way to use a pointer eh? :-) */ + os_f file = (os_f) -1; + + flags = flags; + + switch(mode) + { + case O_RDONLY: + { + e = xosfind_openin(SKIP, name, SKIP, &file); + break; + } + case O_WRONLY: + case O_RDWR|O_CREAT: + case O_RDWR|O_CREAT|O_TRUNC: + { + e = xosfind_openout(SKIP, name, SKIP, &file); + break; + } + case O_RDWR: + { + e = xosfind_openup(SKIP, name, SKIP, &file); + break; + } + } + if (e) + { + file = (os_f) -1; + } + return (file); +} + +extern int close(int fd) +{ + return ((int) xosfind_close((os_f) fd)); +} + +extern int write(int fd, const char *buf, int nbytes) +{ + /* Returns number of bytes written */ + return (nbytes - osgbpb_write((os_f) fd, (const byte*) buf, nbytes)); +} + +extern int read(int fd, char *buf, int nbytes) +{ + /* Returns number of bytes read */ + return (nbytes - osgbpb_read((os_f) fd, (byte*) buf, nbytes)); +} + +extern off_t lseek(int fd, off_t offset, int whence) +{ + int absolute = 0; + + switch (whence) + { + case SEEK_SET: + { + absolute = (int) offset; + break; + } + case SEEK_CUR: + { + absolute = osargs_read_ptr((os_f) fd) + (int) offset; + break; + } + case SEEK_END: + { + absolute = osargs_read_ext((os_f) fd) + (int) offset; + break; + } + } + + osargs_set_ptr((os_f) fd, absolute); + + return ((off_t) osargs_read_ptr((os_f) fd)); +} +#endif + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return ((tsize_t) read((int) fd, buf, (size_t) size)); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return ((tsize_t) write((int) fd, buf, (size_t) size)); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + return ((toff_t) lseek((int) fd, (off_t) off, whence)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (close((int) fd)); +} + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + return (lseek((int) fd, SEEK_END, SEEK_SET)); +} + +#ifdef HAVE_MMAP +#error "I didn't know Acorn had that!" +#endif + +/* !HAVE_MMAP */ +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + (void) fd; (void) pbase; (void) psize; + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ + (void) fd; (void) base; (void) size; +} + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + _tiffMapProc, _tiffUnmapProc); + if (tif) + { + tif->tif_fd = fd; + } + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + + m = _TIFFgetMode(mode, module); + + if (m == -1) + { + return ((TIFF*) 0); + } + + fd = open(name, 0, m); + + if (fd < 0) + { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF *)0); + } + return (TIFFFdOpen(fd, name, mode)); +} + +void* +_TIFFmalloc(tsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(tdata_t p) +{ + free(p); +} + +void* +_TIFFrealloc(tdata_t p, tsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(tdata_t p, int v, tsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +static void +acornWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + { + fprintf(stderr, "%s: ", module); + } + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFwarningHandler = acornWarningHandler; + +static void +acornErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + { + fprintf(stderr, "%s: ", module); + } + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFerrorHandler = acornErrorHandler; diff --git a/libtiff/tif_apple.c b/libtiff/tif_apple.c new file mode 100644 index 00000000..0186de37 --- /dev/null +++ b/libtiff/tif_apple.c @@ -0,0 +1,256 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_apple.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library Macintosh-specific routines. + * + * These routines use only Toolbox and high-level File Manager traps. + * They make no calls to the THINK C "unix" compatibility library. Also, + * malloc is not used directly but it is still referenced internally by + * the ANSI library in rare cases. Heap fragmentation by the malloc ring + * buffer is therefore minimized. + * + * O_RDONLY and O_RDWR are treated identically here. The tif_mode flag is + * checked in TIFFWriteCheck(). + * + * Create below fills in a blank creator signature and sets the file type + * to 'TIFF'. It is much better for the application to do this by Create'ing + * the file first and TIFFOpen'ing it later. + */ + +#include "tiffiop.h" +#include +#include +#include + +#if defined(__PPCC__) || defined(__SC__) || defined(__MRC__) || defined(applec) +#define CtoPstr c2pstr +#endif + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (FSRead((short) fd, (long*) &size, (char*) buf) == noErr ? + size : (tsize_t) -1); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (FSWrite((short) fd, (long*) &size, (char*) buf) == noErr ? + size : (tsize_t) -1); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + long fpos, size; + + if (GetEOF((short) fd, &size) != noErr) + return EOF; + (void) GetFPos((short) fd, &fpos); + + switch (whence) { + case SEEK_CUR: + if (off + fpos > size) + SetEOF((short) fd, off + fpos); + if (SetFPos((short) fd, fsFromMark, off) != noErr) + return EOF; + break; + case SEEK_END: + if (off > 0) + SetEOF((short) fd, off + size); + if (SetFPos((short) fd, fsFromStart, off + size) != noErr) + return EOF; + break; + case SEEK_SET: + if (off > size) + SetEOF((short) fd, off); + if (SetFPos((short) fd, fsFromStart, off) != noErr) + return EOF; + break; + } + + return (toff_t)(GetFPos((short) fd, &fpos) == noErr ? fpos : EOF); +} + +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (FSClose((short) fd)); +} + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + long size; + + if (GetEOF((short) fd, &size) != noErr) { + TIFFError("_tiffSizeProc", "%s: Cannot get file size"); + return (-1L); + } + return ((toff_t) size); +} + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, + _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + Str255 pname; + FInfo finfo; + short fref; + OSErr err; + + strcpy((char*) pname, name); + CtoPstr((char*) pname); + + switch (_TIFFgetMode(mode, module)) { + default: + return ((TIFF*) 0); + case O_RDWR | O_CREAT | O_TRUNC: + if (GetFInfo(pname, 0, &finfo) == noErr) + FSDelete(pname, 0); + /* fall through */ + case O_RDWR | O_CREAT: + if ((err = GetFInfo(pname, 0, &finfo)) == fnfErr) { + if (Create(pname, 0, ' ', 'TIFF') != noErr) + goto badCreate; + if (FSOpen(pname, 0, &fref) != noErr) + goto badOpen; + } else if (err == noErr) { + if (FSOpen(pname, 0, &fref) != noErr) + goto badOpen; + } else + goto badOpen; + break; + case O_RDONLY: + case O_RDWR: + if (FSOpen(pname, 0, &fref) != noErr) + goto badOpen; + break; + } + return (TIFFFdOpen((int) fref, name, mode)); +badCreate: + TIFFError(module, "%s: Cannot create", name); + return ((TIFF*) 0); +badOpen: + TIFFError(module, "%s: Cannot open", name); + return ((TIFF*) 0); +} + +void +_TIFFmemset(tdata_t p, int v, tsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +tdata_t +_TIFFmalloc(tsize_t s) +{ + return (NewPtr((size_t) s)); +} + +void +_TIFFfree(tdata_t p) +{ + DisposePtr(p); +} + +tdata_t +_TIFFrealloc(tdata_t p, tsize_t s) +{ + Ptr n = p; + + SetPtrSize(p, (size_t) s); + if (MemError() && (n = NewPtr((size_t) s)) != NULL) { + BlockMove(p, n, GetPtrSize(p)); + DisposePtr(p); + } + return ((tdata_t) n); +} + +static void +appleWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFwarningHandler = appleWarningHandler; + +static void +appleErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFerrorHandler = appleErrorHandler; diff --git a/libtiff/tif_atari.c b/libtiff/tif_atari.c new file mode 100644 index 00000000..01817de3 --- /dev/null +++ b/libtiff/tif_atari.c @@ -0,0 +1,243 @@ +/* "$Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_atari.c,v 1.1 1999-07-27 21:50:27 mike Exp $" */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library ATARI-specific Routines. + */ +#include "tiffiop.h" +#if defined(__TURBOC__) +#include +#include +#else +#include +#include +#endif + +#ifndef O_ACCMODE +#define O_ACCMODE 3 +#endif + +#include + +#define AEFILNF -33 + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + long r; + + r = Fread((int) fd, size, buf); + if (r < 0) { + errno = (int)-r; + r = -1; + } + return r; +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + long r; + + r = Fwrite((int) fd, size, buf); + if (r < 0) { + errno = (int)-r; + r = -1; + } + return r; +} + +static toff_t +_tiffSeekProc(thandle_t fd, off_t off, int whence) +{ + char buf[256]; + long current_off, expected_off, new_off; + + if (whence == SEEK_END || off <= 0) + return Fseek(off, (int) fd, whence); + current_off = Fseek(0, (int) fd, SEEK_CUR); /* find out where we are */ + if (whence == SEEK_SET) + expected_off = off; + else + expected_off = off + current_off; + new_off = Fseek(off, (int) fd, whence); + if (new_off == expected_off) + return new_off; + /* otherwise extend file -- zero filling the hole */ + if (new_off < 0) /* error? */ + new_off = Fseek(0, (int) fd, SEEK_END); /* go to eof */ + _TIFFmemset(buf, 0, sizeof(buf)); + while (expected_off > new_off) { + off = expected_off - new_off; + if (off > sizeof(buf)) + off = sizeof(buf); + if ((current_off = Fwrite((int) fd, off, buf)) != off) + return (current_off > 0) ? + new_off + current_off : new_off; + new_off += off; + } + return new_off; +} + +static int +_tiffCloseProc(thandle_t fd) +{ + long r; + + r = Fclose((int) fd); + if (r < 0) { + errno = (int)-r; + r = -1; + } + return (int)r; +} + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + long pos, eof; + + pos = Fseek(0, (int) fd, SEEK_CUR); + eof = Fseek(0, (int) fd, SEEK_END); + Fseek(pos, (int) fd, SEEK_SET); + return eof; +} + +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ +} + +/* +* Open a TIFF file descriptor for read/writing. +*/ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, + _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* +* Open a TIFF file for read/writing. +*/ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m; + long fd; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); + if (m & O_TRUNC) { + fd = Fcreate(name, 0); + } else { + fd = Fopen(name, m & O_ACCMODE); + if (fd == AEFILNF && m & O_CREAT) + fd = Fcreate(name, 0); + } + if (fd < 0) + errno = (int)fd; + if (fd < 0) { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF*)0); + } + return (TIFFFdOpen(fd, name, mode)); +} + +#include + +tdata_t +_TIFFmalloc(tsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(tdata_t p) +{ + free(p); +} + +tdata_t +_TIFFrealloc(tdata_t p, tsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(tdata_t p, int v, size_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, size_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +static void +atariWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFwarningHandler = atariWarningHandler; + +static void +atariErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFerrorHandler = atariErrorHandler; diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c new file mode 100644 index 00000000..7f443d8b --- /dev/null +++ b/libtiff/tif_aux.c @@ -0,0 +1,203 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_aux.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Auxiliary Support Routines. + */ +#include "tiffiop.h" + +#ifdef COLORIMETRY_SUPPORT +#include + +static void +TIFFDefaultTransferFunction(TIFFDirectory* td) +{ + uint16 **tf = td->td_transferfunction; + long i, n = 1<td_bitspersample; + + tf[0] = (uint16 *)_TIFFmalloc(n * sizeof (uint16)); + tf[0][0] = 0; + for (i = 1; i < n; i++) { + double t = (double)i/((double) n-1.); + tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5); + } + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + tf[1] = (uint16 *)_TIFFmalloc(n * sizeof (uint16)); + _TIFFmemcpy(tf[1], tf[0], n * sizeof (uint16)); + tf[2] = (uint16 *)_TIFFmalloc(n * sizeof (uint16)); + _TIFFmemcpy(tf[2], tf[0], n * sizeof (uint16)); + } +} + +static void +TIFFDefaultRefBlackWhite(TIFFDirectory* td) +{ + int i; + + td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float)); + for (i = 0; i < 3; i++) { + td->td_refblackwhite[2*i+0] = 0; + td->td_refblackwhite[2*i+1] = (float)((1L<td_bitspersample)-1L); + } +} +#endif + +/* + * Like TIFFGetField, but return any default + * value if the tag is not present in the directory. + * + * NB: We use the value in the directory, rather than + * explcit values so that defaults exist only one + * place in the library -- in TIFFDefaultDirectory. + */ +int +TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (TIFFVGetField(tif, tag, ap)) + return (1); + switch (tag) { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32 *) = td->td_subfiletype; + return (1); + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16 *) = td->td_bitspersample; + return (1); + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16 *) = td->td_threshholding; + return (1); + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16 *) = td->td_fillorder; + return (1); + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16 *) = td->td_orientation; + return (1); + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16 *) = td->td_samplesperpixel; + return (1); + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32 *) = td->td_rowsperstrip; + return (1); + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16 *) = td->td_minsamplevalue; + return (1); + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16 *) = td->td_maxsamplevalue; + return (1); + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16 *) = td->td_planarconfig; + return (1); + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16 *) = td->td_resolutionunit; + return (1); +#ifdef CMYK_SUPPORT + case TIFFTAG_DOTRANGE: + *va_arg(ap, uint16 *) = 0; + *va_arg(ap, uint16 *) = (1<td_bitspersample)-1; + return (1); + case TIFFTAG_INKSET: + *va_arg(ap, uint16 *) = td->td_inkset; + return (1); + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16 *) = td->td_ninks; + return (1); +#endif + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16 *) = td->td_extrasamples; + *va_arg(ap, uint16 **) = td->td_sampleinfo; + return (1); + case TIFFTAG_MATTEING: + *va_arg(ap, uint16 *) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + return (1); + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32 *) = td->td_tiledepth; + return (1); + case TIFFTAG_DATATYPE: + *va_arg(ap, uint16 *) = td->td_sampleformat-1; + return (1); + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32 *) = td->td_imagedepth; + return (1); +#ifdef YCBCR_SUPPORT + case TIFFTAG_YCBCRCOEFFICIENTS: + if (!td->td_ycbcrcoeffs) { + td->td_ycbcrcoeffs = (float *) + _TIFFmalloc(3*sizeof (float)); + /* defaults are from CCIR Recommendation 601-1 */ + td->td_ycbcrcoeffs[0] = 0.299f; + td->td_ycbcrcoeffs[1] = 0.587f; + td->td_ycbcrcoeffs[2] = 0.114f; + } + *va_arg(ap, float **) = td->td_ycbcrcoeffs; + return (1); + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1]; + return (1); + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16 *) = td->td_ycbcrpositioning; + return (1); +#endif +#ifdef COLORIMETRY_SUPPORT + case TIFFTAG_TRANSFERFUNCTION: + if (!td->td_transferfunction[0]) + TIFFDefaultTransferFunction(td); + *va_arg(ap, uint16 **) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + *va_arg(ap, uint16 **) = td->td_transferfunction[1]; + *va_arg(ap, uint16 **) = td->td_transferfunction[2]; + } + return (1); + case TIFFTAG_REFERENCEBLACKWHITE: + if (!td->td_refblackwhite) + TIFFDefaultRefBlackWhite(td); + *va_arg(ap, float **) = td->td_refblackwhite; + return (1); +#endif + } + return (0); +} + +/* + * Like TIFFGetField, but return any default + * value if the tag is not present in the directory. + */ +int +TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...) +{ + int ok; + va_list ap; + + va_start(ap, tag); + ok = TIFFVGetFieldDefaulted(tif, tag, ap); + va_end(ap); + return (ok); +} diff --git a/libtiff/tif_close.c b/libtiff/tif_close.c new file mode 100644 index 00000000..7204d3ec --- /dev/null +++ b/libtiff/tif_close.c @@ -0,0 +1,50 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_close.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +void +TIFFClose(TIFF* tif) +{ + if (tif->tif_mode != O_RDONLY) + /* + * Flush buffered data and directory (if dirty). + */ + TIFFFlush(tif); + (*tif->tif_cleanup)(tif); + TIFFFreeDirectory(tif); + if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER)) + _TIFFfree(tif->tif_rawdata); + if (isMapped(tif)) + TIFFUnmapFileContents(tif, tif->tif_base, tif->tif_size); + (void) TIFFCloseFile(tif); + if (tif->tif_fieldinfo) + _TIFFfree(tif->tif_fieldinfo); + _TIFFfree(tif); +} diff --git a/libtiff/tif_codec.c b/libtiff/tif_codec.c new file mode 100644 index 00000000..cfd5bccf --- /dev/null +++ b/libtiff/tif_codec.c @@ -0,0 +1,116 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_codec.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Builtin Compression Scheme Configuration Support. + */ +#include "tiffiop.h" + +static int NotConfigured(TIFF*, int); + +#ifndef LZW_SUPPORT +#define TIFFInitLZW NotConfigured +#endif +#ifndef PACKBITS_SUPPORT +#define TIFFInitPackbits NotConfigured +#endif +#ifndef THUNDER_SUPPORT +#define TIFFInitThunderScan NotConfigured +#endif +#ifndef NEXT_SUPPORT +#define TIFFInitNeXT NotConfigured +#endif +#ifndef JPEG_SUPPORT +#define TIFFInitJPEG NotConfigured +#endif +#ifndef OJPEG_SUPPORT +#define TIFFInitOJPEG NotConfigured +#endif +#ifndef CCITT_SUPPORT +#define TIFFInitCCITTRLE NotConfigured +#define TIFFInitCCITTRLEW NotConfigured +#define TIFFInitCCITTFax3 NotConfigured +#define TIFFInitCCITTFax4 NotConfigured +#endif +#ifndef JBIG_SUPPORT +#define TIFFInitJBIG NotConfigured +#endif +#ifndef ZIP_SUPPORT +#define TIFFInitZIP NotConfigured +#endif +#ifndef PIXARLOG_SUPPORT +#define TIFFInitPixarLog NotConfigured +#endif +#ifndef LOGLUV_SUPPORT +#define TIFFInitSGILog NotConfigured +#endif + +/* + * Compression schemes statically built into the library. + */ +#ifdef VMS +const TIFFCodec _TIFFBuiltinCODECS[] = { +#else +TIFFCodec _TIFFBuiltinCODECS[] = { +#endif + { "None", COMPRESSION_NONE, TIFFInitDumpMode }, + { "LZW", COMPRESSION_LZW, TIFFInitLZW }, + { "PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits }, + { "ThunderScan", COMPRESSION_THUNDERSCAN,TIFFInitThunderScan }, + { "NeXT", COMPRESSION_NEXT, TIFFInitNeXT }, + { "JPEG", COMPRESSION_JPEG, TIFFInitJPEG }, + { "Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG }, + { "CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE }, + { "CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW }, + { "CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3 }, + { "CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4 }, + { "ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG }, + { "Deflate", COMPRESSION_DEFLATE, TIFFInitZIP }, + { "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog }, + { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog }, + { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog }, + { NULL } +}; + +static int +_notConfigured(TIFF* tif) +{ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + + TIFFError(tif->tif_name, + "%s compression support is not configured", c->name); + return (0); +} + +static int +NotConfigured(TIFF* tif, int scheme) +{ + tif->tif_setupdecode = _notConfigured; + tif->tif_setupencode = _notConfigured; + return (1); +} diff --git a/libtiff/tif_compress.c b/libtiff/tif_compress.c new file mode 100644 index 00000000..0dd33dea --- /dev/null +++ b/libtiff/tif_compress.c @@ -0,0 +1,223 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_compress.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Compression Scheme Configuration Support. + */ +#include "tiffiop.h" + +static int +TIFFNoEncode(TIFF* tif, char* method) +{ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + + if (c) + TIFFError(tif->tif_name, "%s %s encoding is not implemented", + c->name, method); + else + TIFFError(tif->tif_name, + "Compression scheme %u %s encoding is not implemented", + tif->tif_dir.td_compression, method); + return (-1); +} + +int +_TIFFNoRowEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoEncode(tif, "scanline")); +} + +int +_TIFFNoStripEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoEncode(tif, "strip")); +} + +int +_TIFFNoTileEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoEncode(tif, "tile")); +} + +static int +TIFFNoDecode(TIFF* tif, char* method) +{ + const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + + if (c) + TIFFError(tif->tif_name, "%s %s decoding is not implemented", + c->name, method); + else + TIFFError(tif->tif_name, + "Compression scheme %u %s decoding is not implemented", + tif->tif_dir.td_compression, method); + return (-1); +} + +int +_TIFFNoRowDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoDecode(tif, "scanline")); +} + +int +_TIFFNoStripDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoDecode(tif, "strip")); +} + +int +_TIFFNoTileDecode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) pp; (void) cc; (void) s; + return (TIFFNoDecode(tif, "tile")); +} + +int +_TIFFNoSeek(TIFF* tif, uint32 off) +{ + (void) off; + TIFFError(tif->tif_name, + "Compression algorithm does not support random access"); + return (0); +} + +int +_TIFFNoPreCode(TIFF* tif, tsample_t s) +{ + (void) tif; (void) s; + return (1); +} + +static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); } +static void _TIFFvoid(TIFF* tif) { (void) tif; } + +void +_TIFFSetDefaultCompressionState(TIFF* tif) +{ + tif->tif_setupdecode = _TIFFtrue; + tif->tif_predecode = _TIFFNoPreCode; + tif->tif_decoderow = _TIFFNoRowDecode; + tif->tif_decodestrip = _TIFFNoStripDecode; + tif->tif_decodetile = _TIFFNoTileDecode; + tif->tif_setupencode = _TIFFtrue; + tif->tif_preencode = _TIFFNoPreCode; + tif->tif_postencode = _TIFFtrue; + tif->tif_encoderow = _TIFFNoRowEncode; + tif->tif_encodestrip = _TIFFNoStripEncode; + tif->tif_encodetile = _TIFFNoTileEncode; + tif->tif_close = _TIFFvoid; + tif->tif_seek = _TIFFNoSeek; + tif->tif_cleanup = _TIFFvoid; + tif->tif_defstripsize = _TIFFDefaultStripSize; + tif->tif_deftilesize = _TIFFDefaultTileSize; + tif->tif_flags &= ~TIFF_NOBITREV; +} + +int +TIFFSetCompressionScheme(TIFF* tif, int scheme) +{ + const TIFFCodec *c = TIFFFindCODEC(scheme); + + _TIFFSetDefaultCompressionState(tif); + /* + * Don't treat an unknown compression scheme as an error. + * This permits applications to open files with data that + * the library does not have builtin support for, but which + * may still be meaningful. + */ + return (c ? (*c->init)(tif, scheme) : 1); +} + +/* + * Other compression schemes may be registered. Registered + * schemes can also override the builtin versions provided + * by this library. + */ +typedef struct _codec { + struct _codec* next; + TIFFCodec* info; +} codec_t; +static codec_t* registeredCODECS = NULL; + +const TIFFCodec* +TIFFFindCODEC(uint16 scheme) +{ + const TIFFCodec* c; + codec_t* cd; + + for (cd = registeredCODECS; cd; cd = cd->next) + if (cd->info->scheme == scheme) + return ((const TIFFCodec*) cd->info); + for (c = _TIFFBuiltinCODECS; c->name; c++) + if (c->scheme == scheme) + return (c); + return ((const TIFFCodec*) 0); +} + +TIFFCodec* +TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init) +{ + codec_t* cd = (codec_t*) + _TIFFmalloc(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1); + + if (cd != NULL) { + cd->info = (TIFFCodec*) ((tidata_t) cd + sizeof (codec_t)); + cd->info->name = (char*) + ((tidata_t) cd->info + sizeof (TIFFCodec)); + strcpy(cd->info->name, name); + cd->info->scheme = scheme; + cd->info->init = init; + cd->next = registeredCODECS; + registeredCODECS = cd; + } else + TIFFError("TIFFRegisterCODEC", + "No space to register compression scheme %s", name); + return (cd->info); +} + +void +TIFFUnRegisterCODEC(TIFFCodec* c) +{ + codec_t* cd; + codec_t** pcd; + + for (pcd = ®isteredCODECS; (cd = *pcd); pcd = &cd->next) + if (cd->info == c) { + *pcd = cd->next; + _TIFFfree(cd); + return; + } + TIFFError("TIFFUnRegisterCODEC", + "Cannot remove compression scheme %s; not registered", c->name); +} diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c new file mode 100644 index 00000000..107eb99c --- /dev/null +++ b/libtiff/tif_dir.c @@ -0,0 +1,1131 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dir.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Tag Get & Set Routines. + * (and also some miscellaneous stuff) + */ +#include "tiffiop.h" + +/* + * These are used in the backwards compatibility code... + */ +#define DATATYPE_VOID 0 /* !untyped data */ +#define DATATYPE_INT 1 /* !signed integer data */ +#define DATATYPE_UINT 2 /* !unsigned integer data */ +#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ + +void +_TIFFsetByteArray(void** vpp, void* vp, long n) +{ + if (*vpp) + _TIFFfree(*vpp), *vpp = 0; + if (vp && (*vpp = (void*) _TIFFmalloc(n))) + _TIFFmemcpy(*vpp, vp, n); +} +void _TIFFsetString(char** cpp, char* cp) + { _TIFFsetByteArray((void**) cpp, (void*) cp, (long) (strlen(cp)+1)); } +void _TIFFsetNString(char** cpp, char* cp, long n) + { _TIFFsetByteArray((void**) cpp, (void*) cp, n); } +void _TIFFsetShortArray(uint16** wpp, uint16* wp, long n) + { _TIFFsetByteArray((void**) wpp, (void*) wp, n*sizeof (uint16)); } +void _TIFFsetLongArray(uint32** lpp, uint32* lp, long n) + { _TIFFsetByteArray((void**) lpp, (void*) lp, n*sizeof (uint32)); } +void _TIFFsetFloatArray(float** fpp, float* fp, long n) + { _TIFFsetByteArray((void**) fpp, (void*) fp, n*sizeof (float)); } +void _TIFFsetDoubleArray(double** dpp, double* dp, long n) + { _TIFFsetByteArray((void**) dpp, (void*) dp, n*sizeof (double)); } + +/* + * Install extra samples information. + */ +static int +setExtraSamples(TIFFDirectory* td, va_list ap, int* v) +{ + uint16* va; + int i; + + *v = va_arg(ap, int); + if ((uint16) *v > td->td_samplesperpixel) + return (0); + va = va_arg(ap, uint16*); + if (*v > 0 && va == NULL) /* typically missing param */ + return (0); + for (i = 0; i < *v; i++) + if (va[i] > EXTRASAMPLE_UNASSALPHA) + return (0); + td->td_extrasamples = (uint16) *v; + _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); + return (1); +} + +#ifdef CMYK_SUPPORT +static int +checkInkNamesString(TIFF* tif, int slen, const char* s) +{ + TIFFDirectory* td = &tif->tif_dir; + int i = td->td_samplesperpixel; + + if (slen > 0) { + const char* ep = s+slen; + const char* cp = s; + for (; i > 0; i--) { + for (; *cp != '\0'; cp++) + if (cp >= ep) + goto bad; + cp++; /* skip \0 */ + } + return (cp-s); + } +bad: + TIFFError("TIFFSetField", + "%s: Invalid InkNames value; expecting %d names, found %d", + tif->tif_name, + td->td_samplesperpixel, + td->td_samplesperpixel-i); + return (0); +} +#endif + +static int +_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + TIFFDirectory* td = &tif->tif_dir; + int status = 1; + uint32 v32; + int i, v; + double d; + char* s; + + switch (tag) { + case TIFFTAG_SUBFILETYPE: + td->td_subfiletype = va_arg(ap, uint32); + break; + case TIFFTAG_IMAGEWIDTH: + td->td_imagewidth = va_arg(ap, uint32); + break; + case TIFFTAG_IMAGELENGTH: + td->td_imagelength = va_arg(ap, uint32); + break; + case TIFFTAG_BITSPERSAMPLE: + td->td_bitspersample = (uint16) va_arg(ap, int); + /* + * If the data require post-decoding processing + * to byte-swap samples, set it up here. Note + * that since tags are required to be ordered, + * compression code can override this behaviour + * in the setup method if it wants to roll the + * post decoding work in with its normal work. + */ + if (tif->tif_flags & TIFF_SWAB) { + if (td->td_bitspersample == 16) + tif->tif_postdecode = _TIFFSwab16BitData; + else if (td->td_bitspersample == 32) + tif->tif_postdecode = _TIFFSwab32BitData; + else if (td->td_bitspersample == 64) + tif->tif_postdecode = _TIFFSwab64BitData; + } + break; + case TIFFTAG_COMPRESSION: + v = va_arg(ap, int) & 0xffff; + /* + * If we're changing the compression scheme, + * the notify the previous module so that it + * can cleanup any state it's setup. + */ + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { + if (td->td_compression == v) + break; + (*tif->tif_cleanup)(tif); + tif->tif_flags &= ~TIFF_CODERSETUP; + } + /* + * Setup new compression routine state. + */ + if (status = TIFFSetCompressionScheme(tif, v)) + td->td_compression = v; + break; + case TIFFTAG_PHOTOMETRIC: + td->td_photometric = (uint16) va_arg(ap, int); + break; + case TIFFTAG_THRESHHOLDING: + td->td_threshholding = (uint16) va_arg(ap, int); + break; + case TIFFTAG_FILLORDER: + v = va_arg(ap, int); + if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) + goto badvalue; + td->td_fillorder = (uint16) v; + break; + case TIFFTAG_DOCUMENTNAME: + _TIFFsetString(&td->td_documentname, va_arg(ap, char*)); + break; + case TIFFTAG_ARTIST: + _TIFFsetString(&td->td_artist, va_arg(ap, char*)); + break; + case TIFFTAG_DATETIME: + _TIFFsetString(&td->td_datetime, va_arg(ap, char*)); + break; + case TIFFTAG_HOSTCOMPUTER: + _TIFFsetString(&td->td_hostcomputer, va_arg(ap, char*)); + break; + case TIFFTAG_IMAGEDESCRIPTION: + _TIFFsetString(&td->td_imagedescription, va_arg(ap, char*)); + break; + case TIFFTAG_MAKE: + _TIFFsetString(&td->td_make, va_arg(ap, char*)); + break; + case TIFFTAG_MODEL: + _TIFFsetString(&td->td_model, va_arg(ap, char*)); + break; + case TIFFTAG_SOFTWARE: + _TIFFsetString(&td->td_software, va_arg(ap, char*)); + break; + case TIFFTAG_ORIENTATION: + v = va_arg(ap, int); + if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) { + TIFFWarning(tif->tif_name, + "Bad value %ld for \"%s\" tag ignored", + v, _TIFFFieldWithTag(tif, tag)->field_name); + } else + td->td_orientation = (uint16) v; + break; + case TIFFTAG_SAMPLESPERPIXEL: + /* XXX should cross check -- e.g. if pallette, then 1 */ + v = va_arg(ap, int); + if (v == 0) + goto badvalue; + td->td_samplesperpixel = (uint16) v; + break; + case TIFFTAG_ROWSPERSTRIP: + v32 = va_arg(ap, uint32); + if (v32 == 0) + goto badvalue32; + td->td_rowsperstrip = v32; + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { + td->td_tilelength = v32; + td->td_tilewidth = td->td_imagewidth; + } + break; + case TIFFTAG_MINSAMPLEVALUE: + td->td_minsamplevalue = (uint16) va_arg(ap, int); + break; + case TIFFTAG_MAXSAMPLEVALUE: + td->td_maxsamplevalue = (uint16) va_arg(ap, int); + break; + case TIFFTAG_SMINSAMPLEVALUE: + td->td_sminsamplevalue = (double) va_arg(ap, dblparam_t); + break; + case TIFFTAG_SMAXSAMPLEVALUE: + td->td_smaxsamplevalue = (double) va_arg(ap, dblparam_t); + break; + case TIFFTAG_XRESOLUTION: + td->td_xresolution = (float) va_arg(ap, dblparam_t); + break; + case TIFFTAG_YRESOLUTION: + td->td_yresolution = (float) va_arg(ap, dblparam_t); + break; + case TIFFTAG_PLANARCONFIG: + v = va_arg(ap, int); + if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) + goto badvalue; + td->td_planarconfig = (uint16) v; + break; + case TIFFTAG_PAGENAME: + _TIFFsetString(&td->td_pagename, va_arg(ap, char*)); + break; + case TIFFTAG_XPOSITION: + td->td_xposition = (float) va_arg(ap, dblparam_t); + break; + case TIFFTAG_YPOSITION: + td->td_yposition = (float) va_arg(ap, dblparam_t); + break; + case TIFFTAG_RESOLUTIONUNIT: + v = va_arg(ap, int); + if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) + goto badvalue; + td->td_resolutionunit = (uint16) v; + break; + case TIFFTAG_PAGENUMBER: + td->td_pagenumber[0] = (uint16) va_arg(ap, int); + td->td_pagenumber[1] = (uint16) va_arg(ap, int); + break; + case TIFFTAG_HALFTONEHINTS: + td->td_halftonehints[0] = (uint16) va_arg(ap, int); + td->td_halftonehints[1] = (uint16) va_arg(ap, int); + break; + case TIFFTAG_COLORMAP: + v32 = (uint32)(1L<td_bitspersample); + _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32); + _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32); + _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); + break; + case TIFFTAG_EXTRASAMPLES: + if (!setExtraSamples(td, ap, &v)) + goto badvalue; + break; + case TIFFTAG_MATTEING: + td->td_extrasamples = (uint16) (va_arg(ap, int) != 0); + if (td->td_extrasamples) { + uint16 sv = EXTRASAMPLE_ASSOCALPHA; + _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); + } + break; + case TIFFTAG_TILEWIDTH: + v32 = va_arg(ap, uint32); + if (v32 % 16) { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarning(tif->tif_name, + "Nonstandard tile width %d, convert file", v32); + } + td->td_tilewidth = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILELENGTH: + v32 = va_arg(ap, uint32); + if (v32 % 16) { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarning(tif->tif_name, + "Nonstandard tile length %d, convert file", v32); + } + td->td_tilelength = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILEDEPTH: + v32 = va_arg(ap, uint32); + if (v32 == 0) + goto badvalue32; + td->td_tiledepth = v32; + break; + case TIFFTAG_DATATYPE: + v = va_arg(ap, int); + switch (v) { + case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; + case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; + case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; + case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; + default: goto badvalue; + } + td->td_sampleformat = (uint16) v; + break; + case TIFFTAG_SAMPLEFORMAT: + v = va_arg(ap, int); + if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_VOID < v) + goto badvalue; + td->td_sampleformat = (uint16) v; + break; + case TIFFTAG_IMAGEDEPTH: + td->td_imagedepth = va_arg(ap, uint32); + break; + case TIFFTAG_STONITS: + d = va_arg(ap, dblparam_t); + if (d <= 0.) + goto badvaluedbl; + td->td_stonits = d; + break; +#if SUBIFD_SUPPORT + case TIFFTAG_SUBIFD: + if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { + td->td_nsubifd = (uint16) va_arg(ap, int); + _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*), + (long) td->td_nsubifd); + } else { + TIFFError(tif->tif_name, "Sorry, cannot nest SubIFDs"); + status = 0; + } + break; +#endif +#ifdef YCBCR_SUPPORT + case TIFFTAG_YCBCRCOEFFICIENTS: + _TIFFsetFloatArray(&td->td_ycbcrcoeffs, va_arg(ap, float*), 3); + break; + case TIFFTAG_YCBCRPOSITIONING: + td->td_ycbcrpositioning = (uint16) va_arg(ap, int); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int); + td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int); + break; +#endif +#ifdef COLORIMETRY_SUPPORT + case TIFFTAG_WHITEPOINT: + _TIFFsetFloatArray(&td->td_whitepoint, va_arg(ap, float*), 2); + break; + case TIFFTAG_PRIMARYCHROMATICITIES: + _TIFFsetFloatArray(&td->td_primarychromas, va_arg(ap, float*), 6); + break; + case TIFFTAG_TRANSFERFUNCTION: + v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; + for (i = 0; i < v; i++) + _TIFFsetShortArray(&td->td_transferfunction[i], + va_arg(ap, uint16*), 1L<td_bitspersample); + break; + case TIFFTAG_REFERENCEBLACKWHITE: + /* XXX should check for null range */ + _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6); + break; +#endif +#ifdef CMYK_SUPPORT + case TIFFTAG_INKSET: + td->td_inkset = (uint16) va_arg(ap, int); + break; + case TIFFTAG_DOTRANGE: + /* XXX should check for null range */ + td->td_dotrange[0] = (uint16) va_arg(ap, int); + td->td_dotrange[1] = (uint16) va_arg(ap, int); + break; + case TIFFTAG_INKNAMES: + i = va_arg(ap, int); + s = va_arg(ap, char*); + i = checkInkNamesString(tif, i, s); + if (status = (i > 0)) { + _TIFFsetNString(&td->td_inknames, s, i); + td->td_inknameslen = i; + } + break; + case TIFFTAG_NUMBEROFINKS: + td->td_ninks = (uint16) va_arg(ap, int); + break; + case TIFFTAG_TARGETPRINTER: + _TIFFsetString(&td->td_targetprinter, va_arg(ap, char*)); + break; +#endif +#ifdef ICC_SUPPORT + case TIFFTAG_ICCPROFILE: + td->td_profileLength = (uint32) va_arg(ap, uint32); + _TIFFsetByteArray(&td->td_profileData, va_arg(ap, void*), + td->td_profileLength); + break; +#endif +#ifdef PHOTOSHOP_SUPPORT + case TIFFTAG_PHOTOSHOP: + td->td_photoshopLength = (uint32) va_arg(ap, uint32); + _TIFFsetByteArray (&td->td_photoshopData, va_arg(ap, void*), + td->td_photoshopLength); + break; +#endif +#ifdef IPTC_SUPPORT + case TIFFTAG_RICHTIFFIPTC: + td->td_richtiffiptcLength = (uint32) va_arg(ap, uint32); +#ifdef PHOTOSHOP_SUPPORT + _TIFFsetLongArray ((uint32**)&td->td_richtiffiptcData, va_arg(ap, uint32*), + td->td_richtiffiptcLength); +#else + _TIFFsetByteArray (&td->td_photoshopData, va_arg(ap, void*), + td->td_photoshopLength); +#endif + break; +#endif + default: + /* + * This can happen if multiple images are open with + * different codecs which have private tags. The + * global tag information table may then have tags + * that are valid for one file but not the other. + * If the client tries to set a tag that is not valid + * for the image's codec then we'll arrive here. This + * happens, for example, when tiffcp is used to convert + * between compression schemes and codec-specific tags + * are blindly copied. + */ + TIFFError("TIFFSetField", + "%s: Invalid %stag \"%s\" (not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseduo-" : "", + _TIFFFieldWithTag(tif, tag)->field_name); + status = 0; + break; + } + if (status) { + TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + } + va_end(ap); + return (status); +badvalue: + TIFFError(tif->tif_name, "%d: Bad value for \"%s\"", v, + _TIFFFieldWithTag(tif, tag)->field_name); + va_end(ap); + return (0); +badvalue32: + TIFFError(tif->tif_name, "%ld: Bad value for \"%s\"", v32, + _TIFFFieldWithTag(tif, tag)->field_name); + va_end(ap); + return (0); +badvaluedbl: + TIFFError(tif->tif_name, "%f: Bad value for \"%s\"", d, + _TIFFFieldWithTag(tif, tag)->field_name); + va_end(ap); + return (0); +} + +/* + * Return 1/0 according to whether or not + * it is permissible to set the tag's value. + * Note that we allow ImageLength to be changed + * so that we can append and extend to images. + * Any other tag may not be altered once writing + * has commenced, unless its value has no effect + * on the format of the data that is written. + */ +static int +OkToChangeTag(TIFF* tif, ttag_t tag) +{ + const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); + if (!fip) { /* unknown tag */ + TIFFError("TIFFSetField", "%s: Unknown %stag %u", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); + return (0); + } + if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && + !fip->field_oktochange) { + /* + * Consult info table to see if tag can be changed + * after we've started writing. We only allow changes + * to those tags that don't/shouldn't affect the + * compression and/or format of the data. + */ + TIFFError("TIFFSetField", + "%s: Cannot modify tag \"%s\" while writing", + tif->tif_name, fip->field_name); + return (0); + } + return (1); +} + +/* + * Record the value of a field in the + * internal directory structure. The + * field will be written to the file + * when/if the directory structure is + * updated. + */ +int +TIFFSetField(TIFF* tif, ttag_t tag, ...) +{ + va_list ap; + int status; + + va_start(ap, tag); + status = TIFFVSetField(tif, tag, ap); + va_end(ap); + return (status); +} + +/* + * Like TIFFSetField, but taking a varargs + * parameter list. This routine is useful + * for building higher-level interfaces on + * top of the library. + */ +int +TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + return OkToChangeTag(tif, tag) ? + (*tif->tif_vsetfield)(tif, tag, ap) : 0; +} + +static int +_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + TIFFDirectory* td = &tif->tif_dir; + + switch (tag) { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32*) = td->td_subfiletype; + break; + case TIFFTAG_IMAGEWIDTH: + *va_arg(ap, uint32*) = td->td_imagewidth; + break; + case TIFFTAG_IMAGELENGTH: + *va_arg(ap, uint32*) = td->td_imagelength; + break; + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16*) = td->td_bitspersample; + break; + case TIFFTAG_COMPRESSION: + *va_arg(ap, uint16*) = td->td_compression; + break; + case TIFFTAG_PHOTOMETRIC: + *va_arg(ap, uint16*) = td->td_photometric; + break; + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16*) = td->td_threshholding; + break; + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16*) = td->td_fillorder; + break; + case TIFFTAG_DOCUMENTNAME: + *va_arg(ap, char**) = td->td_documentname; + break; + case TIFFTAG_ARTIST: + *va_arg(ap, char**) = td->td_artist; + break; + case TIFFTAG_DATETIME: + *va_arg(ap, char**) = td->td_datetime; + break; + case TIFFTAG_HOSTCOMPUTER: + *va_arg(ap, char**) = td->td_hostcomputer; + break; + case TIFFTAG_IMAGEDESCRIPTION: + *va_arg(ap, char**) = td->td_imagedescription; + break; + case TIFFTAG_MAKE: + *va_arg(ap, char**) = td->td_make; + break; + case TIFFTAG_MODEL: + *va_arg(ap, char**) = td->td_model; + break; + case TIFFTAG_SOFTWARE: + *va_arg(ap, char**) = td->td_software; + break; + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16*) = td->td_orientation; + break; + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16*) = td->td_samplesperpixel; + break; + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32*) = td->td_rowsperstrip; + break; + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16*) = td->td_minsamplevalue; + break; + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16*) = td->td_maxsamplevalue; + break; + case TIFFTAG_SMINSAMPLEVALUE: + *va_arg(ap, double*) = td->td_sminsamplevalue; + break; + case TIFFTAG_SMAXSAMPLEVALUE: + *va_arg(ap, double*) = td->td_smaxsamplevalue; + break; + case TIFFTAG_XRESOLUTION: + *va_arg(ap, float*) = td->td_xresolution; + break; + case TIFFTAG_YRESOLUTION: + *va_arg(ap, float*) = td->td_yresolution; + break; + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16*) = td->td_planarconfig; + break; + case TIFFTAG_XPOSITION: + *va_arg(ap, float*) = td->td_xposition; + break; + case TIFFTAG_YPOSITION: + *va_arg(ap, float*) = td->td_yposition; + break; + case TIFFTAG_PAGENAME: + *va_arg(ap, char**) = td->td_pagename; + break; + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16*) = td->td_resolutionunit; + break; + case TIFFTAG_PAGENUMBER: + *va_arg(ap, uint16*) = td->td_pagenumber[0]; + *va_arg(ap, uint16*) = td->td_pagenumber[1]; + break; + case TIFFTAG_HALFTONEHINTS: + *va_arg(ap, uint16*) = td->td_halftonehints[0]; + *va_arg(ap, uint16*) = td->td_halftonehints[1]; + break; + case TIFFTAG_COLORMAP: + *va_arg(ap, uint16**) = td->td_colormap[0]; + *va_arg(ap, uint16**) = td->td_colormap[1]; + *va_arg(ap, uint16**) = td->td_colormap[2]; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + *va_arg(ap, uint32**) = td->td_stripoffset; + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + *va_arg(ap, uint32**) = td->td_stripbytecount; + break; + case TIFFTAG_MATTEING: + *va_arg(ap, uint16*) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + break; + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16*) = td->td_extrasamples; + *va_arg(ap, uint16**) = td->td_sampleinfo; + break; + case TIFFTAG_TILEWIDTH: + *va_arg(ap, uint32*) = td->td_tilewidth; + break; + case TIFFTAG_TILELENGTH: + *va_arg(ap, uint32*) = td->td_tilelength; + break; + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32*) = td->td_tiledepth; + break; + case TIFFTAG_DATATYPE: + switch (td->td_sampleformat) { + case SAMPLEFORMAT_UINT: + *va_arg(ap, uint16*) = DATATYPE_UINT; + break; + case SAMPLEFORMAT_INT: + *va_arg(ap, uint16*) = DATATYPE_INT; + break; + case SAMPLEFORMAT_IEEEFP: + *va_arg(ap, uint16*) = DATATYPE_IEEEFP; + break; + case SAMPLEFORMAT_VOID: + *va_arg(ap, uint16*) = DATATYPE_VOID; + break; + } + break; + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16*) = td->td_sampleformat; + break; + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32*) = td->td_imagedepth; + break; + case TIFFTAG_STONITS: + *va_arg(ap, double*) = td->td_stonits; + break; +#if SUBIFD_SUPPORT + case TIFFTAG_SUBIFD: + *va_arg(ap, uint16*) = td->td_nsubifd; + *va_arg(ap, uint32**) = td->td_subifd; + break; +#endif +#ifdef YCBCR_SUPPORT + case TIFFTAG_YCBCRCOEFFICIENTS: + *va_arg(ap, float**) = td->td_ycbcrcoeffs; + break; + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16*) = td->td_ycbcrpositioning; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; + break; +#endif +#ifdef COLORIMETRY_SUPPORT + case TIFFTAG_WHITEPOINT: + *va_arg(ap, float**) = td->td_whitepoint; + break; + case TIFFTAG_PRIMARYCHROMATICITIES: + *va_arg(ap, float**) = td->td_primarychromas; + break; + case TIFFTAG_TRANSFERFUNCTION: + *va_arg(ap, uint16**) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) { + *va_arg(ap, uint16**) = td->td_transferfunction[1]; + *va_arg(ap, uint16**) = td->td_transferfunction[2]; + } + break; + case TIFFTAG_REFERENCEBLACKWHITE: + *va_arg(ap, float**) = td->td_refblackwhite; + break; +#endif +#ifdef CMYK_SUPPORT + case TIFFTAG_INKSET: + *va_arg(ap, uint16*) = td->td_inkset; + break; + case TIFFTAG_DOTRANGE: + *va_arg(ap, uint16*) = td->td_dotrange[0]; + *va_arg(ap, uint16*) = td->td_dotrange[1]; + break; + case TIFFTAG_INKNAMES: + *va_arg(ap, char**) = td->td_inknames; + break; + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16*) = td->td_ninks; + break; + case TIFFTAG_TARGETPRINTER: + *va_arg(ap, char**) = td->td_targetprinter; + break; +#endif +#ifdef ICC_SUPPORT + case TIFFTAG_ICCPROFILE: + *va_arg(ap, uint32*) = td->td_profileLength; + *va_arg(ap, void**) = td->td_profileData; + break; +#endif +#ifdef PHOTOSHOP_SUPPORT + case TIFFTAG_PHOTOSHOP: + *va_arg(ap, uint32*) = td->td_photoshopLength; + *va_arg(ap, void**) = td->td_photoshopData; + break; +#endif +#ifdef IPTC_SUPPORT + case TIFFTAG_RICHTIFFIPTC: + *va_arg(ap, uint32*) = td->td_richtiffiptcLength; + *va_arg(ap, void**) = td->td_richtiffiptcData; + break; +#endif + default: + /* + * This can happen if multiple images are open with + * different codecs which have private tags. The + * global tag information table may then have tags + * that are valid for one file but not the other. + * If the client tries to get a tag that is not valid + * for the image's codec then we'll arrive here. + */ + TIFFError("TIFFGetField", + "%s: Invalid %stag \"%s\" (not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + _TIFFFieldWithTag(tif, tag)->field_name); + break; + } + return (1); +} + +/* + * Return the value of a field in the + * internal directory structure. + */ +int +TIFFGetField(TIFF* tif, ttag_t tag, ...) +{ + int status; + va_list ap; + + va_start(ap, tag); + status = TIFFVGetField(tif, tag, ap); + va_end(ap); + return (status); +} + +/* + * Like TIFFGetField, but taking a varargs + * parameter list. This routine is useful + * for building higher-level interfaces on + * top of the library. + */ +int +TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); + return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? + (*tif->tif_vgetfield)(tif, tag, ap) : 0); +} + +#define CleanupField(member) { \ + if (td->member) { \ + _TIFFfree(td->member); \ + td->member = 0; \ + } \ +} + +/* + * Release storage associated with a directory. + */ +void +TIFFFreeDirectory(TIFF* tif) +{ + register TIFFDirectory *td = &tif->tif_dir; + + CleanupField(td_colormap[0]); + CleanupField(td_colormap[1]); + CleanupField(td_colormap[2]); + CleanupField(td_documentname); + CleanupField(td_artist); + CleanupField(td_datetime); + CleanupField(td_hostcomputer); + CleanupField(td_imagedescription); + CleanupField(td_make); + CleanupField(td_model); + CleanupField(td_software); + CleanupField(td_pagename); + CleanupField(td_sampleinfo); +#if SUBIFD_SUPPORT + CleanupField(td_subifd); +#endif +#ifdef YCBCR_SUPPORT + CleanupField(td_ycbcrcoeffs); +#endif +#ifdef CMYK_SUPPORT + CleanupField(td_inknames); + CleanupField(td_targetprinter); +#endif +#ifdef COLORIMETRY_SUPPORT + CleanupField(td_whitepoint); + CleanupField(td_primarychromas); + CleanupField(td_refblackwhite); + CleanupField(td_transferfunction[0]); + CleanupField(td_transferfunction[1]); + CleanupField(td_transferfunction[2]); +#endif +#ifdef ICC_SUPPORT + CleanupField(td_profileData); +#endif +#ifdef PHOTOSHOP_SUPPORT + CleanupField(td_photoshopData); +#endif +#ifdef IPTC_SUPPORT + CleanupField(td_richtiffiptcData); +#endif + CleanupField(td_stripoffset); + CleanupField(td_stripbytecount); +} +#undef CleanupField + +/* + * Client Tag extension support (from Niles Ritter). + */ +static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; + +TIFFExtendProc +TIFFSetTagExtender(TIFFExtendProc extender) +{ + TIFFExtendProc prev = _TIFFextender; + _TIFFextender = extender; + return (prev); +} + +/* + * Setup a default directory structure. + */ +int +TIFFDefaultDirectory(TIFF* tif) +{ + register TIFFDirectory* td = &tif->tif_dir; + + _TIFFSetupFieldInfo(tif); + _TIFFmemset(td, 0, sizeof (*td)); + td->td_fillorder = FILLORDER_MSB2LSB; + td->td_bitspersample = 1; + td->td_threshholding = THRESHHOLD_BILEVEL; + td->td_orientation = ORIENTATION_TOPLEFT; + td->td_samplesperpixel = 1; + td->td_rowsperstrip = (uint32) -1; + td->td_tilewidth = (uint32) -1; + td->td_tilelength = (uint32) -1; + td->td_tiledepth = 1; + td->td_resolutionunit = RESUNIT_INCH; + td->td_sampleformat = SAMPLEFORMAT_VOID; + td->td_imagedepth = 1; +#ifdef YCBCR_SUPPORT + td->td_ycbcrsubsampling[0] = 2; + td->td_ycbcrsubsampling[1] = 2; + td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; +#endif +#ifdef CMYK_SUPPORT + td->td_inkset = INKSET_CMYK; + td->td_ninks = 4; +#endif + tif->tif_postdecode = _TIFFNoPostDecode; + tif->tif_vsetfield = _TIFFVSetField; + tif->tif_vgetfield = _TIFFVGetField; + tif->tif_printdir = NULL; + /* + * Give client code a chance to install their own + * tag extensions & methods, prior to compression overloads. + */ + if (_TIFFextender) + (*_TIFFextender)(tif); + (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + /* + * NB: The directory is marked dirty as a result of setting + * up the default compression scheme. However, this really + * isn't correct -- we want TIFF_DIRTYDIRECT to be set only + * if the user does something. We could just do the setup + * by hand, but it seems better to use the normal mechanism + * (i.e. TIFFSetField). + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + return (1); +} + +static int +TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off) +{ + static const char module[] = "TIFFAdvanceDirectory"; + uint16 dircount; + + if (!SeekOK(tif, *nextdir) || + !ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFError(module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + if (off != NULL) + *off = TIFFSeekFile(tif, + dircount*sizeof (TIFFDirEntry), SEEK_CUR); + else + (void) TIFFSeekFile(tif, + dircount*sizeof (TIFFDirEntry), SEEK_CUR); + if (!ReadOK(tif, nextdir, sizeof (uint32))) { + TIFFError(module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(nextdir); + return (1); +} + +/* + * Count the number of directories in a file. + */ +tdir_t +TIFFNumberOfDirectories(TIFF* tif) +{ + uint32 nextdir = tif->tif_header.tiff_diroff; + tdir_t n = 0; + + while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) + n++; + return (n); +} + +/* + * Set the n-th directory as the current directory. + * NB: Directories are numbered starting at 0. + */ +int +TIFFSetDirectory(TIFF* tif, tdir_t dirn) +{ + uint32 nextdir; + tdir_t n; + + nextdir = tif->tif_header.tiff_diroff; + for (n = dirn; n > 0 && nextdir != 0; n--) + if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) + return (0); + tif->tif_nextdiroff = nextdir; + /* + * Set curdir to the actual directory index. The + * -1 is because TIFFReadDirectory will increment + * tif_curdir after successfully reading the directory. + */ + tif->tif_curdir = (dirn - n) - 1; + return (TIFFReadDirectory(tif)); +} + +/* + * Set the current directory to be the directory + * located at the specified file offset. This interface + * is used mainly to access directories linked with + * the SubIFD tag (e.g. thumbnail images). + */ +int +TIFFSetSubDirectory(TIFF* tif, uint32 diroff) +{ + tif->tif_nextdiroff = diroff; + return (TIFFReadDirectory(tif)); +} + +/* + * Return file offset of the current directory. + */ +uint32 +TIFFCurrentDirOffset(TIFF* tif) +{ + return (tif->tif_diroff); +} + +/* + * Return an indication of whether or not we are + * at the last directory in the file. + */ +int +TIFFLastDirectory(TIFF* tif) +{ + return (tif->tif_nextdiroff == 0); +} + +/* + * Unlink the specified directory from the directory chain. + */ +int +TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) +{ + static const char module[] = "TIFFUnlinkDirectory"; + uint32 nextdir; + toff_t off; + tdir_t n; + + if (tif->tif_mode == O_RDONLY) { + TIFFError(module, "Can not unlink directory in read-only file"); + return (0); + } + /* + * Go to the directory before the one we want + * to unlink and nab the offset of the link + * field we'll need to patch. + */ + nextdir = tif->tif_header.tiff_diroff; + off = sizeof (uint16) + sizeof (uint16); + for (n = dirn-1; n > 0; n--) { + if (nextdir == 0) { + TIFFError(module, "Directory %d does not exist", dirn); + return (0); + } + if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) + return (0); + } + /* + * Advance to the directory to be unlinked and fetch + * the offset of the directory that follows. + */ + if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) + return (0); + /* + * Go back and patch the link field of the preceding + * directory to point to the offset of the directory + * that follows. + */ + (void) TIFFSeekFile(tif, off, SEEK_SET); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir); + if (!WriteOK(tif, &nextdir, sizeof (uint32))) { + TIFFError(module, "Error writing directory link"); + return (0); + } + /* + * Leave directory state setup safely. We don't have + * facilities for doing inserting and removing directories, + * so it's safest to just invalidate everything. This + * means that the caller can only append to the directory + * chain. + */ + (*tif->tif_cleanup)(tif); + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE); + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; /* force link on next write */ + tif->tif_nextdiroff = 0; /* next write must be at end */ + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (tstrip_t) -1; + return (1); +} diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h new file mode 100644 index 00000000..54eced26 --- /dev/null +++ b/libtiff/tif_dir.h @@ -0,0 +1,252 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dir.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFDIR_ +#define _TIFFDIR_ +/* + * ``Library-private'' Directory-related Definitions. + */ + +/* + * Internal format of a TIFF directory entry. + */ +typedef struct { +#define FIELD_SETLONGS 3 + /* bit vector of fields that are set */ + u_long td_fieldsset[FIELD_SETLONGS]; + + uint32 td_imagewidth, td_imagelength, td_imagedepth; + uint32 td_tilewidth, td_tilelength, td_tiledepth; + uint32 td_subfiletype; + uint16 td_bitspersample; + uint16 td_sampleformat; + uint16 td_compression; + uint16 td_photometric; + uint16 td_threshholding; + uint16 td_fillorder; + uint16 td_orientation; + uint16 td_samplesperpixel; + uint32 td_rowsperstrip; + uint16 td_minsamplevalue, td_maxsamplevalue; + double td_sminsamplevalue, td_smaxsamplevalue; + float td_xresolution, td_yresolution; + uint16 td_resolutionunit; + uint16 td_planarconfig; + float td_xposition, td_yposition; + uint16 td_pagenumber[2]; + uint16* td_colormap[3]; + uint16 td_halftonehints[2]; + uint16 td_extrasamples; + uint16* td_sampleinfo; + double td_stonits; + char* td_documentname; + char* td_artist; + char* td_datetime; + char* td_hostcomputer; + char* td_imagedescription; + char* td_make; + char* td_model; + char* td_software; + char* td_pagename; + tstrip_t td_stripsperimage; + tstrip_t td_nstrips; /* size of offset & bytecount arrays */ + uint32* td_stripoffset; + uint32* td_stripbytecount; +#if SUBIFD_SUPPORT + uint16 td_nsubifd; + uint32* td_subifd; +#endif +#ifdef YCBCR_SUPPORT + float* td_ycbcrcoeffs; + uint16 td_ycbcrsubsampling[2]; + uint16 td_ycbcrpositioning; +#endif +#ifdef COLORIMETRY_SUPPORT + float* td_whitepoint; + float* td_primarychromas; + float* td_refblackwhite; + uint16* td_transferfunction[3]; +#endif +#ifdef CMYK_SUPPORT + uint16 td_inkset; + uint16 td_ninks; + uint16 td_dotrange[2]; + int td_inknameslen; + char* td_inknames; + char* td_targetprinter; +#endif +#ifdef ICC_SUPPORT + uint32 td_profileLength; + void *td_profileData; +#endif +#ifdef PHOTOSHOP_SUPPORT + uint32 td_photoshopLength; + void *td_photoshopData; +#endif +#ifdef IPTC_SUPPORT + uint32 td_richtiffiptcLength; + void *td_richtiffiptcData; +#endif +} TIFFDirectory; + +/* + * Field flags used to indicate fields that have + * been set in a directory, and to reference fields + * when manipulating a directory. + */ + +/* + * FIELD_IGNORE is used to signify tags that are to + * be processed but otherwise ignored. This permits + * antiquated tags to be quietly read and discarded. + * Note that a bit *is* allocated for ignored tags; + * this is understood by the directory reading logic + * which uses this fact to avoid special-case handling + */ +#define FIELD_IGNORE 0 + +/* multi-item fields */ +#define FIELD_IMAGEDIMENSIONS 1 +#define FIELD_TILEDIMENSIONS 2 +#define FIELD_RESOLUTION 3 +#define FIELD_POSITION 4 + +/* single-item fields */ +#define FIELD_SUBFILETYPE 5 +#define FIELD_BITSPERSAMPLE 6 +#define FIELD_COMPRESSION 7 +#define FIELD_PHOTOMETRIC 8 +#define FIELD_THRESHHOLDING 9 +#define FIELD_FILLORDER 10 +#define FIELD_DOCUMENTNAME 11 +#define FIELD_IMAGEDESCRIPTION 12 +#define FIELD_MAKE 13 +#define FIELD_MODEL 14 +#define FIELD_ORIENTATION 15 +#define FIELD_SAMPLESPERPIXEL 16 +#define FIELD_ROWSPERSTRIP 17 +#define FIELD_MINSAMPLEVALUE 18 +#define FIELD_MAXSAMPLEVALUE 19 +#define FIELD_PLANARCONFIG 20 +#define FIELD_PAGENAME 21 +#define FIELD_RESOLUTIONUNIT 22 +#define FIELD_PAGENUMBER 23 +#define FIELD_STRIPBYTECOUNTS 24 +#define FIELD_STRIPOFFSETS 25 +#define FIELD_COLORMAP 26 +#define FIELD_ARTIST 27 +#define FIELD_DATETIME 28 +#define FIELD_HOSTCOMPUTER 29 +#define FIELD_SOFTWARE 30 +#define FIELD_EXTRASAMPLES 31 +#define FIELD_SAMPLEFORMAT 32 +#define FIELD_SMINSAMPLEVALUE 33 +#define FIELD_SMAXSAMPLEVALUE 34 +#define FIELD_IMAGEDEPTH 35 +#define FIELD_TILEDEPTH 36 +#define FIELD_HALFTONEHINTS 37 +#define FIELD_YCBCRCOEFFICIENTS 38 +#define FIELD_YCBCRSUBSAMPLING 39 +#define FIELD_YCBCRPOSITIONING 40 +#define FIELD_REFBLACKWHITE 41 +#define FIELD_WHITEPOINT 42 +#define FIELD_PRIMARYCHROMAS 43 +#define FIELD_TRANSFERFUNCTION 44 +#define FIELD_INKSET 45 +#define FIELD_INKNAMES 46 +#define FIELD_DOTRANGE 47 +#define FIELD_TARGETPRINTER 48 +#define FIELD_SUBIFD 49 +#define FIELD_NUMBEROFINKS 50 +#define FIELD_ICCPROFILE 51 +#define FIELD_PHOTOSHOP 52 +#define FIELD_RICHTIFFIPTC 53 +#define FIELD_STONITS 54 +/* end of support for well-known tags; codec-private tags follow */ +#define FIELD_CODEC 55 /* base of codec-private tags */ +/* + * Pseudo-tags don't normally need field bits since they + * are not written to an output file (by definition). + * The library also has express logic to always query a + * codec for a pseudo-tag so allocating a field bit for + * one is a waste. If codec wants to promote the notion + * of a pseudo-tag being ``set'' or ``unset'' then it can + * do using internal state flags without polluting the + * field bit space defined for real tags. + */ +#define FIELD_PSEUDO 0 + +#define FIELD_LAST (32*FIELD_SETLONGS-1) + +#define TIFFExtractData(tif, type, v) \ + ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \ + ((v) >> (tif)->tif_typeshift[type]) & (tif)->tif_typemask[type] : \ + (v) & (tif)->tif_typemask[type])) +#define TIFFInsertData(tif, type, v) \ + ((uint32) ((tif)->tif_header.tiff_magic == TIFF_BIGENDIAN ? \ + ((v) & (tif)->tif_typemask[type]) << (tif)->tif_typeshift[type] : \ + (v) & (tif)->tif_typemask[type])) + +typedef struct { + ttag_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + u_short field_bit; /* bit in fieldsset bit vector */ + u_char field_oktochange; /* if true, can change while writing */ + u_char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ +} TIFFFieldInfo; + +#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ +#define TIFF_VARIABLE -1 /* marker for variable length tags */ +#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ +#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */ + +extern const int tiffDataWidth[]; /* table of tag datatype widths */ + +#define BITn(n) (((u_long)1L)<<((n)&0x1f)) +#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32]) +#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) +#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) +#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) + +#define FieldSet(fields, f) (fields[(f)/32] & BITn(f)) +#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f)) + +#if defined(__cplusplus) +extern "C" { +#endif +extern void _TIFFSetupFieldInfo(TIFF*); +extern void _TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], int); +extern void _TIFFPrintFieldInfo(TIFF*, FILE*); +extern const TIFFFieldInfo* _TIFFFindFieldInfo(TIFF*, ttag_t, TIFFDataType); +extern const TIFFFieldInfo* _TIFFFieldWithTag(TIFF*, ttag_t); +extern TIFFDataType _TIFFSampleToTagType(TIFF*); +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFDIR_ */ diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c new file mode 100644 index 00000000..e10a6dbe --- /dev/null +++ b/libtiff/tif_dirinfo.c @@ -0,0 +1,386 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dirinfo.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Core Directory Tag Support. + */ +#include "tiffiop.h" +#include + +/* + * NB: NB: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG. + * If a tag can have both LONG and SHORT types + * then the LONG must be placed before the SHORT for + * writing to work properly. + */ +static const TIFFFieldInfo tiffFieldInfo[] = { + { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, FIELD_SUBFILETYPE, + TRUE, FALSE, "SubfileType" }, +/* XXX SHORT for compatibility w/ old versions of the library */ + { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_SHORT, FIELD_SUBFILETYPE, + TRUE, FALSE, "SubfileType" }, + { TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, FIELD_SUBFILETYPE, + TRUE, FALSE, "OldSubfileType" }, + { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, FIELD_IMAGEDIMENSIONS, + FALSE, FALSE, "ImageWidth" }, + { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDIMENSIONS, + FALSE, FALSE, "ImageWidth" }, + { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, FIELD_IMAGEDIMENSIONS, + TRUE, FALSE, "ImageLength" }, + { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDIMENSIONS, + TRUE, FALSE, "ImageLength" }, + { TIFFTAG_BITSPERSAMPLE, -1,-1, TIFF_SHORT, FIELD_BITSPERSAMPLE, + FALSE, FALSE, "BitsPerSample" }, + { TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, FIELD_COMPRESSION, + FALSE, FALSE, "Compression" }, + { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, FIELD_PHOTOMETRIC, + FALSE, FALSE, "PhotometricInterpretation" }, + { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, FIELD_THRESHHOLDING, + TRUE, FALSE, "Threshholding" }, + { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, FIELD_IGNORE, + TRUE, FALSE, "CellWidth" }, + { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, FIELD_IGNORE, + TRUE, FALSE, "CellLength" }, + { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, FIELD_FILLORDER, + FALSE, FALSE, "FillOrder" }, + { TIFFTAG_DOCUMENTNAME, -1,-1, TIFF_ASCII, FIELD_DOCUMENTNAME, + TRUE, FALSE, "DocumentName" }, + { TIFFTAG_IMAGEDESCRIPTION, -1,-1, TIFF_ASCII, FIELD_IMAGEDESCRIPTION, + TRUE, FALSE, "ImageDescription" }, + { TIFFTAG_MAKE, -1,-1, TIFF_ASCII, FIELD_MAKE, + TRUE, FALSE, "Make" }, + { TIFFTAG_MODEL, -1,-1, TIFF_ASCII, FIELD_MODEL, + TRUE, FALSE, "Model" }, + { TIFFTAG_STRIPOFFSETS, -1,-1, TIFF_LONG, FIELD_STRIPOFFSETS, + FALSE, FALSE, "StripOffsets" }, + { TIFFTAG_STRIPOFFSETS, -1,-1, TIFF_SHORT, FIELD_STRIPOFFSETS, + FALSE, FALSE, "StripOffsets" }, + { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, FIELD_ORIENTATION, + FALSE, FALSE, "Orientation" }, + { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, FIELD_SAMPLESPERPIXEL, + FALSE, FALSE, "SamplesPerPixel" }, + { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, FIELD_ROWSPERSTRIP, + FALSE, FALSE, "RowsPerStrip" }, + { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_SHORT, FIELD_ROWSPERSTRIP, + FALSE, FALSE, "RowsPerStrip" }, + { TIFFTAG_STRIPBYTECOUNTS, -1,-1, TIFF_LONG, FIELD_STRIPBYTECOUNTS, + FALSE, FALSE, "StripByteCounts" }, + { TIFFTAG_STRIPBYTECOUNTS, -1,-1, TIFF_SHORT, FIELD_STRIPBYTECOUNTS, + FALSE, FALSE, "StripByteCounts" }, + { TIFFTAG_MINSAMPLEVALUE, -2,-1, TIFF_SHORT, FIELD_MINSAMPLEVALUE, + TRUE, FALSE, "MinSampleValue" }, + { TIFFTAG_MAXSAMPLEVALUE, -2,-1, TIFF_SHORT, FIELD_MAXSAMPLEVALUE, + TRUE, FALSE, "MaxSampleValue" }, + { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_RESOLUTION, + FALSE, FALSE, "XResolution" }, + { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, FIELD_RESOLUTION, + FALSE, FALSE, "YResolution" }, + { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, FIELD_PLANARCONFIG, + FALSE, FALSE, "PlanarConfiguration" }, + { TIFFTAG_PAGENAME, -1,-1, TIFF_ASCII, FIELD_PAGENAME, + TRUE, FALSE, "PageName" }, + { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, FIELD_POSITION, + TRUE, FALSE, "XPosition" }, + { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, FIELD_POSITION, + TRUE, FALSE, "YPosition" }, + { TIFFTAG_FREEOFFSETS, -1,-1, TIFF_LONG, FIELD_IGNORE, + FALSE, FALSE, "FreeOffsets" }, + { TIFFTAG_FREEBYTECOUNTS, -1,-1, TIFF_LONG, FIELD_IGNORE, + FALSE, FALSE, "FreeByteCounts" }, + { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, FIELD_IGNORE, + TRUE, FALSE, "GrayResponseUnit" }, + { TIFFTAG_GRAYRESPONSECURVE,-1,-1, TIFF_SHORT, FIELD_IGNORE, + TRUE, FALSE, "GrayResponseCurve" }, + { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, FIELD_RESOLUTIONUNIT, + FALSE, FALSE, "ResolutionUnit" }, + { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, FIELD_PAGENUMBER, + TRUE, FALSE, "PageNumber" }, + { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, FIELD_IGNORE, + TRUE, FALSE, "ColorResponseUnit" }, +#ifdef COLORIMETRY_SUPPORT + { TIFFTAG_TRANSFERFUNCTION, -1,-1, TIFF_SHORT, FIELD_TRANSFERFUNCTION, + TRUE, FALSE, "TransferFunction" }, +#endif + { TIFFTAG_SOFTWARE, -1,-1, TIFF_ASCII, FIELD_SOFTWARE, + TRUE, FALSE, "Software" }, + { TIFFTAG_DATETIME, 20,20, TIFF_ASCII, FIELD_DATETIME, + TRUE, FALSE, "DateTime" }, + { TIFFTAG_ARTIST, -1,-1, TIFF_ASCII, FIELD_ARTIST, + TRUE, FALSE, "Artist" }, + { TIFFTAG_HOSTCOMPUTER, -1,-1, TIFF_ASCII, FIELD_HOSTCOMPUTER, + TRUE, FALSE, "HostComputer" }, +#ifdef COLORIMETRY_SUPPORT + { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL,FIELD_WHITEPOINT, + TRUE, FALSE, "WhitePoint" }, + { TIFFTAG_PRIMARYCHROMATICITIES,6,6,TIFF_RATIONAL,FIELD_PRIMARYCHROMAS, + TRUE, FALSE, "PrimaryChromaticities" }, +#endif + { TIFFTAG_COLORMAP, -1,-1, TIFF_SHORT, FIELD_COLORMAP, + TRUE, FALSE, "ColorMap" }, + { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, FIELD_HALFTONEHINTS, + TRUE, FALSE, "HalftoneHints" }, + { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, FIELD_TILEDIMENSIONS, + FALSE, FALSE, "TileWidth" }, + { TIFFTAG_TILEWIDTH, 1, 1, TIFF_SHORT, FIELD_TILEDIMENSIONS, + FALSE, FALSE, "TileWidth" }, + { TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, FIELD_TILEDIMENSIONS, + FALSE, FALSE, "TileLength" }, + { TIFFTAG_TILELENGTH, 1, 1, TIFF_SHORT, FIELD_TILEDIMENSIONS, + FALSE, FALSE, "TileLength" }, + { TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG, FIELD_STRIPOFFSETS, + FALSE, FALSE, "TileOffsets" }, + { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG, FIELD_STRIPBYTECOUNTS, + FALSE, FALSE, "TileByteCounts" }, + { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_SHORT, FIELD_STRIPBYTECOUNTS, + FALSE, FALSE, "TileByteCounts" }, +#ifdef TIFFTAG_SUBIFD + { TIFFTAG_SUBIFD, -1,-1, TIFF_LONG, FIELD_SUBIFD, + TRUE, TRUE, "SubIFD" }, +#endif +#ifdef CMYK_SUPPORT /* 6.0 CMYK tags */ + { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, FIELD_INKSET, + FALSE, FALSE, "InkSet" }, + { TIFFTAG_INKNAMES, -1,-1, TIFF_ASCII, FIELD_INKNAMES, + TRUE, TRUE, "InkNames" }, + { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, FIELD_NUMBEROFINKS, + TRUE, FALSE, "NumberOfInks" }, + { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, FIELD_DOTRANGE, + FALSE, FALSE, "DotRange" }, + { TIFFTAG_DOTRANGE, 2, 2, TIFF_BYTE, FIELD_DOTRANGE, + FALSE, FALSE, "DotRange" }, + { TIFFTAG_TARGETPRINTER, -1,-1, TIFF_ASCII, FIELD_TARGETPRINTER, + TRUE, FALSE, "TargetPrinter" }, +#endif + { TIFFTAG_EXTRASAMPLES, -1,-1, TIFF_SHORT, FIELD_EXTRASAMPLES, + FALSE, FALSE, "ExtraSamples" }, +/* XXX for bogus Adobe Photoshop v2.5 files */ + { TIFFTAG_EXTRASAMPLES, -1,-1, TIFF_BYTE, FIELD_EXTRASAMPLES, + FALSE, FALSE, "ExtraSamples" }, + { TIFFTAG_SAMPLEFORMAT, -1,-1, TIFF_SHORT, FIELD_SAMPLEFORMAT, + FALSE, FALSE, "SampleFormat" }, + { TIFFTAG_SMINSAMPLEVALUE, -2,-1, TIFF_ANY, FIELD_SMINSAMPLEVALUE, + TRUE, FALSE, "SMinSampleValue" }, + { TIFFTAG_SMAXSAMPLEVALUE, -2,-1, TIFF_ANY, FIELD_SMAXSAMPLEVALUE, + TRUE, FALSE, "SMaxSampleValue" }, +#ifdef YCBCR_SUPPORT /* 6.0 YCbCr tags */ + { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, FIELD_YCBCRCOEFFICIENTS, + FALSE, FALSE, "YCbCrCoefficients" }, + { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, FIELD_YCBCRSUBSAMPLING, + FALSE, FALSE, "YCbCrSubsampling" }, + { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, FIELD_YCBCRPOSITIONING, + FALSE, FALSE, "YCbCrPositioning" }, +#endif +#ifdef COLORIMETRY_SUPPORT + { TIFFTAG_REFERENCEBLACKWHITE,6,6,TIFF_RATIONAL, FIELD_REFBLACKWHITE, + TRUE, FALSE, "ReferenceBlackWhite" }, +/* XXX temporarily accept LONG for backwards compatibility */ + { TIFFTAG_REFERENCEBLACKWHITE,6,6,TIFF_LONG, FIELD_REFBLACKWHITE, + TRUE, FALSE, "ReferenceBlackWhite" }, +#endif +/* begin SGI tags */ + { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, FIELD_EXTRASAMPLES, + FALSE, FALSE, "Matteing" }, + { TIFFTAG_DATATYPE, -2,-1, TIFF_SHORT, FIELD_SAMPLEFORMAT, + FALSE, FALSE, "DataType" }, + { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, FIELD_IMAGEDEPTH, + FALSE, FALSE, "ImageDepth" }, + { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_SHORT, FIELD_IMAGEDEPTH, + FALSE, FALSE, "ImageDepth" }, + { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, FIELD_TILEDEPTH, + FALSE, FALSE, "TileDepth" }, + { TIFFTAG_TILEDEPTH, 1, 1, TIFF_SHORT, FIELD_TILEDEPTH, + FALSE, FALSE, "TileDepth" }, +/* end SGI tags */ +#ifdef IPTC_SUPPORT +#ifdef PHOTOSHOP_SUPPORT + { TIFFTAG_RICHTIFFIPTC, -1,-1, TIFF_LONG, FIELD_RICHTIFFIPTC, + FALSE, TRUE, "RichTIFFIPTC" }, +#else + { TIFFTAG_RICHTIFFIPTC, -1,-3, TIFF_UNDEFINED, FIELD_RICHTIFFIPTC, + FALSE, TRUE, "RichTIFFIPTC" }, +#endif +#endif +#ifdef PHOTOSHOP_SUPPORT + { TIFFTAG_PHOTOSHOP, -1,-3, TIFF_UNDEFINED, FIELD_PHOTOSHOP, + FALSE, TRUE, "Photoshop" }, + { TIFFTAG_PHOTOSHOP, -1,-1, TIFF_BYTE, FIELD_PHOTOSHOP, + FALSE, TRUE, "Photoshop" }, +#endif +#ifdef ICC_SUPPORT + { TIFFTAG_ICCPROFILE, -1,-3, TIFF_UNDEFINED, FIELD_ICCPROFILE, + FALSE, TRUE, "ICC Profile" }, +#endif + { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, FIELD_STONITS, + FALSE, FALSE, "StoNits" }, +}; +#define N(a) (sizeof (a) / sizeof (a[0])) + +void +_TIFFSetupFieldInfo(TIFF* tif) +{ + if (tif->tif_fieldinfo) { + _TIFFfree(tif->tif_fieldinfo); + tif->tif_nfields = 0; + } + _TIFFMergeFieldInfo(tif, tiffFieldInfo, N(tiffFieldInfo)); +} + +static int +tagCompare(const void* a, const void* b) +{ + const TIFFFieldInfo* ta = *(const TIFFFieldInfo**) a; + const TIFFFieldInfo* tb = *(const TIFFFieldInfo**) b; + /* NB: be careful of return values for 16-bit platforms */ + if (ta->field_tag != tb->field_tag) + return (ta->field_tag < tb->field_tag ? -1 : 1); + else + return (tb->field_type < ta->field_type ? -1 : 1); +} + +void +_TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], int n) +{ + TIFFFieldInfo** tp; + int i; + + if (tif->tif_nfields > 0) { + tif->tif_fieldinfo = (TIFFFieldInfo**) + _TIFFrealloc(tif->tif_fieldinfo, + (tif->tif_nfields+n) * sizeof (TIFFFieldInfo*)); + } else { + tif->tif_fieldinfo = (TIFFFieldInfo**) + _TIFFmalloc(n * sizeof (TIFFFieldInfo*)); + } + tp = &tif->tif_fieldinfo[tif->tif_nfields]; + for (i = 0; i < n; i++) + tp[i] = (TIFFFieldInfo*) &info[i]; /* XXX */ + /* + * NB: the core tags are presumed sorted correctly. + */ + if (tif->tif_nfields > 0) + qsort(tif->tif_fieldinfo, (size_t) (tif->tif_nfields += n), + sizeof (TIFFFieldInfo*), tagCompare); + else + tif->tif_nfields += n; +} + +void +_TIFFPrintFieldInfo(TIFF* tif, FILE* fd) +{ + int i; + + fprintf(fd, "%s: \n", tif->tif_name); + for (i = 0; i < tif->tif_nfields; i++) { + const TIFFFieldInfo* fip = tif->tif_fieldinfo[i]; + fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n" + , i + , (unsigned long) fip->field_tag + , fip->field_readcount, fip->field_writecount + , fip->field_type + , fip->field_bit + , fip->field_oktochange ? "TRUE" : "FALSE" + , fip->field_passcount ? "TRUE" : "FALSE" + , fip->field_name + ); + } +} + +const int tiffDataWidth[] = { + 1, /* nothing */ + 1, /* TIFF_BYTE */ + 1, /* TIFF_ASCII */ + 2, /* TIFF_SHORT */ + 4, /* TIFF_LONG */ + 8, /* TIFF_RATIONAL */ + 1, /* TIFF_SBYTE */ + 1, /* TIFF_UNDEFINED */ + 2, /* TIFF_SSHORT */ + 4, /* TIFF_SLONG */ + 8, /* TIFF_SRATIONAL */ + 4, /* TIFF_FLOAT */ + 8, /* TIFF_DOUBLE */ +}; + +/* + * Return nearest TIFFDataType to the sample type of an image. + */ +TIFFDataType +_TIFFSampleToTagType(TIFF* tif) +{ + int bps = (int) TIFFhowmany(tif->tif_dir.td_bitspersample, 8); + + switch (tif->tif_dir.td_sampleformat) { + case SAMPLEFORMAT_IEEEFP: + return (bps == 4 ? TIFF_FLOAT : TIFF_DOUBLE); + case SAMPLEFORMAT_INT: + return (bps <= 1 ? TIFF_SBYTE : + bps <= 2 ? TIFF_SSHORT : TIFF_SLONG); + case SAMPLEFORMAT_UINT: + return (bps <= 1 ? TIFF_BYTE : + bps <= 2 ? TIFF_SHORT : TIFF_LONG); + case SAMPLEFORMAT_VOID: + return (TIFF_UNDEFINED); + } + /*NOTREACHED*/ + return (TIFF_UNDEFINED); +} + +const TIFFFieldInfo* +_TIFFFindFieldInfo(TIFF* tif, ttag_t tag, TIFFDataType dt) +{ + static const TIFFFieldInfo *last = NULL; + int i, n; + + if (last && last->field_tag == tag && + (dt == TIFF_ANY || dt == last->field_type)) + return (last); + /* NB: if table gets big, use sorted search (e.g. binary search) */ + for (i = 0, n = tif->tif_nfields; i < n; i++) { + const TIFFFieldInfo* fip = tif->tif_fieldinfo[i]; + if (fip->field_tag == tag && + (dt == TIFF_ANY || fip->field_type == dt)) + return (last = fip); + } + return ((const TIFFFieldInfo *)0); +} + +#include +#include + +const TIFFFieldInfo* +_TIFFFieldWithTag(TIFF* tif, ttag_t tag) +{ + const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); + if (!fip) { + TIFFError("TIFFFieldWithTag", + "Internal error, unknown tag 0x%x", (u_int) tag); + assert(fip != NULL); + /*NOTREACHED*/ + } + return (fip); +} diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c new file mode 100644 index 00000000..2001d880 --- /dev/null +++ b/libtiff/tif_dirread.c @@ -0,0 +1,1368 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dirread.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Read Support Routines. + */ +#include "tiffiop.h" + +#define IGNORE 0 /* tag placeholder used below */ + +#if HAVE_IEEEFP +#define TIFFCvtIEEEFloatToNative(tif, n, fp) +#define TIFFCvtIEEEDoubleToNative(tif, n, dp) +#else +extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*); +extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*); +#endif + +static void EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16); +static void MissingRequired(TIFF*, const char*); +static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32); +static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*); +static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*); +static float TIFFFetchRational(TIFF*, TIFFDirEntry*); +static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*); +static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, int*); +static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*); +static int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*); +static int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**); +static int TIFFFetchExtraSamples(TIFF*, TIFFDirEntry*); +static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*); +static float TIFFFetchFloat(TIFF*, TIFFDirEntry*); +static int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*); +static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*); +static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*); +static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*); +static void ChopUpSingleUncompressedStrip(TIFF*); + +static char * +CheckMalloc(TIFF* tif, tsize_t n, const char* what) +{ + char *cp = (char*)_TIFFmalloc(n); + if (cp == NULL) + TIFFError(tif->tif_name, "No space %s", what); + return (cp); +} + +/* + * Read the next TIFF directory from a file + * and convert it to the internal format. + * We read directories sequentially. + */ +int +TIFFReadDirectory(TIFF* tif) +{ + register TIFFDirEntry* dp; + register int n; + register TIFFDirectory* td; + TIFFDirEntry* dir; + int iv; + long v; + double dv; + const TIFFFieldInfo* fip; + int fix; + uint16 dircount; + uint32 nextdiroff; + char* cp; + int diroutoforderwarning = 0; + + tif->tif_diroff = tif->tif_nextdiroff; + if (tif->tif_diroff == 0) /* no more directories */ + return (0); + /* + * Cleanup any previous compression state. + */ + (*tif->tif_cleanup)(tif); + tif->tif_curdir++; + nextdiroff = 0; + if (!isMapped(tif)) { + if (!SeekOK(tif, tif->tif_diroff)) { + TIFFError(tif->tif_name, + "Seek error accessing TIFF directory"); + return (0); + } + if (!ReadOK(tif, &dircount, sizeof (uint16))) { + TIFFError(tif->tif_name, + "Can not read TIFF directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + dir = (TIFFDirEntry *)CheckMalloc(tif, + dircount * sizeof (TIFFDirEntry), "to read TIFF directory"); + if (dir == NULL) + return (0); + if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) { + TIFFError(tif->tif_name, "Can not read TIFF directory"); + goto bad; + } + /* + * Read offset to next directory for sequential scans. + */ + (void) ReadOK(tif, &nextdiroff, sizeof (uint32)); + } else { + toff_t off = tif->tif_diroff; + + if (off + sizeof (uint16) > tif->tif_size) { + TIFFError(tif->tif_name, + "Can not read TIFF directory count"); + return (0); + } else + _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16)); + off += sizeof (uint16); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + dir = (TIFFDirEntry *)CheckMalloc(tif, + dircount * sizeof (TIFFDirEntry), "to read TIFF directory"); + if (dir == NULL) + return (0); + if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) { + TIFFError(tif->tif_name, "Can not read TIFF directory"); + goto bad; + } else + _TIFFmemcpy(dir, tif->tif_base + off, + dircount*sizeof (TIFFDirEntry)); + off += dircount* sizeof (TIFFDirEntry); + if (off + sizeof (uint32) <= tif->tif_size) + _TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32)); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdiroff); + tif->tif_nextdiroff = nextdiroff; + + tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ + /* + * Setup default value and then make a pass over + * the fields to check type and tag information, + * and to extract info required to size data + * structures. A second pass is made afterwards + * to read in everthing not taken in the first pass. + */ + td = &tif->tif_dir; + /* free any old stuff and reinit */ + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + /* + * Electronic Arts writes gray-scale TIFF files + * without a PlanarConfiguration directory entry. + * Thus we setup a default value here, even though + * the TIFF spec says there is no default value. + */ + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + + /* + * Sigh, we must make a separate pass through the + * directory for the following reason: + * + * We must process the Compression tag in the first pass + * in order to merge in codec-private tag definitions (otherwise + * we may get complaints about unknown tags). However, the + * Compression tag may be dependent on the SamplesPerPixel + * tag value because older TIFF specs permited Compression + * to be written as a SamplesPerPixel-count tag entry. + * Thus if we don't first figure out the correct SamplesPerPixel + * tag value then we may end up ignoring the Compression tag + * value because it has an incorrect count value (if the + * true value of SamplesPerPixel is not 1). + * + * It sure would have been nice if Aldus had really thought + * this stuff through carefully. + */ + for (dp = dir, n = dircount; n > 0; n--, dp++) { + if (tif->tif_flags & TIFF_SWAB) { + TIFFSwabArrayOfShort(&dp->tdir_tag, 2); + TIFFSwabArrayOfLong(&dp->tdir_count, 2); + } + if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) { + if (!TIFFFetchNormalTag(tif, dp)) + goto bad; + dp->tdir_tag = IGNORE; + } + } + /* + * First real pass over the directory. + */ + fix = 0; + for (dp = dir, n = dircount; n > 0; n--, dp++) { + /* + * Find the field information entry for this tag. + */ + if (dp->tdir_tag == IGNORE) + continue; + /* + * Silicon Beach (at least) writes unordered + * directory tags (violating the spec). Handle + * it here, but be obnoxious (maybe they'll fix it?). + */ + if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) { + if (!diroutoforderwarning) { + TIFFWarning(tif->tif_name, + "invalid TIFF directory; tags are not sorted in ascending order"); + diroutoforderwarning = 1; + } + fix = 0; /* O(n^2) */ + } + while (fix < tif->tif_nfields && + tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag) + fix++; + if (fix == tif->tif_nfields || + tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) { + TIFFWarning(tif->tif_name, + "unknown field with tag %d (0x%x) ignored", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_tag = IGNORE; + fix = 0; /* restart search */ + continue; + } + /* + * Null out old tags that we ignore. + */ + if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) { + ignore: + dp->tdir_tag = IGNORE; + continue; + } + /* + * Check data type. + */ + fip = tif->tif_fieldinfo[fix]; + while (dp->tdir_type != (u_short) fip->field_type) { + if (fip->field_type == TIFF_ANY) /* wildcard */ + break; + fip++, fix++; + if (fix == tif->tif_nfields || + fip->field_tag != dp->tdir_tag) { + TIFFWarning(tif->tif_name, + "wrong data type %d for \"%s\"; tag ignored", + dp->tdir_type, fip[-1].field_name); + goto ignore; + } + } + /* + * Check count if known in advance. + */ + if (fip->field_readcount != TIFF_VARIABLE) { + uint32 expected = (fip->field_readcount == TIFF_SPP) ? + (uint32) td->td_samplesperpixel : + (uint32) fip->field_readcount; + if (!CheckDirCount(tif, dp, expected)) + goto ignore; + } + + switch (dp->tdir_tag) { + case TIFFTAG_COMPRESSION: + /* + * The 5.0 spec says the Compression tag has + * one value, while earlier specs say it has + * one value per sample. Because of this, we + * accept the tag if one value is supplied. + */ + if (dp->tdir_count == 1) { + v = TIFFExtractData(tif, + dp->tdir_type, dp->tdir_offset); + if (!TIFFSetField(tif, dp->tdir_tag, (int)v)) + goto bad; + break; + } + if (!TIFFFetchPerSampleShorts(tif, dp, &iv) || + !TIFFSetField(tif, dp->tdir_tag, iv)) + goto bad; + dp->tdir_tag = IGNORE; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + case TIFFTAG_TILEBYTECOUNTS: + TIFFSetFieldBit(tif, fip->field_bit); + break; + case TIFFTAG_IMAGEWIDTH: + case TIFFTAG_IMAGELENGTH: + case TIFFTAG_IMAGEDEPTH: + case TIFFTAG_TILELENGTH: + case TIFFTAG_TILEWIDTH: + case TIFFTAG_TILEDEPTH: + case TIFFTAG_PLANARCONFIG: + case TIFFTAG_ROWSPERSTRIP: + if (!TIFFFetchNormalTag(tif, dp)) + goto bad; + dp->tdir_tag = IGNORE; + break; + case TIFFTAG_EXTRASAMPLES: + (void) TIFFFetchExtraSamples(tif, dp); + dp->tdir_tag = IGNORE; + break; + } + } + + /* + * Allocate directory structure and setup defaults. + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { + MissingRequired(tif, "ImageLength"); + goto bad; + } + if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) { + MissingRequired(tif, "PlanarConfiguration"); + goto bad; + } + /* + * Setup appropriate structures (by strip or by tile) + */ + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { + td->td_nstrips = TIFFNumberOfStrips(tif); + td->td_tilewidth = td->td_imagewidth; + td->td_tilelength = td->td_rowsperstrip; + td->td_tiledepth = td->td_imagedepth; + tif->tif_flags &= ~TIFF_ISTILED; + } else { + td->td_nstrips = TIFFNumberOfTiles(tif); + tif->tif_flags |= TIFF_ISTILED; + } + td->td_stripsperimage = td->td_nstrips; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + td->td_stripsperimage /= td->td_samplesperpixel; + if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { + MissingRequired(tif, + isTiled(tif) ? "TileOffsets" : "StripOffsets"); + goto bad; + } + + /* + * Second pass: extract other information. + */ + for (dp = dir, n = dircount; n > 0; n--, dp++) { + if (dp->tdir_tag == IGNORE) + continue; + switch (dp->tdir_tag) { + case TIFFTAG_MINSAMPLEVALUE: + case TIFFTAG_MAXSAMPLEVALUE: + case TIFFTAG_BITSPERSAMPLE: + /* + * The 5.0 spec says the Compression tag has + * one value, while earlier specs say it has + * one value per sample. Because of this, we + * accept the tag if one value is supplied. + * + * The MinSampleValue, MaxSampleValue and + * BitsPerSample tags are supposed to be written + * as one value/sample, but some vendors incorrectly + * write one value only -- so we accept that + * as well (yech). + */ + if (dp->tdir_count == 1) { + v = TIFFExtractData(tif, + dp->tdir_type, dp->tdir_offset); + if (!TIFFSetField(tif, dp->tdir_tag, (int)v)) + goto bad; + break; + } + /* fall thru... */ + case TIFFTAG_DATATYPE: + case TIFFTAG_SAMPLEFORMAT: + if (!TIFFFetchPerSampleShorts(tif, dp, &iv) || + !TIFFSetField(tif, dp->tdir_tag, iv)) + goto bad; + break; + case TIFFTAG_SMINSAMPLEVALUE: + case TIFFTAG_SMAXSAMPLEVALUE: + if (!TIFFFetchPerSampleAnys(tif, dp, &dv) || + !TIFFSetField(tif, dp->tdir_tag, dv)) + goto bad; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + if (!TIFFFetchStripThing(tif, dp, + td->td_nstrips, &td->td_stripoffset)) + goto bad; + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + if (!TIFFFetchStripThing(tif, dp, + td->td_nstrips, &td->td_stripbytecount)) + goto bad; + break; + case TIFFTAG_COLORMAP: + case TIFFTAG_TRANSFERFUNCTION: + /* + * TransferFunction can have either 1x or 3x data + * values; Colormap can have only 3x items. + */ + v = 1L<td_bitspersample; + if (dp->tdir_tag == TIFFTAG_COLORMAP || + dp->tdir_count != (uint32) v) { + if (!CheckDirCount(tif, dp, (uint32)(3*v))) + break; + } + v *= sizeof (uint16); + cp = CheckMalloc(tif, dp->tdir_count * sizeof (uint16), + "to read \"TransferFunction\" tag"); + if (cp != NULL) { + if (TIFFFetchData(tif, dp, cp)) { + /* + * This deals with there being only + * one array to apply to all samples. + */ + uint32 c = + (uint32)1 << td->td_bitspersample; + if (dp->tdir_count == c) + v = 0; + TIFFSetField(tif, dp->tdir_tag, + cp, cp+v, cp+2*v); + } + _TIFFfree(cp); + } + break; + case TIFFTAG_PAGENUMBER: + case TIFFTAG_HALFTONEHINTS: + case TIFFTAG_YCBCRSUBSAMPLING: + case TIFFTAG_DOTRANGE: + (void) TIFFFetchShortPair(tif, dp); + break; +#ifdef COLORIMETRY_SUPPORT + case TIFFTAG_REFERENCEBLACKWHITE: + (void) TIFFFetchRefBlackWhite(tif, dp); + break; +#endif +/* BEGIN REV 4.0 COMPATIBILITY */ + case TIFFTAG_OSUBFILETYPE: + v = 0; + switch (TIFFExtractData(tif, dp->tdir_type, + dp->tdir_offset)) { + case OFILETYPE_REDUCEDIMAGE: + v = FILETYPE_REDUCEDIMAGE; + break; + case OFILETYPE_PAGE: + v = FILETYPE_PAGE; + break; + } + if (v) + (void) TIFFSetField(tif, + TIFFTAG_SUBFILETYPE, (int)v); + break; +/* END REV 4.0 COMPATIBILITY */ + default: + (void) TIFFFetchNormalTag(tif, dp); + break; + } + } + /* + * Verify Palette image has a Colormap. + */ + if (td->td_photometric == PHOTOMETRIC_PALETTE && + !TIFFFieldSet(tif, FIELD_COLORMAP)) { + MissingRequired(tif, "Colormap"); + goto bad; + } + /* + * Attempt to deal with a missing StripByteCounts tag. + */ + if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { + /* + * Some manufacturers violate the spec by not giving + * the size of the strips. In this case, assume there + * is one uncompressed strip of data. + */ + if ((td->td_planarconfig == PLANARCONFIG_CONTIG && + td->td_nstrips > 1) || + (td->td_planarconfig == PLANARCONFIG_SEPARATE && + td->td_nstrips != td->td_samplesperpixel)) { + MissingRequired(tif, "StripByteCounts"); + goto bad; + } + TIFFWarning(tif->tif_name, +"TIFF directory is missing required \"%s\" field, calculating from imagelength", + _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + EstimateStripByteCounts(tif, dir, dircount); +#define BYTECOUNTLOOKSBAD \ + (td->td_stripbytecount[0] == 0 || \ + (td->td_compression == COMPRESSION_NONE && \ + td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0])) + } else if (td->td_nstrips == 1 && BYTECOUNTLOOKSBAD) { + /* + * Plexus (and others) sometimes give a value + * of zero for a tag when they don't know what + * the correct value is! Try and handle the + * simple case of estimating the size of a one + * strip image. + */ + TIFFWarning(tif->tif_name, + "Bogus \"%s\" field, ignoring and calculating from imagelength", + _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name); + EstimateStripByteCounts(tif, dir, dircount); + } + if (dir) + _TIFFfree((char *)dir); + if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + td->td_maxsamplevalue = (uint16)((1L<td_bitspersample)-1); + /* + * Setup default compression scheme. + */ + if (!TIFFFieldSet(tif, FIELD_COMPRESSION)) + TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + /* + * Some manufacturers make life difficult by writing + * large amounts of uncompressed data as a single strip. + * This is contrary to the recommendations of the spec. + * The following makes an attempt at breaking such images + * into strips closer to the recommended 8k bytes. A + * side effect, however, is that the RowsPerStrip tag + * value may be changed. + */ + if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE && + (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP) + ChopUpSingleUncompressedStrip(tif); + /* + * Reinitialize i/o since we are starting on a new directory. + */ + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (tstrip_t) -1; + tif->tif_col = (uint32) -1; + tif->tif_curtile = (ttile_t) -1; + tif->tif_tilesize = TIFFTileSize(tif); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + return (1); +bad: + if (dir) + _TIFFfree(dir); + return (0); +} + +static void +EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount) +{ + register TIFFDirEntry *dp; + register TIFFDirectory *td = &tif->tif_dir; + uint16 i; + + if (td->td_stripbytecount) + _TIFFfree(td->td_stripbytecount); + td->td_stripbytecount = (uint32*) + CheckMalloc(tif, td->td_nstrips * sizeof (uint32), + "for \"StripByteCounts\" array"); + if (td->td_compression != COMPRESSION_NONE) { + uint32 space = (uint32)(sizeof (TIFFHeader) + + sizeof (uint16) + + (dircount * sizeof (TIFFDirEntry)) + + sizeof (uint32)); + toff_t filesize = TIFFGetFileSize(tif); + uint16 n; + + /* calculate amount of space used by indirect values */ + for (dp = dir, n = dircount; n > 0; n--, dp++) { + uint32 cc = dp->tdir_count*tiffDataWidth[dp->tdir_type]; + if (cc > sizeof (uint32)) + space += cc; + } + space = filesize - space; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + space /= td->td_samplesperpixel; + for (i = 0; i < td->td_nstrips; i++) + td->td_stripbytecount[i] = space; + /* + * This gross hack handles the case were the offset to + * the last strip is past the place where we think the strip + * should begin. Since a strip of data must be contiguous, + * it's safe to assume that we've overestimated the amount + * of data in the strip and trim this number back accordingly. + */ + i--; + if (td->td_stripoffset[i] + td->td_stripbytecount[i] > filesize) + td->td_stripbytecount[i] = + filesize - td->td_stripoffset[i]; + } else { + uint32 rowbytes = TIFFScanlineSize(tif); + uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage; + for (i = 0; i < td->td_nstrips; i++) + td->td_stripbytecount[i] = rowbytes*rowsperstrip; + } + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + td->td_rowsperstrip = td->td_imagelength; +} + +static void +MissingRequired(TIFF* tif, const char* tagname) +{ + TIFFError(tif->tif_name, + "TIFF directory is missing required \"%s\" field", tagname); +} + +/* + * Check the count field of a directory + * entry against a known value. The caller + * is expected to skip/ignore the tag if + * there is a mismatch. + */ +static int +CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count) +{ + if (count != dir->tdir_count) { + TIFFWarning(tif->tif_name, + "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, + dir->tdir_count, count); + return (0); + } + return (1); +} + +/* + * Fetch a contiguous directory item. + */ +static tsize_t +TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + int w = tiffDataWidth[dir->tdir_type]; + tsize_t cc = dir->tdir_count * w; + + if (!isMapped(tif)) { + if (!SeekOK(tif, dir->tdir_offset)) + goto bad; + if (!ReadOK(tif, cp, cc)) + goto bad; + } else { + if (dir->tdir_offset + cc > tif->tif_size) + goto bad; + _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc); + } + if (tif->tif_flags & TIFF_SWAB) { + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); + break; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); + break; + case TIFF_DOUBLE: + TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); + break; + } + } + return (cc); +bad: + TIFFError(tif->tif_name, "Error fetching data for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + return ((tsize_t) 0); +} + +/* + * Fetch an ASCII item from the file. + */ +static tsize_t +TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + if (dir->tdir_count <= 4) { + uint32 l = dir->tdir_offset; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&l); + _TIFFmemcpy(cp, &l, dir->tdir_count); + return (1); + } + return (TIFFFetchData(tif, dir, cp)); +} + +/* + * Convert numerator+denominator to float. + */ +static int +cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv) +{ + if (denom == 0) { + TIFFError(tif->tif_name, + "%s: Rational with zero denominator (num = %lu)", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num); + return (0); + } else { + if (dir->tdir_type == TIFF_RATIONAL) + *rv = ((float)num / (float)denom); + else + *rv = ((float)(int32)num / (float)(int32)denom); + return (1); + } +} + +/* + * Fetch a rational item from the file + * at offset off and return the value + * as a floating point number. + */ +static float +TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir) +{ + uint32 l[2]; + float v; + + return (!TIFFFetchData(tif, dir, (char *)l) || + !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v); +} + +/* + * Fetch a single floating point value + * from the offset field and return it + * as a native float. + */ +static float +TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir) +{ + long l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset); + float v = *(float*) &l; + TIFFCvtIEEEFloatToNative(tif, 1, &v); + return (v); +} + +/* + * Fetch an array of BYTE or SBYTE values. + */ +static int +TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) +{ + if (dir->tdir_count <= 4) { + /* + * Extract data from offset field. + */ + if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { + switch (dir->tdir_count) { + case 4: v[3] = dir->tdir_offset & 0xff; + case 3: v[2] = (dir->tdir_offset >> 8) & 0xff; + case 2: v[1] = (dir->tdir_offset >> 16) & 0xff; + case 1: v[0] = dir->tdir_offset >> 24; + } + } else { + switch (dir->tdir_count) { + case 4: v[3] = dir->tdir_offset >> 24; + case 3: v[2] = (dir->tdir_offset >> 16) & 0xff; + case 2: v[1] = (dir->tdir_offset >> 8) & 0xff; + case 1: v[0] = dir->tdir_offset & 0xff; + } + } + return (1); + } else + return (TIFFFetchData(tif, dir, (char*) v) != 0); /* XXX */ +} + +/* + * Fetch an array of SHORT or SSHORT values. + */ +static int +TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) +{ + if (dir->tdir_count <= 2) { + if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { + switch (dir->tdir_count) { + case 2: v[1] = dir->tdir_offset & 0xffff; + case 1: v[0] = dir->tdir_offset >> 16; + } + } else { + switch (dir->tdir_count) { + case 2: v[1] = dir->tdir_offset >> 16; + case 1: v[0] = dir->tdir_offset & 0xffff; + } + } + return (1); + } else + return (TIFFFetchData(tif, dir, (char *)v) != 0); +} + +/* + * Fetch a pair of SHORT or BYTE values. + */ +static int +TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir) +{ + uint16 v[2]; + int ok = 0; + + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + ok = TIFFFetchShortArray(tif, dir, v); + break; + case TIFF_BYTE: + case TIFF_SBYTE: + ok = TIFFFetchByteArray(tif, dir, v); + break; + } + if (ok) + TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); + return (ok); +} + +/* + * Fetch an array of LONG or SLONG values. + */ +static int +TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) +{ + if (dir->tdir_count == 1) { + v[0] = dir->tdir_offset; + return (1); + } else + return (TIFFFetchData(tif, dir, (char*) v) != 0); +} + +/* + * Fetch an array of RATIONAL or SRATIONAL values. + */ +static int +TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) +{ + int ok = 0; + uint32* l; + + l = (uint32*)CheckMalloc(tif, + dir->tdir_count*tiffDataWidth[dir->tdir_type], + "to fetch array of rationals"); + if (l) { + if (TIFFFetchData(tif, dir, (char *)l)) { + uint32 i; + for (i = 0; i < dir->tdir_count; i++) { + ok = cvtRational(tif, dir, + l[2*i+0], l[2*i+1], &v[i]); + if (!ok) + break; + } + } + _TIFFfree((char *)l); + } + return (ok); +} + +/* + * Fetch an array of FLOAT values. + */ +static int +TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) +{ + + if (dir->tdir_count == 1) { + v[0] = *(float*) &dir->tdir_offset; + TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); + return (1); + } else if (TIFFFetchData(tif, dir, (char*) v)) { + TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); + return (1); + } else + return (0); +} + +/* + * Fetch an array of DOUBLE values. + */ +static int +TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) +{ + if (TIFFFetchData(tif, dir, (char*) v)) { + TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v); + return (1); + } else + return (0); +} + +/* + * Fetch an array of ANY values. The actual values are + * returned as doubles which should be able hold all the + * types. Yes, there really should be an tany_t to avoid + * this potential non-portability ... Note in particular + * that we assume that the double return value vector is + * large enough to read in any fundamental type. We use + * that vector as a buffer to read in the base type vector + * and then convert it in place to double (from end + * to front of course). + */ +static int +TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v) +{ + int i; + + switch (dir->tdir_type) { + case TIFF_BYTE: + case TIFF_SBYTE: + if (!TIFFFetchByteArray(tif, dir, (uint16*) v)) + return (0); + if (dir->tdir_type == TIFF_BYTE) { + uint16* vp = (uint16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } else { + int16* vp = (int16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_SHORT: + case TIFF_SSHORT: + if (!TIFFFetchShortArray(tif, dir, (uint16*) v)) + return (0); + if (dir->tdir_type == TIFF_SHORT) { + uint16* vp = (uint16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } else { + int16* vp = (int16*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_LONG: + case TIFF_SLONG: + if (!TIFFFetchLongArray(tif, dir, (uint32*) v)) + return (0); + if (dir->tdir_type == TIFF_LONG) { + uint32* vp = (uint32*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } else { + int32* vp = (int32*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + if (!TIFFFetchRationalArray(tif, dir, (float*) v)) + return (0); + { float* vp = (float*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_FLOAT: + if (!TIFFFetchFloatArray(tif, dir, (float*) v)) + return (0); + { float* vp = (float*) v; + for (i = dir->tdir_count-1; i >= 0; i--) + v[i] = vp[i]; + } + break; + case TIFF_DOUBLE: + return (TIFFFetchDoubleArray(tif, dir, (double*) v)); + default: + /* TIFF_NOTYPE */ + /* TIFF_ASCII */ + /* TIFF_UNDEFINED */ + TIFFError(tif->tif_name, + "Cannot read TIFF_ANY type %d for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + return (0); + } + return (1); +} + +/* + * Fetch a tag that is not handled by special case code. + */ +static int +TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp) +{ + static const char mesg[] = "to fetch tag value"; + int ok = 0; + const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag); + + if (dp->tdir_count > 1) { /* array of values */ + char* cp = NULL; + + switch (dp->tdir_type) { + case TIFF_BYTE: + case TIFF_SBYTE: + /* NB: always expand BYTE values to shorts */ + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (uint16), mesg); + ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp); + break; + case TIFF_SHORT: + case TIFF_SSHORT: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (uint16), mesg); + ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp); + break; + case TIFF_LONG: + case TIFF_SLONG: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (uint32), mesg); + ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp); + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (float), mesg); + ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp); + break; + case TIFF_FLOAT: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (float), mesg); + ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp); + break; + case TIFF_DOUBLE: + cp = CheckMalloc(tif, + dp->tdir_count * sizeof (double), mesg); + ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp); + break; + case TIFF_ASCII: + case TIFF_UNDEFINED: /* bit of a cheat... */ + /* + * Some vendors write strings w/o the trailing + * NULL byte, so always append one just in case. + */ + cp = CheckMalloc(tif, dp->tdir_count+1, mesg); + if (ok = (cp && TIFFFetchString(tif, dp, cp))) + cp[dp->tdir_count] = '\0'; /* XXX */ + break; + } + if (ok) { + ok = (fip->field_passcount ? + TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp) + : TIFFSetField(tif, dp->tdir_tag, cp)); + } + if (cp != NULL) + _TIFFfree(cp); + } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */ + switch (dp->tdir_type) { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + /* + * If the tag is also acceptable as a LONG or SLONG + * then TIFFSetField will expect an uint32 parameter + * passed to it (through varargs). Thus, for machines + * where sizeof (int) != sizeof (uint32) we must do + * a careful check here. It's hard to say if this + * is worth optimizing. + * + * NB: We use TIFFFieldWithTag here knowing that + * it returns us the first entry in the table + * for the tag and that that entry is for the + * widest potential data type the tag may have. + */ + { TIFFDataType type = fip->field_type; + if (type != TIFF_LONG && type != TIFF_SLONG) { + uint16 v = (uint16) + TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset); + ok = (fip->field_passcount ? + TIFFSetField(tif, dp->tdir_tag, 1, &v) + : TIFFSetField(tif, dp->tdir_tag, v)); + break; + } + } + /* fall thru... */ + case TIFF_LONG: + case TIFF_SLONG: + { uint32 v32 = + TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset); + ok = (fip->field_passcount ? + TIFFSetField(tif, dp->tdir_tag, 1, &v32) + : TIFFSetField(tif, dp->tdir_tag, v32)); + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + { float v = (dp->tdir_type == TIFF_FLOAT ? + TIFFFetchFloat(tif, dp) + : TIFFFetchRational(tif, dp)); + ok = (fip->field_passcount ? + TIFFSetField(tif, dp->tdir_tag, 1, &v) + : TIFFSetField(tif, dp->tdir_tag, v)); + } + break; + case TIFF_DOUBLE: + { double v; + ok = (TIFFFetchDoubleArray(tif, dp, &v) && + (fip->field_passcount ? + TIFFSetField(tif, dp->tdir_tag, 1, &v) + : TIFFSetField(tif, dp->tdir_tag, v)) + ); + } + break; + case TIFF_ASCII: + case TIFF_UNDEFINED: /* bit of a cheat... */ + { char c[2]; + if (ok = (TIFFFetchString(tif, dp, c) != 0)) { + c[1] = '\0'; /* XXX paranoid */ + ok = TIFFSetField(tif, dp->tdir_tag, c); + } + } + break; + } + } + return (ok); +} + +#define NITEMS(x) (sizeof (x) / sizeof (x[0])) +/* + * Fetch samples/pixel short values for + * the specified tag and verify that + * all values are the same. + */ +static int +TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl) +{ + int samples = tif->tif_dir.td_samplesperpixel; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { + uint16 buf[10]; + uint16* v = buf; + + if (samples > NITEMS(buf)) + v = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); + if (TIFFFetchShortArray(tif, dir, v)) { + int i; + for (i = 1; i < samples; i++) + if (v[i] != v[0]) { + TIFFError(tif->tif_name, + "Cannot handle different per-sample values for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + goto bad; + } + *pl = v[0]; + status = 1; + } + bad: + if (v != buf) + _TIFFfree((char*) v); + } + return (status); +} + +/* + * Fetch samples/pixel ANY values for + * the specified tag and verify that + * all values are the same. + */ +static int +TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl) +{ + int samples = (int) tif->tif_dir.td_samplesperpixel; + int status = 0; + + if (CheckDirCount(tif, dir, (uint32) samples)) { + double buf[10]; + double* v = buf; + + if (samples > NITEMS(buf)) + v = (double*) _TIFFmalloc(samples * sizeof (double)); + if (TIFFFetchAnyArray(tif, dir, v)) { + int i; + for (i = 1; i < samples; i++) + if (v[i] != v[0]) { + TIFFError(tif->tif_name, + "Cannot handle different per-sample values for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + goto bad; + } + *pl = v[0]; + status = 1; + } + bad: + if (v != buf) + _TIFFfree(v); + } + return (status); +} +#undef NITEMS + +/* + * Fetch a set of offsets or lengths. + * While this routine says "strips", + * in fact it's also used for tiles. + */ +static int +TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp) +{ + register uint32* lp; + int status; + + if (!CheckDirCount(tif, dir, (uint32) nstrips)) + return (0); + /* + * Allocate space for strip information. + */ + if (*lpp == NULL && + (*lpp = (uint32 *)CheckMalloc(tif, + nstrips * sizeof (uint32), "for strip array")) == NULL) + return (0); + lp = *lpp; + if (dir->tdir_type == (int)TIFF_SHORT) { + /* + * Handle uint16->uint32 expansion. + */ + uint16* dp = (uint16*) CheckMalloc(tif, + dir->tdir_count* sizeof (uint16), "to fetch strip tag"); + if (dp == NULL) + return (0); + if (status = TIFFFetchShortArray(tif, dir, dp)) { + register uint16* wp = dp; + while (nstrips-- > 0) + *lp++ = *wp++; + } + _TIFFfree((char*) dp); + } else + status = TIFFFetchLongArray(tif, dir, lp); + return (status); +} + +#define NITEMS(x) (sizeof (x) / sizeof (x[0])) +/* + * Fetch and set the ExtraSamples tag. + */ +static int +TIFFFetchExtraSamples(TIFF* tif, TIFFDirEntry* dir) +{ + uint16 buf[10]; + uint16* v = buf; + int status; + + if (dir->tdir_count > NITEMS(buf)) + v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16)); + if (dir->tdir_type == TIFF_BYTE) + status = TIFFFetchByteArray(tif, dir, v); + else + status = TIFFFetchShortArray(tif, dir, v); + if (status) + status = TIFFSetField(tif, dir->tdir_tag, dir->tdir_count, v); + if (v != buf) + _TIFFfree((char*) v); + return (status); +} +#undef NITEMS + +#ifdef COLORIMETRY_SUPPORT +/* + * Fetch and set the RefBlackWhite tag. + */ +static int +TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir) +{ + static const char mesg[] = "for \"ReferenceBlackWhite\" array"; + char* cp; + int ok; + + if (dir->tdir_type == TIFF_RATIONAL) + return (TIFFFetchNormalTag(tif, dir)); + /* + * Handle LONG's for backward compatibility. + */ + cp = CheckMalloc(tif, dir->tdir_count * sizeof (uint32), mesg); + if (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) { + float* fp = (float*) + CheckMalloc(tif, dir->tdir_count * sizeof (float), mesg); + if (ok = (fp != NULL)) { + uint32 i; + for (i = 0; i < dir->tdir_count; i++) + fp[i] = (float)((uint32*) cp)[i]; + ok = TIFFSetField(tif, dir->tdir_tag, fp); + _TIFFfree((char*) fp); + } + } + if (cp) + _TIFFfree(cp); + return (ok); +} +#endif + +/* + * Replace a single strip (tile) of uncompressed data by + * multiple strips (tiles), each approximately 8Kbytes. + * This is useful for dealing with large images or + * for dealing with machines with a limited amount + * memory. + */ +static void +ChopUpSingleUncompressedStrip(TIFF* tif) +{ + register TIFFDirectory *td = &tif->tif_dir; + uint32 bytecount = td->td_stripbytecount[0]; + uint32 offset = td->td_stripoffset[0]; + tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes; + tstrip_t strip, nstrips, rowsperstrip; + uint32* newcounts; + uint32* newoffsets; + + /* + * Make the rows hold at least one + * scanline, but fill 8k if possible. + */ + if (rowbytes > 8192) { + stripbytes = rowbytes; + rowsperstrip = 1; + } else { + rowsperstrip = 8192 / rowbytes; + stripbytes = rowbytes * rowsperstrip; + } + /* never increase the number of strips in an image */ + if (rowsperstrip >= td->td_rowsperstrip) + return; + nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes); + newcounts = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32), + "for chopped \"StripByteCounts\" array"); + newoffsets = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32), + "for chopped \"StripOffsets\" array"); + if (newcounts == NULL || newoffsets == NULL) { + /* + * Unable to allocate new strip information, give + * up and use the original one strip information. + */ + if (newcounts != NULL) + _TIFFfree(newcounts); + if (newoffsets != NULL) + _TIFFfree(newoffsets); + return; + } + /* + * Fill the strip information arrays with + * new bytecounts and offsets that reflect + * the broken-up format. + */ + for (strip = 0; strip < nstrips; strip++) { + if (stripbytes > bytecount) + stripbytes = bytecount; + newcounts[strip] = stripbytes; + newoffsets[strip] = offset; + offset += stripbytes; + bytecount -= stripbytes; + } + /* + * Replace old single strip info with multi-strip info. + */ + td->td_stripsperimage = td->td_nstrips = nstrips; + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + + _TIFFfree(td->td_stripbytecount); + _TIFFfree(td->td_stripoffset); + td->td_stripbytecount = newcounts; + td->td_stripoffset = newoffsets; +} diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c new file mode 100644 index 00000000..5f0eedb5 --- /dev/null +++ b/libtiff/tif_dirwrite.c @@ -0,0 +1,998 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dirwrite.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Write Support Routines. + */ +#include "tiffiop.h" + +#if HAVE_IEEEFP +#define TIFFCvtNativeToIEEEFloat(tif, n, fp) +#define TIFFCvtNativeToIEEEDouble(tif, n, dp) +#else +extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*); +extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*); +#endif + +static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*); +static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32); +static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*); +static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*); +static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*); +static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**); +static int TIFFWriteShortArray(TIFF*, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*); +static int TIFFWriteLongArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*); +static int TIFFWriteRationalArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); +static int TIFFWriteFloatArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); +static int TIFFWriteDoubleArray(TIFF *, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); +static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*); +static int TIFFWriteAnyArray(TIFF*, + TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); +#ifdef COLORIMETRY_SUPPORT +static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*); +#endif +#ifdef CMYK_SUPPORT +static int TIFFWriteInkNames(TIFF*, TIFFDirEntry*); +#endif +static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*); +static int TIFFLinkDirectory(TIFF*); + +#define WriteRationalPair(type, tag1, v1, tag2, v2) { \ + if (!TIFFWriteRational(tif, type, tag1, dir, v1)) \ + goto bad; \ + if (!TIFFWriteRational(tif, type, tag2, dir+1, v2)) \ + goto bad; \ + dir++; \ +} +#define TIFFWriteRational(tif, type, tag, dir, v) \ + TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v)) +#ifndef TIFFWriteRational +static int TIFFWriteRational(TIFF*, + TIFFDataType, ttag_t, TIFFDirEntry*, float); +#endif + +/* + * Write the contents of the current directory + * to the specified file. This routine doesn't + * handle overwriting a directory with auxiliary + * storage that's been changed. + */ +int +TIFFWriteDirectory(TIFF* tif) +{ + uint16 dircount; + uint32 diroff; + ttag_t tag; + uint32 nfields; + tsize_t dirsize; + char* data; + TIFFDirEntry* dir; + TIFFDirectory* td; + u_long b, fields[FIELD_SETLONGS]; + int fi, nfi; + + if (tif->tif_mode == O_RDONLY) + return (1); + /* + * Clear write state so that subsequent images with + * different characteristics get the right buffers + * setup for them. + */ + if (tif->tif_flags & TIFF_POSTENCODE) { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) { + TIFFError(tif->tif_name, + "Error post-encoding before directory write"); + return (0); + } + } + (*tif->tif_close)(tif); /* shutdown encoder */ + /* + * Flush any data that might have been written + * by the compression close+cleanup routines. + */ + if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) { + TIFFError(tif->tif_name, + "Error flushing data before directory write"); + return (0); + } + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); + + td = &tif->tif_dir; + /* + * Size the directory so that we can calculate + * offsets for the data items that aren't kept + * in-place in each field. + */ + nfields = 0; + for (b = 0; b <= FIELD_LAST; b++) + if (TIFFFieldSet(tif, b)) + nfields += (b < FIELD_SUBFILETYPE ? 2 : 1); + dirsize = nfields * sizeof (TIFFDirEntry); + data = (char*) _TIFFmalloc(dirsize); + if (data == NULL) { + TIFFError(tif->tif_name, + "Cannot write directory, out of space"); + return (0); + } + /* + * Directory hasn't been placed yet, put + * it at the end of the file and link it + * into the existing directory structure. + */ + if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif)) + goto bad; + tif->tif_dataoff = (toff_t)( + tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); + if (tif->tif_dataoff & 1) + tif->tif_dataoff++; + (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); + tif->tif_curdir++; + dir = (TIFFDirEntry*) data; + /* + * Setup external form of directory + * entries and write data items. + */ + _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields)); + /* + * Write out ExtraSamples tag only if + * extra samples are present in the data. + */ + if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) { + ResetFieldBit(fields, FIELD_EXTRASAMPLES); + nfields--; + dirsize -= sizeof (TIFFDirEntry); + } /*XXX*/ + for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) { + const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi]; + if (!FieldSet(fields, fip->field_bit)) + continue; + switch (fip->field_bit) { + case FIELD_STRIPOFFSETS: + /* + * We use one field bit for both strip and tile + * offsets, and so must be careful in selecting + * the appropriate field descriptor (so that tags + * are written in sorted order). + */ + tag = isTiled(tif) ? + TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS; + if (tag != fip->field_tag) + continue; + if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir, + (uint32) td->td_nstrips, td->td_stripoffset)) + goto bad; + break; + case FIELD_STRIPBYTECOUNTS: + /* + * We use one field bit for both strip and tile + * byte counts, and so must be careful in selecting + * the appropriate field descriptor (so that tags + * are written in sorted order). + */ + tag = isTiled(tif) ? + TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS; + if (tag != fip->field_tag) + continue; + if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir, + (uint32) td->td_nstrips, td->td_stripbytecount)) + goto bad; + break; + case FIELD_ROWSPERSTRIP: + TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP, + dir, td->td_rowsperstrip); + break; + case FIELD_COLORMAP: + if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir, + 3, td->td_colormap)) + goto bad; + break; + case FIELD_IMAGEDIMENSIONS: + TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH, + dir++, td->td_imagewidth); + TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH, + dir, td->td_imagelength); + break; + case FIELD_TILEDIMENSIONS: + TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH, + dir++, td->td_tilewidth); + TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH, + dir, td->td_tilelength); + break; + case FIELD_POSITION: + WriteRationalPair(TIFF_RATIONAL, + TIFFTAG_XPOSITION, td->td_xposition, + TIFFTAG_YPOSITION, td->td_yposition); + break; + case FIELD_RESOLUTION: + WriteRationalPair(TIFF_RATIONAL, + TIFFTAG_XRESOLUTION, td->td_xresolution, + TIFFTAG_YRESOLUTION, td->td_yresolution); + break; + case FIELD_BITSPERSAMPLE: + case FIELD_MINSAMPLEVALUE: + case FIELD_MAXSAMPLEVALUE: + case FIELD_SAMPLEFORMAT: + if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir)) + goto bad; + break; + case FIELD_SMINSAMPLEVALUE: + case FIELD_SMAXSAMPLEVALUE: + if (!TIFFWritePerSampleAnys(tif, + _TIFFSampleToTagType(tif), fip->field_tag, dir)) + goto bad; + break; + case FIELD_PAGENUMBER: + case FIELD_HALFTONEHINTS: +#ifdef YCBCR_SUPPORT + case FIELD_YCBCRSUBSAMPLING: +#endif +#ifdef CMYK_SUPPORT + case FIELD_DOTRANGE: +#endif + if (!TIFFSetupShortPair(tif, fip->field_tag, dir)) + goto bad; + break; +#ifdef CMYK_SUPPORT + case FIELD_INKNAMES: + if (!TIFFWriteInkNames(tif, dir)) + goto bad; + break; +#endif +#ifdef COLORIMETRY_SUPPORT + case FIELD_TRANSFERFUNCTION: + if (!TIFFWriteTransferFunction(tif, dir)) + goto bad; + break; +#endif +#if SUBIFD_SUPPORT + case FIELD_SUBIFD: + if (!TIFFWriteNormalTag(tif, dir, fip)) + goto bad; + /* + * Total hack: if this directory includes a SubIFD + * tag then force the next directories to be + * written as ``sub directories'' of this one. This + * is used to write things like thumbnails and + * image masks that one wants to keep out of the + * normal directory linkage access mechanism. + */ + if (dir->tdir_count > 0) { + tif->tif_flags |= TIFF_INSUBIFD; + tif->tif_nsubifd = dir->tdir_count; + if (dir->tdir_count > 1) + tif->tif_subifdoff = dir->tdir_offset; + else + tif->tif_subifdoff = (uint32)( + tif->tif_diroff + + sizeof (uint16) + + ((char*)&dir->tdir_offset-data)); + } + break; +#endif + default: + if (!TIFFWriteNormalTag(tif, dir, fip)) + goto bad; + break; + } + dir++; + ResetFieldBit(fields, fip->field_bit); + } + /* + * Write directory. + */ + dircount = (uint16) nfields; + diroff = (uint32) tif->tif_nextdiroff; + if (tif->tif_flags & TIFF_SWAB) { + /* + * The file's byte order is opposite to the + * native machine architecture. We overwrite + * the directory information with impunity + * because it'll be released below after we + * write it to the file. Note that all the + * other tag construction routines assume that + * we do this byte-swapping; i.e. they only + * byte-swap indirect data. + */ + for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { + TIFFSwabArrayOfShort(&dir->tdir_tag, 2); + TIFFSwabArrayOfLong(&dir->tdir_count, 2); + } + dircount = (uint16) nfields; + TIFFSwabShort(&dircount); + TIFFSwabLong(&diroff); + } + (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET); + if (!WriteOK(tif, &dircount, sizeof (dircount))) { + TIFFError(tif->tif_name, "Error writing directory count"); + goto bad; + } + if (!WriteOK(tif, data, dirsize)) { + TIFFError(tif->tif_name, "Error writing directory contents"); + goto bad; + } + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(tif->tif_name, "Error writing directory link"); + goto bad; + } + TIFFFreeDirectory(tif); + _TIFFfree(data); + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + (*tif->tif_cleanup)(tif); + + /* + * Reset directory-related state for subsequent + * directories. + */ + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32) -1; + tif->tif_curstrip = (tstrip_t) -1; + return (1); +bad: + _TIFFfree(data); + return (0); +} +#undef WriteRationalPair + +/* + * Process tags that are not special cased. + */ +static int +TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) +{ + u_short wc = (u_short) fip->field_writecount; + uint32 wc2; + + dir->tdir_tag = fip->field_tag; + dir->tdir_type = (u_short) fip->field_type; + dir->tdir_count = wc; +#define WRITEF(x,y) x(tif, fip->field_type, fip->field_tag, dir, wc, y) + switch (fip->field_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + if (wc > 1) { + uint16* wp; + if (wc == (u_short) TIFF_VARIABLE) + TIFFGetField(tif, fip->field_tag, &wc, &wp); + else + TIFFGetField(tif, fip->field_tag, &wp); + if (!WRITEF(TIFFWriteShortArray, wp)) + return (0); + } else { + uint16 sv; + TIFFGetField(tif, fip->field_tag, &sv); + dir->tdir_offset = + TIFFInsertData(tif, dir->tdir_type, sv); + } + break; + case TIFF_LONG: + case TIFF_SLONG: + if (wc > 1) { + uint32* lp; + if (wc == (u_short) TIFF_VARIABLE) + TIFFGetField(tif, fip->field_tag, &wc, &lp); + else + TIFFGetField(tif, fip->field_tag, &lp); + if (!WRITEF(TIFFWriteLongArray, lp)) + return (0); + } else { + /* XXX handle LONG->SHORT conversion */ + TIFFGetField(tif, fip->field_tag, &dir->tdir_offset); + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + if (wc > 1) { + float* fp; + if (wc == (u_short) TIFF_VARIABLE) + TIFFGetField(tif, fip->field_tag, &wc, &fp); + else + TIFFGetField(tif, fip->field_tag, &fp); + if (!WRITEF(TIFFWriteRationalArray, fp)) + return (0); + } else { + float fv; + TIFFGetField(tif, fip->field_tag, &fv); + if (!WRITEF(TIFFWriteRationalArray, &fv)) + return (0); + } + break; + case TIFF_FLOAT: + if (wc > 1) { + float* fp; + if (wc == (u_short) TIFF_VARIABLE) + TIFFGetField(tif, fip->field_tag, &wc, &fp); + else + TIFFGetField(tif, fip->field_tag, &fp); + if (!WRITEF(TIFFWriteFloatArray, fp)) + return (0); + } else { + float fv; + TIFFGetField(tif, fip->field_tag, &fv); + if (!WRITEF(TIFFWriteFloatArray, &fv)) + return (0); + } + break; + case TIFF_DOUBLE: + if (wc > 1) { + double* dp; + if (wc == (u_short) TIFF_VARIABLE) + TIFFGetField(tif, fip->field_tag, &wc, &dp); + else + TIFFGetField(tif, fip->field_tag, &dp); + if (!WRITEF(TIFFWriteDoubleArray, dp)) + return (0); + } else { + double dv; + TIFFGetField(tif, fip->field_tag, &dv); + if (!WRITEF(TIFFWriteDoubleArray, &dv)) + return (0); + } + break; + case TIFF_ASCII: + { char* cp; + TIFFGetField(tif, fip->field_tag, &cp); + dir->tdir_count = (uint32) (strlen(cp) + 1); + if (!TIFFWriteByteArray(tif, dir, cp)) + return (0); + } + break; + case TIFF_UNDEFINED: + { char* cp; + if (wc == (u_short) TIFF_VARIABLE) { + TIFFGetField(tif, fip->field_tag, &wc, &cp); + dir->tdir_count = wc; + } else if (wc == (u_short) TIFF_VARIABLE2) { + TIFFGetField(tif, fip->field_tag, &wc2, &cp); + dir->tdir_count = wc2; + } else + TIFFGetField(tif, fip->field_tag, &cp); + if (!TIFFWriteByteArray(tif, dir, cp)) + return (0); + } + break; + } + return (1); +} +#undef WRITEF + +/* + * Setup a directory entry with either a SHORT + * or LONG type according to the value. + */ +static void +TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v) +{ + dir->tdir_tag = tag; + dir->tdir_count = 1; + if (v > 0xffffL) { + dir->tdir_type = (short) TIFF_LONG; + dir->tdir_offset = v; + } else { + dir->tdir_type = (short) TIFF_SHORT; + dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); + } +} +#undef MakeShortDirent + +#ifndef TIFFWriteRational +/* + * Setup a RATIONAL directory entry and + * write the associated indirect value. + */ +static int +TIFFWriteRational(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v) +{ + return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v)); +} +#endif + +#define NITEMS(x) (sizeof (x) / sizeof (x[0])) +/* + * Setup a directory entry that references a + * samples/pixel array of SHORT values and + * (potentially) write the associated indirect + * values. + */ +static int +TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) +{ + uint16 buf[10], v; + uint16* w = buf; + int i, status, samples = tif->tif_dir.td_samplesperpixel; + + if (samples > NITEMS(buf)) + w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); + TIFFGetField(tif, tag, &v); + for (i = 0; i < samples; i++) + w[i] = v; + status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w); + if (w != buf) + _TIFFfree((char*) w); + return (status); +} + +/* + * Setup a directory entry that references a samples/pixel array of ``type'' + * values and (potentially) write the associated indirect values. The source + * data from TIFFGetField() for the specified tag must be returned as double. + */ +static int +TIFFWritePerSampleAnys(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir) +{ + double buf[10], v; + double* w = buf; + int i, status; + int samples = (int) tif->tif_dir.td_samplesperpixel; + + if (samples > NITEMS(buf)) + w = (double*) _TIFFmalloc(samples * sizeof (double)); + TIFFGetField(tif, tag, &v); + for (i = 0; i < samples; i++) + w[i] = v; + status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w); + if (w != buf) + _TIFFfree(w); + return (status); +} +#undef NITEMS + +/* + * Setup a pair of shorts that are returned by + * value, rather than as a reference to an array. + */ +static int +TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) +{ + uint16 v[2]; + + TIFFGetField(tif, tag, &v[0], &v[1]); + return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v)); +} + +/* + * Setup a directory entry for an NxM table of shorts, + * where M is known to be 2**bitspersample, and write + * the associated indirect data. + */ +static int +TIFFWriteShortTable(TIFF* tif, + ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) +{ + uint32 i, off; + + dir->tdir_tag = tag; + dir->tdir_type = (short) TIFF_SHORT; + /* XXX -- yech, fool TIFFWriteData */ + dir->tdir_count = (uint32) (1L<tif_dir.td_bitspersample); + off = tif->tif_dataoff; + for (i = 0; i < n; i++) + if (!TIFFWriteData(tif, dir, (char *)table[i])) + return (0); + dir->tdir_count *= n; + dir->tdir_offset = off; + return (1); +} + +/* + * Write/copy data associated with an ASCII or opaque tag value. + */ +static int +TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + if (dir->tdir_count > 4) { + if (!TIFFWriteData(tif, dir, cp)) + return (0); + } else + _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count); + return (1); +} + +/* + * Setup a directory entry of an array of SHORT + * or SSHORT and write the associated indirect values. + */ +static int +TIFFWriteShortArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (n <= 2) { + if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { + dir->tdir_offset = (uint32) ((long) v[0] << 16); + if (n == 2) + dir->tdir_offset |= v[1] & 0xffff; + } else { + dir->tdir_offset = v[0] & 0xffff; + if (n == 2) + dir->tdir_offset |= (long) v[1] << 16; + } + return (1); + } else + return (TIFFWriteData(tif, dir, (char*) v)); +} + +/* + * Setup a directory entry of an array of LONG + * or SLONG and write the associated indirect values. + */ +static int +TIFFWriteLongArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (n == 1) { + dir->tdir_offset = v[0]; + return (1); + } else + return (TIFFWriteData(tif, dir, (char*) v)); +} + +/* + * Setup a directory entry of an array of RATIONAL + * or SRATIONAL and write the associated indirect values. + */ +static int +TIFFWriteRationalArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) +{ + uint32 i; + uint32* t; + int status; + + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32)); + for (i = 0; i < n; i++) { + float fv = v[i]; + int sign = 1; + uint32 den; + + if (fv < 0) { + if (type == TIFF_RATIONAL) { + TIFFWarning(tif->tif_name, + "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", + _TIFFFieldWithTag(tif,tag)->field_name, fv); + fv = 0; + } else + fv = -fv, sign = -1; + } + den = 1L; + if (fv > 0) { + while (fv < 1L<<(31-3) && den < 1L<<(31-3)) + fv *= 1<<3, den *= 1L<<3; + } + t[2*i+0] = sign * (fv + 0.5); + t[2*i+1] = den; + } + status = TIFFWriteData(tif, dir, (char *)t); + _TIFFfree((char*) t); + return (status); +} + +static int +TIFFWriteFloatArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + TIFFCvtNativeToIEEEFloat(tif, n, v); + if (n == 1) { + dir->tdir_offset = *(uint32*) &v[0]; + return (1); + } else + return (TIFFWriteData(tif, dir, (char*) v)); +} + +static int +TIFFWriteDoubleArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) +{ + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + TIFFCvtNativeToIEEEDouble(tif, n, v); + return (TIFFWriteData(tif, dir, (char*) v)); +} + +/* + * Write an array of ``type'' values for a specified tag (i.e. this is a tag + * which is allowed to have different types, e.g. SMaxSampleType). + * Internally the data values are represented as double since a double can + * hold any of the TIFF tag types (yes, this should really be an abstract + * type tany_t for portability). The data is converted into the specified + * type in a temporary buffer and then handed off to the appropriate array + * writer. + */ +static int +TIFFWriteAnyArray(TIFF* tif, + TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) +{ + char buf[10 * sizeof(double)]; + char* w = buf; + int i, status = 0; + + if (n * tiffDataWidth[type] > sizeof buf) + w = (char*) _TIFFmalloc(n * tiffDataWidth[type]); + switch (type) { + case TIFF_BYTE: + { uint8* bp = (uint8*) w; + for (i = 0; i < n; i++) + bp[i] = (uint8) v[i]; + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (!TIFFWriteByteArray(tif, dir, (char*) bp)) + goto out; + } + break; + case TIFF_SBYTE: + { int8* bp = (int8*) w; + for (i = 0; i < n; i++) + bp[i] = (int8) v[i]; + dir->tdir_tag = tag; + dir->tdir_type = (short) type; + dir->tdir_count = n; + if (!TIFFWriteByteArray(tif, dir, (char*) bp)) + goto out; + } + break; + case TIFF_SHORT: + { uint16* bp = (uint16*) w; + for (i = 0; i < n; i++) + bp[i] = (uint16) v[i]; + if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) + goto out; + } + break; + case TIFF_SSHORT: + { int16* bp = (int16*) w; + for (i = 0; i < n; i++) + bp[i] = (int16) v[i]; + if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) + goto out; + } + break; + case TIFF_LONG: + { uint32* bp = (uint32*) w; + for (i = 0; i < n; i++) + bp[i] = (uint32) v[i]; + if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp)) + goto out; + } + break; + case TIFF_SLONG: + { int32* bp = (int32*) w; + for (i = 0; i < n; i++) + bp[i] = (int32) v[i]; + if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp)) + goto out; + } + break; + case TIFF_FLOAT: + { float* bp = (float*) w; + for (i = 0; i < n; i++) + bp[i] = (float) v[i]; + if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp)) + goto out; + } + break; + case TIFF_DOUBLE: + return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v)); + default: + /* TIFF_NOTYPE */ + /* TIFF_ASCII */ + /* TIFF_UNDEFINED */ + /* TIFF_RATIONAL */ + /* TIFF_SRATIONAL */ + goto out; + } + status = 1; + out: + if (w != buf) + _TIFFfree(w); + return (status); +} + +#ifdef COLORIMETRY_SUPPORT +static int +TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir) +{ + TIFFDirectory* td = &tif->tif_dir; + tsize_t n = (1L<td_bitspersample) * sizeof (uint16); + uint16** tf = td->td_transferfunction; + int ncols; + + /* + * Check if the table can be written as a single column, + * or if it must be written as 3 columns. Note that we + * write a 3-column tag if there are 2 samples/pixel and + * a single column of data won't suffice--hmm. + */ + switch (td->td_samplesperpixel - td->td_extrasamples) { + default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; } + case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; } + case 1: case 0: ncols = 1; + } + return (TIFFWriteShortTable(tif, + TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf)); +} +#endif + +#ifdef CMYK_SUPPORT +static int +TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir) +{ + TIFFDirectory* td = &tif->tif_dir; + + dir->tdir_tag = TIFFTAG_INKNAMES; + dir->tdir_type = (short) TIFF_ASCII; + dir->tdir_count = td->td_inknameslen; + return (TIFFWriteByteArray(tif, dir, td->td_inknames)); +} +#endif + +/* + * Write a contiguous directory item. + */ +static int +TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp) +{ + tsize_t cc; + + if (tif->tif_flags & TIFF_SWAB) { + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); + break; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); + break; + case TIFF_DOUBLE: + TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); + break; + } + } + dir->tdir_offset = tif->tif_dataoff; + cc = dir->tdir_count * tiffDataWidth[dir->tdir_type]; + if (SeekOK(tif, dir->tdir_offset) && + WriteOK(tif, cp, cc)) { + tif->tif_dataoff += (cc + 1) & ~1; + return (1); + } + TIFFError(tif->tif_name, "Error writing data for field \"%s\"", + _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); + return (0); +} + +/* + * Link the current directory into the + * directory chain for the file. + */ +static int +TIFFLinkDirectory(TIFF* tif) +{ + static const char module[] = "TIFFLinkDirectory"; + uint32 nextdir; + uint32 diroff; + + tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; + diroff = (uint32) tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&diroff); +#if SUBIFD_SUPPORT + if (tif->tif_flags & TIFF_INSUBIFD) { + (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(module, + "%s: Error writing SubIFD directory link", + tif->tif_name); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += sizeof (diroff); + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } +#endif + if (tif->tif_header.tiff_diroff == 0) { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff; +#define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f)) + (void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET); + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(tif->tif_name, "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + nextdir = tif->tif_header.tiff_diroff; + do { + uint16 dircount; + + if (!SeekOK(tif, nextdir) || + !ReadOK(tif, &dircount, sizeof (dircount))) { + TIFFError(module, "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void) TIFFSeekFile(tif, + dircount * sizeof (TIFFDirEntry), SEEK_CUR); + if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { + TIFFError(module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir); + } while (nextdir != 0); + (void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR); + if (!WriteOK(tif, &diroff, sizeof (diroff))) { + TIFFError(module, "Error writing directory link"); + return (0); + } + return (1); +} diff --git a/libtiff/tif_dumpmode.c b/libtiff/tif_dumpmode.c new file mode 100644 index 00000000..43b88dac --- /dev/null +++ b/libtiff/tif_dumpmode.c @@ -0,0 +1,114 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * "Null" Compression Algorithm Support. + */ +#include "tiffiop.h" + +/* + * Encode a hunk of pixels. + */ +static int +DumpModeEncode(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s) +{ + (void) s; + while (cc > 0) { + tsize_t n; + + n = cc; + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + n = tif->tif_rawdatasize - tif->tif_rawcc; + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != pp) + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && + !TIFFFlushData1(tif)) + return (-1); + } + return (1); +} + +/* + * Decode a hunk of pixels. + */ +static int +DumpModeDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +{ + (void) s; + if (tif->tif_rawcc < cc) { + TIFFError(tif->tif_name, + "DumpModeDecode: Not enough data for scanline %d", + tif->tif_row); + return (0); + } + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != buf) + _TIFFmemcpy(buf, tif->tif_rawcp, cc); + tif->tif_rawcp += cc; + tif->tif_rawcc -= cc; + return (1); +} + +/* + * Seek forwards nrows in the current strip. + */ +static int +DumpModeSeek(TIFF* tif, uint32 nrows) +{ + tif->tif_rawcp += nrows * tif->tif_scanlinesize; + tif->tif_rawcc -= nrows * tif->tif_scanlinesize; + return (1); +} + +/* + * Initialize dump mode. + */ +int +TIFFInitDumpMode(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_decoderow = DumpModeDecode; + tif->tif_decodestrip = DumpModeDecode; + tif->tif_decodetile = DumpModeDecode; + tif->tif_encoderow = DumpModeEncode; + tif->tif_encodestrip = DumpModeEncode; + tif->tif_encodetile = DumpModeEncode; + tif->tif_seek = DumpModeSeek; + return (1); +} diff --git a/libtiff/tif_error.c b/libtiff/tif_error.c new file mode 100644 index 00000000..e3c31ff5 --- /dev/null +++ b/libtiff/tif_error.c @@ -0,0 +1,49 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +TIFFErrorHandler +TIFFSetErrorHandler(TIFFErrorHandler handler) +{ + TIFFErrorHandler prev = _TIFFerrorHandler; + _TIFFerrorHandler = handler; + return (prev); +} + +void +TIFFError(const char* module, const char* fmt, ...) +{ + if (_TIFFerrorHandler) { + va_list ap; + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } +} diff --git a/libtiff/tif_fax3.c b/libtiff/tif_fax3.c new file mode 100644 index 00000000..1040f6f1 --- /dev/null +++ b/libtiff/tif_fax3.c @@ -0,0 +1,1534 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_fax3.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef CCITT_SUPPORT +/* + * TIFF Library. + * + * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support. + * + * This file contains support for decoding and encoding TIFF + * compression algorithms 2, 3, 4, and 32771. + * + * Decoder support is derived, with permission, from the code + * in Frank Cringle's viewfax program; + * Copyright (C) 1990, 1995 Frank D. Cringle. + */ +#include "tif_fax3.h" +#define G3CODES +#include "t4.h" +#include +#include + +/* + * NB: define PURIFY if you're using purify and you want + * to avoid some harmless array bounds complaints that + * can happen in the _TIFFFax3fillruns routine. + */ + +/* + * Compression+decompression state blocks are + * derived from this ``base state'' block. + */ +typedef struct { + int mode; /* operating mode */ + uint32 rowbytes; /* bytes in a decoded scanline */ + uint32 rowpixels; /* pixels in a scanline */ + + uint16 cleanfaxdata; /* CleanFaxData tag */ + uint32 badfaxrun; /* BadFaxRun tag */ + uint32 badfaxlines; /* BadFaxLines tag */ + uint32 groupoptions; /* Group 3/4 options tag */ + uint32 recvparams; /* encoded Class 2 session params */ + char* subaddress; /* subaddress string */ + uint32 recvtime; /* time spent receiving (secs) */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} Fax3BaseState; +#define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data) + +typedef struct { + Fax3BaseState b; + const u_char* bitmap; /* bit reversal table */ + uint32 data; /* current i/o byte/word */ + int bit; /* current i/o bit in byte */ + int EOLcnt; /* count of EOL codes recognized */ + TIFFFaxFillFunc fill; /* fill routine */ + uint16* runs; /* b&w runs for current/previous row */ + uint16* refruns; /* runs for reference line */ + uint16* curruns; /* runs for current line */ +} Fax3DecodeState; +#define DecoderState(tif) ((Fax3DecodeState*) Fax3State(tif)) + +typedef struct { + Fax3BaseState b; + int data; /* current i/o byte */ + int bit; /* current i/o bit in byte */ + enum { G3_1D, G3_2D } tag; /* encoding state */ + u_char* refline; /* reference line for 2d decoding */ + int k; /* #rows left that can be 2d encoded */ + int maxk; /* max #rows that can be 2d encoded */ +} Fax3EncodeState; +#define EncoderState(tif) ((Fax3EncodeState*) Fax3State(tif)) + +#define is2DEncoding(sp) \ + (sp->b.groupoptions & GROUP3OPT_2DENCODING) +#define isAligned(p,t) ((((u_long)(p)) & (sizeof (t)-1)) == 0) + +/* + * Group 3 and Group 4 Decoding. + */ + +/* + * These macros glue the TIFF library state to + * the state expected by Frank's decoder. + */ +#define DECLARE_STATE(tif, sp, mod) \ + static const char module[] = mod; \ + Fax3DecodeState* sp = DecoderState(tif); \ + int a0; /* reference element */ \ + int lastx = sp->b.rowpixels; /* last element in row */ \ + uint32 BitAcc; /* bit accumulator */ \ + int BitsAvail; /* # valid bits in BitAcc */ \ + int RunLength; /* length of current run */ \ + u_char* cp; /* next byte of input data */ \ + u_char* ep; /* end of input data */ \ + uint16* pa; /* place to stuff next run */ \ + uint16* thisrun; /* current row's run array */ \ + int EOLcnt; /* # EOL codes recognized */ \ + const u_char* bitmap = sp->bitmap; /* input data bit reverser */ \ + const TIFFFaxTabEnt* TabEnt +#define DECLARE_STATE_2D(tif, sp, mod) \ + DECLARE_STATE(tif, sp, mod); \ + int b1; /* next change on prev line */ \ + uint16* pb /* next run in reference line */\ +/* + * Load any state that may be changed during decoding. + */ +#define CACHE_STATE(tif, sp) do { \ + BitAcc = sp->data; \ + BitsAvail = sp->bit; \ + EOLcnt = sp->EOLcnt; \ + cp = (unsigned char*) tif->tif_rawcp; \ + ep = cp + tif->tif_rawcc; \ +} while (0) +/* + * Save state possibly changed during decoding. + */ +#define UNCACHE_STATE(tif, sp) do { \ + sp->bit = BitsAvail; \ + sp->data = BitAcc; \ + sp->EOLcnt = EOLcnt; \ + tif->tif_rawcc -= (tidata_t) cp - tif->tif_rawcp; \ + tif->tif_rawcp = (tidata_t) cp; \ +} while (0) + +/* + * Setup state for decoding a strip. + */ +static int +Fax3PreDecode(TIFF* tif, tsample_t s) +{ + Fax3DecodeState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + sp->bit = 0; /* force initial read */ + sp->data = 0; + sp->EOLcnt = 0; /* force initial scan for EOL */ + /* + * Decoder assumes lsb-to-msb bit order. Note that we select + * this here rather than in Fax3SetupState so that viewers can + * hold the image open, fiddle with the FillOrder tag value, + * and then re-decode the image. Otherwise they'd need to close + * and open the image to get the state reset. + */ + sp->bitmap = + TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); + if (sp->refruns) { /* init reference line to white */ + sp->refruns[0] = sp->b.rowpixels; + sp->refruns[1] = 0; + } + return (1); +} + +/* + * Routine for handling various errors/conditions. + * Note how they are "glued into the decoder" by + * overriding the definitions used by the decoder. + */ + +static void +Fax3Unexpected(const char* module, TIFF* tif, uint32 a0) +{ + TIFFError(module, "%s: Bad code word at scanline %d (x %lu)", + tif->tif_name, tif->tif_row, (u_long) a0); +} +#define unexpected(table, a0) Fax3Unexpected(module, tif, a0) + +static void +Fax3Extension(const char* module, TIFF* tif, uint32 a0) +{ + TIFFError(module, + "%s: Uncompressed data (not supported) at scanline %d (x %lu)", + tif->tif_name, tif->tif_row, (u_long) a0); +} +#define extension(a0) Fax3Extension(module, tif, a0) + +static void +Fax3BadLength(const char* module, TIFF* tif, uint32 a0, uint32 lastx) +{ + TIFFWarning(module, "%s: %s at scanline %d (got %lu, expected %lu)", + tif->tif_name, + a0 < lastx ? "Premature EOL" : "Line length mismatch", + tif->tif_row, (u_long) a0, (u_long) lastx); +} +#define badlength(a0,lastx) Fax3BadLength(module, tif, a0, lastx) + +static void +Fax3PrematureEOF(const char* module, TIFF* tif, uint32 a0) +{ + TIFFWarning(module, "%s: Premature EOF at scanline %d (x %lu)", + tif->tif_name, tif->tif_row, (u_long) a0); +} +#define prematureEOF(a0) Fax3PrematureEOF(module, tif, a0) + +#define Nop + +/* + * Decode the requested amount of G3 1D-encoded data. + */ +static int +Fax3Decode1D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +{ + DECLARE_STATE(tif, sp, "Fax3Decode1D"); + + (void) s; + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while ((long)occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); +#endif + SYNC_EOL(EOF1D); + EXPAND1D(EOF1Da); + (*sp->fill)(buf, thisrun, pa, lastx); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + if (occ != 0) + tif->tif_row++; + continue; + EOF1D: /* premature EOF */ + CLEANUP_RUNS(); + EOF1Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} + +#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +/* + * Decode the requested amount of G3 2D-encoded data. + */ +static int +Fax3Decode2D(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +{ + DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); + int is1D; /* current line is 1d/2d-encoded */ + + (void) s; + CACHE_STATE(tif, sp); + while ((long)occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d", + BitAcc, BitsAvail, EOLcnt); +#endif + SYNC_EOL(EOF2D); + NeedBits8(1, EOF2D); + is1D = GetBits(1); /* 1D/2D-encoding tag bit */ + ClrBits(1); +#ifdef FAX3_DEBUG + printf(" %s\n-------------------- %d\n", + is1D ? "1D" : "2D", tif->tif_row); + fflush(stdout); +#endif + pb = sp->refruns; + b1 = *pb++; + if (is1D) + EXPAND1D(EOF2Da); + else + EXPAND2D(EOF2Da); + (*sp->fill)(buf, thisrun, pa, lastx); + SETVAL(0); /* imaginary change for reference */ + SWAP(uint16*, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + if (occ != 0) + tif->tif_row++; + continue; + EOF2D: /* premature EOF */ + CLEANUP_RUNS(); + EOF2Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} +#undef SWAP + +/* + * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes. + * For machines with 64-bit longs this is <16 bytes; otherwise + * this is <8 bytes. We optimize the code here to reflect the + * machine characteristics. + */ +#if defined(__alpha) || _MIPS_SZLONG == 64 +#define FILL(n, cp) \ + switch (n) { \ + case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\ + case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\ + case 9: (cp)[8] = 0xff; case 8: (cp)[7] = 0xff; case 7: (cp)[6] = 0xff;\ + case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; case 4: (cp)[3] = 0xff;\ + case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ + case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ + } +#define ZERO(n, cp) \ + switch (n) { \ + case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0; \ + case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0; \ + case 9: (cp)[8] = 0; case 8: (cp)[7] = 0; case 7: (cp)[6] = 0; \ + case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; case 4: (cp)[3] = 0; \ + case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ + case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ + } +#else +#define FILL(n, cp) \ + switch (n) { \ + case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \ + case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \ + case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \ + } +#define ZERO(n, cp) \ + switch (n) { \ + case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; \ + case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \ + case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \ + } +#endif + +/* + * Bit-fill a row according to the white/black + * runs generated during G3/G4 decoding. + */ +void +_TIFFFax3fillruns(u_char* buf, uint16* runs, uint16* erun, uint32 lastx) +{ + static const unsigned char _fillmasks[] = + { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; + u_char* cp; + uint32 x, bx, run; + int32 n, nw; + long* lp; + + if ((erun-runs)&1) + *erun++ = 0; + x = 0; + for (; runs < erun; runs += 2) { + run = runs[0]; + if (x+run > lastx) + run = runs[0] = lastx - x; + if (run) { + cp = buf + (x>>3); + bx = x&7; + if (run > 8-bx) { + if (bx) { /* align to byte boundary */ + *cp++ &= 0xff << (8-bx); + run -= 8-bx; + } + if (n = run >> 3) { /* multiple bytes to fill */ + if ((n/sizeof (long)) > 1) { + /* + * Align to longword boundary and fill. + */ + for (; n && !isAligned(cp, long); n--) + *cp++ = 0x00; + lp = (long*) cp; + nw = (int32)(n / sizeof (long)); + n -= nw * sizeof (long); + do { + *lp++ = 0L; + } while (--nw); + cp = (u_char*) lp; + } + ZERO(n, cp); + run &= 7; + } +#ifdef PURIFY + if (run) + cp[0] &= 0xff >> run; +#else + cp[0] &= 0xff >> run; +#endif + } else + cp[0] &= ~(_fillmasks[run]>>bx); + x += runs[0]; + } + run = runs[1]; + if (x+run > lastx) + run = runs[1] = lastx - x; + if (run) { + cp = buf + (x>>3); + bx = x&7; + if (run > 8-bx) { + if (bx) { /* align to byte boundary */ + *cp++ |= 0xff >> bx; + run -= 8-bx; + } + if (n = run>>3) { /* multiple bytes to fill */ + if ((n/sizeof (long)) > 1) { + /* + * Align to longword boundary and fill. + */ + for (; n && !isAligned(cp, long); n--) + *cp++ = 0xff; + lp = (long*) cp; + nw = (int32)(n / sizeof (long)); + n -= nw * sizeof (long); + do { + *lp++ = -1L; + } while (--nw); + cp = (u_char*) lp; + } + FILL(n, cp); + run &= 7; + } +#ifdef PURIFY + if (run) + cp[0] |= 0xff00 >> run; +#else + cp[0] |= 0xff00 >> run; +#endif + } else + cp[0] |= _fillmasks[run]>>bx; + x += runs[1]; + } + } + assert(x == lastx); +} +#undef ZERO +#undef FILL + +/* + * Setup G3/G4-related compression/decompression state + * before data is processed. This routine is called once + * per image -- it sets up different state based on whether + * or not decoding or encoding is being done and whether + * 1D- or 2D-encoded data is involved. + */ +static int +Fax3SetupState(TIFF* tif) +{ + TIFFDirectory* td = &tif->tif_dir; + Fax3BaseState* sp = Fax3State(tif); + long rowbytes, rowpixels; + int needsRefLine; + + if (td->td_bitspersample != 1) { + TIFFError(tif->tif_name, + "Bits/sample must be 1 for Group 3/4 encoding/decoding"); + return (0); + } + /* + * Calculate the scanline/tile widths. + */ + if (isTiled(tif)) { + rowbytes = TIFFTileRowSize(tif); + rowpixels = td->td_tilewidth; + } else { + rowbytes = TIFFScanlineSize(tif); + rowpixels = td->td_imagewidth; + } + sp->rowbytes = (uint32) rowbytes; + sp->rowpixels = (uint32) rowpixels; + /* + * Allocate any additional space required for decoding/encoding. + */ + needsRefLine = ( + (sp->groupoptions & GROUP3OPT_2DENCODING) || + td->td_compression == COMPRESSION_CCITTFAX4 + ); + if (tif->tif_mode == O_RDONLY) { /* 1d/2d decoding */ + Fax3DecodeState* dsp = DecoderState(tif); + uint32 nruns = needsRefLine ? + 2*TIFFroundup(rowpixels,32) : rowpixels; + + dsp->runs = (uint16*) _TIFFmalloc(nruns*sizeof (uint16)); + if (dsp->runs == NULL) { + TIFFError("Fax3SetupState", + "%s: No space for Group 3/4 run arrays", + tif->tif_name); + return (0); + } + dsp->curruns = dsp->runs; + if (needsRefLine) + dsp->refruns = dsp->runs + (nruns>>1); + else + dsp->refruns = NULL; + if (is2DEncoding(dsp)) { /* NB: default is 1D routine */ + tif->tif_decoderow = Fax3Decode2D; + tif->tif_decodestrip = Fax3Decode2D; + tif->tif_decodetile = Fax3Decode2D; + } + } else if (needsRefLine) { /* 2d encoding */ + Fax3EncodeState* esp = EncoderState(tif); + /* + * 2d encoding requires a scanline + * buffer for the ``reference line''; the + * scanline against which delta encoding + * is referenced. The reference line must + * be initialized to be ``white'' (done elsewhere). + */ + esp->refline = (u_char*) _TIFFmalloc(rowbytes); + if (esp->refline == NULL) { + TIFFError("Fax3SetupState", + "%s: No space for Group 3/4 reference line", + tif->tif_name); + return (0); + } + } else /* 1d encoding */ + EncoderState(tif)->refline = NULL; + return (1); +} + +/* + * CCITT Group 3 FAX Encoding. + */ + +#define Fax3FlushBits(tif, sp) { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + (void) TIFFFlushData1(tif); \ + *(tif)->tif_rawcp++ = (sp)->data; \ + (tif)->tif_rawcc++; \ + (sp)->data = 0, (sp)->bit = 8; \ +} +#define _FlushBits(tif) { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + (void) TIFFFlushData1(tif); \ + *(tif)->tif_rawcp++ = data; \ + (tif)->tif_rawcc++; \ + data = 0, bit = 8; \ +} +static const int _msbmask[9] = + { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; +#define _PutBits(tif, bits, length) { \ + while (length > bit) { \ + data |= bits >> (length - bit); \ + length -= bit; \ + _FlushBits(tif); \ + } \ + data |= (bits & _msbmask[length]) << (bit - length); \ + bit -= length; \ + if (bit == 0) \ + _FlushBits(tif); \ +} + +/* + * Write a variable-length bit-value to + * the output stream. Values are + * assumed to be at most 16 bits. + */ +static void +Fax3PutBits(TIFF* tif, u_int bits, u_int length) +{ + Fax3EncodeState* sp = EncoderState(tif); + int bit = sp->bit; + int data = sp->data; + + _PutBits(tif, bits, length); + + sp->data = data; + sp->bit = bit; +} + +/* + * Write a code to the output stream. + */ +#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) + +#ifdef FAX3_DEBUG +#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B") +#define DEBUG_PRINT(what,len) { \ + int t; \ + printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len); \ + for (t = length-1; t >= 0; t--) \ + putchar(code & (1<bit; + int data = sp->data; + u_int code, length; + + while (span >= 2624) { + const tableentry* te = &tab[63 + (2560>>6)]; + code = te->code, length = te->length; +#ifdef FAX3_DEBUG + DEBUG_PRINT("MakeUp", te->runlen); +#endif + _PutBits(tif, code, length); + span -= te->runlen; + } + if (span >= 64) { + const tableentry* te = &tab[63 + (span>>6)]; + assert(te->runlen == 64*(span>>6)); + code = te->code, length = te->length; +#ifdef FAX3_DEBUG + DEBUG_PRINT("MakeUp", te->runlen); +#endif + _PutBits(tif, code, length); + span -= te->runlen; + } + code = tab[span].code, length = tab[span].length; +#ifdef FAX3_DEBUG + DEBUG_PRINT(" Term", tab[span].runlen); +#endif + _PutBits(tif, code, length); + + sp->data = data; + sp->bit = bit; +} + +/* + * Write an EOL code to the output stream. The zero-fill + * logic for byte-aligning encoded scanlines is handled + * here. We also handle writing the tag bit for the next + * scanline when doing 2d encoding. + */ +static void +Fax3PutEOL(TIFF* tif) +{ + Fax3EncodeState* sp = EncoderState(tif); + int bit = sp->bit; + int data = sp->data; + u_int code, length; + + if (sp->b.groupoptions & GROUP3OPT_FILLBITS) { + /* + * Force bit alignment so EOL will terminate on + * a byte boundary. That is, force the bit alignment + * to 16-12 = 4 before putting out the EOL code. + */ + int align = 8 - 4; + if (align != sp->bit) { + if (align > sp->bit) + align = sp->bit + (8 - align); + else + align = sp->bit - align; + code = 0; + _PutBits(tif, 0, align); + } + } + code = EOL, length = 12; + if (is2DEncoding(sp)) + code = (code<<1) | (sp->tag == G3_1D), length++; + _PutBits(tif, code, length); + + sp->data = data; + sp->bit = bit; +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +Fax3PreEncode(TIFF* tif, tsample_t s) +{ + Fax3EncodeState* sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + sp->bit = 8; + sp->data = 0; + sp->tag = G3_1D; + /* + * This is necessary for Group 4; otherwise it isn't + * needed because the first scanline of each strip ends + * up being copied into the refline. + */ + if (sp->refline) + _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); + if (is2DEncoding(sp)) { + float res = tif->tif_dir.td_yresolution; + /* + * The CCITT spec says that when doing 2d encoding, you + * should only do it on K consecutive scanlines, where K + * depends on the resolution of the image being encoded + * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory + * code initializes td_yresolution to 0, this code will + * select a K of 2 unless the YResolution tag is set + * appropriately. (Note also that we fudge a little here + * and use 150 lpi to avoid problems with units conversion.) + */ + if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) + res *= 2.54f; /* convert to inches */ + sp->maxk = (res > 150 ? 4 : 2); + sp->k = sp->maxk-1; + } else + sp->k = sp->maxk = 0; + return (1); +} + +static const u_char zeroruns[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ +}; +static const u_char oneruns[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ +}; + +/* + * On certain systems it pays to inline + * the routines that find pixel spans. + */ +#ifdef VAXC +static int32 find0span(u_char*, int32, int32); +static int32 find1span(u_char*, int32, int32); +#pragma inline(find0span,find1span) +#endif + +/* + * Find a span of ones or zeros using the supplied + * table. The ``base'' of the bit string is supplied + * along with the start+end bit indices. + */ +INLINE static int32 +find0span(u_char* bp, int32 bs, int32 be) +{ + int32 bits = be - bs; + int32 n, span; + + bp += bs>>3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7))) { + span = zeroruns[(*bp << n) & 0xff]; + if (span > 8-n) /* table value too generous */ + span = 8-n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n+span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } else + span = 0; + if (bits >= 2*8*sizeof (long)) { + long* lp; + /* + * Align to longword boundary and check longwords. + */ + while (!isAligned(bp, long)) { + if (*bp != 0x00) + return (span + zeroruns[*bp]); + span += 8, bits -= 8; + bp++; + } + lp = (long*) bp; + while (bits >= 8*sizeof (long) && *lp == 0) { + span += 8*sizeof (long), bits -= 8*sizeof (long); + lp++; + } + bp = (u_char*) lp; + } + /* + * Scan full bytes for all 0's. + */ + while (bits >= 8) { + if (*bp != 0x00) /* end of run */ + return (span + zeroruns[*bp]); + span += 8, bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) { + n = zeroruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); +} + +INLINE static int32 +find1span(u_char* bp, int32 bs, int32 be) +{ + int32 bits = be - bs; + int32 n, span; + + bp += bs>>3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7))) { + span = oneruns[(*bp << n) & 0xff]; + if (span > 8-n) /* table value too generous */ + span = 8-n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n+span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } else + span = 0; + if (bits >= 2*8*sizeof (long)) { + long* lp; + /* + * Align to longword boundary and check longwords. + */ + while (!isAligned(bp, long)) { + if (*bp != 0xff) + return (span + oneruns[*bp]); + span += 8, bits -= 8; + bp++; + } + lp = (long*) bp; + while (bits >= 8*sizeof (long) && *lp == ~0) { + span += 8*sizeof (long), bits -= 8*sizeof (long); + lp++; + } + bp = (u_char*) lp; + } + /* + * Scan full bytes for all 1's. + */ + while (bits >= 8) { + if (*bp != 0xff) /* end of run */ + return (span + oneruns[*bp]); + span += 8, bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) { + n = oneruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); +} + +/* + * Return the offset of the next bit in the range + * [bs..be] that is different from the specified + * color. The end, be, is returned if no such bit + * exists. + */ +#define finddiff(_cp, _bs, _be, _color) \ + (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be))) +/* + * Like finddiff, but also check the starting bit + * against the end in case start > end. + */ +#define finddiff2(_cp, _bs, _be, _color) \ + (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be) + +/* + * 1d-encode a row of pixels. The encoding is + * a sequence of all-white or all-black spans + * of pixels encoded with Huffman codes. + */ +static int +Fax3Encode1DRow(TIFF* tif, u_char* bp, uint32 bits) +{ + Fax3EncodeState* sp = EncoderState(tif); + int32 bs = 0, span; + + for (;;) { + span = find0span(bp, bs, bits); /* white span */ + putspan(tif, span, TIFFFaxWhiteCodes); + bs += span; + if (bs >= bits) + break; + span = find1span(bp, bs, bits); /* black span */ + putspan(tif, span, TIFFFaxBlackCodes); + bs += span; + if (bs >= bits) + break; + } + if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) { + if (sp->bit != 8) /* byte-align */ + Fax3FlushBits(tif, sp); + if ((sp->b.mode&FAXMODE_WORDALIGN) && + !isAligned(tif->tif_rawcp, uint16)) + Fax3FlushBits(tif, sp); + } + return (1); +} + +static const tableentry horizcode = + { 3, 0x1 }; /* 001 */ +static const tableentry passcode = + { 4, 0x1 }; /* 0001 */ +static const tableentry vcodes[7] = { + { 7, 0x03 }, /* 0000 011 */ + { 6, 0x03 }, /* 0000 11 */ + { 3, 0x03 }, /* 011 */ + { 1, 0x1 }, /* 1 */ + { 3, 0x2 }, /* 010 */ + { 6, 0x02 }, /* 0000 10 */ + { 7, 0x02 } /* 0000 010 */ +}; + +/* + * 2d-encode a row of pixels. Consult the CCITT + * documentation for the algorithm. + */ +static int +Fax3Encode2DRow(TIFF* tif, u_char* bp, u_char* rp, uint32 bits) +{ +#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1) + int32 a0 = 0; + int32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0)); + int32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0)); + int32 a2, b2; + + for (;;) { + b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1)); + if (b2 >= a1) { + int32 d = b1 - a1; + if (!(-3 <= d && d <= 3)) { /* horizontal mode */ + a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1)); + putcode(tif, &horizcode); + if (a0+a1 == 0 || PIXEL(bp, a0) == 0) { + putspan(tif, a1-a0, TIFFFaxWhiteCodes); + putspan(tif, a2-a1, TIFFFaxBlackCodes); + } else { + putspan(tif, a1-a0, TIFFFaxBlackCodes); + putspan(tif, a2-a1, TIFFFaxWhiteCodes); + } + a0 = a2; + } else { /* vertical mode */ + putcode(tif, &vcodes[d+3]); + a0 = a1; + } + } else { /* pass mode */ + putcode(tif, &passcode); + a0 = b2; + } + if (a0 >= bits) + break; + a1 = finddiff(bp, a0, bits, PIXEL(bp,a0)); + b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0)); + b1 = finddiff(rp, b1, bits, PIXEL(bp,a0)); + } + return (1); +#undef PIXEL +} + +/* + * Encode a buffer of pixels. + */ +static int +Fax3Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + Fax3EncodeState* sp = EncoderState(tif); + + (void) s; + while ((long)cc > 0) { + if ((sp->b.mode & FAXMODE_NOEOL) == 0) + Fax3PutEOL(tif); + if (is2DEncoding(sp)) { + if (sp->tag == G3_1D) { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + sp->tag = G3_2D; + } else { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + sp->k--; + } + if (sp->k == 0) { + sp->tag = G3_1D; + sp->k = sp->maxk-1; + } else + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + } else { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + } + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + if (cc != 0) + tif->tif_row++; + } + return (1); +} + +static int +Fax3PostEncode(TIFF* tif) +{ + Fax3EncodeState* sp = EncoderState(tif); + + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); +} + +static void +Fax3Close(TIFF* tif) +{ + if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) { + Fax3EncodeState* sp = EncoderState(tif); + u_int code = EOL; + u_int length = 12; + int i; + + if (is2DEncoding(sp)) + code = (code<<1) | (sp->tag == G3_1D), length++; + for (i = 0; i < 6; i++) + Fax3PutBits(tif, code, length); + Fax3FlushBits(tif, sp); + } +} + +static void +Fax3Cleanup(TIFF* tif) +{ + if (tif->tif_data) { + if (tif->tif_mode == O_RDONLY) { + Fax3DecodeState* sp = DecoderState(tif); + if (sp->runs) + _TIFFfree(sp->runs); + } else { + Fax3EncodeState* sp = EncoderState(tif); + if (sp->refline) + _TIFFfree(sp->refline); + } + if (Fax3State(tif)->subaddress) + _TIFFfree(Fax3State(tif)->subaddress); + _TIFFfree(tif->tif_data); + tif->tif_data = NULL; + } +} + +#define FIELD_BADFAXLINES (FIELD_CODEC+0) +#define FIELD_CLEANFAXDATA (FIELD_CODEC+1) +#define FIELD_BADFAXRUN (FIELD_CODEC+2) +#define FIELD_RECVPARAMS (FIELD_CODEC+3) +#define FIELD_SUBADDRESS (FIELD_CODEC+4) +#define FIELD_RECVTIME (FIELD_CODEC+5) + +#define FIELD_OPTIONS (FIELD_CODEC+6) + +static const TIFFFieldInfo faxFieldInfo[] = { + { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, + FALSE, FALSE, "FaxMode" }, + { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, FIELD_PSEUDO, + FALSE, FALSE, "FaxFillFunc" }, + { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, FIELD_BADFAXLINES, + TRUE, FALSE, "BadFaxLines" }, + { TIFFTAG_BADFAXLINES, 1, 1, TIFF_SHORT, FIELD_BADFAXLINES, + TRUE, FALSE, "BadFaxLines" }, + { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, FIELD_CLEANFAXDATA, + TRUE, FALSE, "CleanFaxData" }, + { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_LONG, FIELD_BADFAXRUN, + TRUE, FALSE, "ConsecutiveBadFaxLines" }, + { TIFFTAG_CONSECUTIVEBADFAXLINES,1,1, TIFF_SHORT, FIELD_BADFAXRUN, + TRUE, FALSE, "ConsecutiveBadFaxLines" }, + { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, FIELD_RECVPARAMS, + TRUE, FALSE, "FaxRecvParams" }, + { TIFFTAG_FAXSUBADDRESS, -1,-1, TIFF_ASCII, FIELD_SUBADDRESS, + TRUE, FALSE, "FaxSubAddress" }, + { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, FIELD_RECVTIME, + TRUE, FALSE, "FaxRecvTime" }, +}; +static const TIFFFieldInfo fax3FieldInfo[] = { + { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, + FALSE, FALSE, "Group3Options" }, +}; +static const TIFFFieldInfo fax4FieldInfo[] = { + { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS, + FALSE, FALSE, "Group4Options" }, +}; +#define N(a) (sizeof (a) / sizeof (a[0])) + +static int +Fax3VSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + Fax3BaseState* sp = Fax3State(tif); + + switch (tag) { + case TIFFTAG_FAXMODE: + sp->mode = va_arg(ap, int); + return (1); /* NB: pseudo tag */ + case TIFFTAG_FAXFILLFUNC: + if (tif->tif_mode == O_RDONLY) + DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); + return (1); /* NB: pseudo tag */ + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + sp->groupoptions = va_arg(ap, uint32); + break; + case TIFFTAG_BADFAXLINES: + sp->badfaxlines = va_arg(ap, uint32); + break; + case TIFFTAG_CLEANFAXDATA: + sp->cleanfaxdata = (uint16) va_arg(ap, int); + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + sp->badfaxrun = va_arg(ap, uint32); + break; + case TIFFTAG_FAXRECVPARAMS: + sp->recvparams = va_arg(ap, uint32); + break; + case TIFFTAG_FAXSUBADDRESS: + _TIFFsetString(&sp->subaddress, va_arg(ap, char*)); + break; + case TIFFTAG_FAXRECVTIME: + sp->recvtime = va_arg(ap, uint32); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); +} + +static int +Fax3VGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + Fax3BaseState* sp = Fax3State(tif); + + switch (tag) { + case TIFFTAG_FAXMODE: + *va_arg(ap, int*) = sp->mode; + break; + case TIFFTAG_FAXFILLFUNC: + if (tif->tif_mode == O_RDONLY) + *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill; + break; + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + *va_arg(ap, uint32*) = sp->groupoptions; + break; + case TIFFTAG_BADFAXLINES: + *va_arg(ap, uint32*) = sp->badfaxlines; + break; + case TIFFTAG_CLEANFAXDATA: + *va_arg(ap, uint16*) = sp->cleanfaxdata; + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + *va_arg(ap, uint32*) = sp->badfaxrun; + break; + case TIFFTAG_FAXRECVPARAMS: + *va_arg(ap, uint32*) = sp->recvparams; + break; + case TIFFTAG_FAXSUBADDRESS: + *va_arg(ap, char**) = sp->subaddress; + break; + case TIFFTAG_FAXRECVTIME: + *va_arg(ap, uint32*) = sp->recvtime; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static void +Fax3PrintDir(TIFF* tif, FILE* fd, long flags) +{ + Fax3BaseState* sp = Fax3State(tif); + + (void) flags; + if (TIFFFieldSet(tif,FIELD_OPTIONS)) { + const char* sep = " "; + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) { + fprintf(fd, " Group 4 Options:"); + if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } else { + + fprintf(fd, " Group 3 Options:"); + if (sp->groupoptions & GROUP3OPT_2DENCODING) + fprintf(fd, "%s2-d encoding", sep), sep = "+"; + if (sp->groupoptions & GROUP3OPT_FILLBITS) + fprintf(fd, "%sEOL padding", sep), sep = "+"; + if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } + fprintf(fd, " (%lu = 0x%lx)\n", + (u_long) sp->groupoptions, (u_long) sp->groupoptions); + } + if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) { + fprintf(fd, " Fax Data:"); + switch (sp->cleanfaxdata) { + case CLEANFAXDATA_CLEAN: + fprintf(fd, " clean"); + break; + case CLEANFAXDATA_REGENERATED: + fprintf(fd, " receiver regenerated"); + break; + case CLEANFAXDATA_UNCLEAN: + fprintf(fd, " uncorrected errors"); + break; + } + fprintf(fd, " (%u = 0x%x)\n", + sp->cleanfaxdata, sp->cleanfaxdata); + } + if (TIFFFieldSet(tif,FIELD_BADFAXLINES)) + fprintf(fd, " Bad Fax Lines: %lu\n", (u_long) sp->badfaxlines); + if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) + fprintf(fd, " Consecutive Bad Fax Lines: %lu\n", + (u_long) sp->badfaxrun); + if (TIFFFieldSet(tif,FIELD_RECVPARAMS)) + fprintf(fd, " Fax Receive Parameters: %08lx\n", + (u_long) sp->recvparams); + if (TIFFFieldSet(tif,FIELD_SUBADDRESS)) + fprintf(fd, " Fax SubAddress: %s\n", sp->subaddress); + if (TIFFFieldSet(tif,FIELD_RECVTIME)) + fprintf(fd, " Fax Receive Time: %lu secs\n", + (u_long) sp->recvtime); +} + +static int +InitCCITTFax3(TIFF* tif) +{ + Fax3BaseState* sp; + + /* + * Allocate state block so tag methods have storage to record values. + */ + if (tif->tif_mode == O_RDONLY) + tif->tif_data = _TIFFmalloc(sizeof (Fax3DecodeState)); + else + tif->tif_data = _TIFFmalloc(sizeof (Fax3EncodeState)); + if (tif->tif_data == NULL) { + TIFFError("TIFFInitCCITTFax3", + "%s: No space for state block", tif->tif_name); + return (0); + } + sp = Fax3State(tif); + + /* + * Merge codec-specific tag information and + * override parent get/set field methods. + */ + _TIFFMergeFieldInfo(tif, faxFieldInfo, N(faxFieldInfo)); + sp->vgetparent = tif->tif_vgetfield; + tif->tif_vgetfield = Fax3VGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_vsetfield; + tif->tif_vsetfield = Fax3VSetField; /* hook for codec tags */ + tif->tif_printdir = Fax3PrintDir; /* hook for codec tags */ + sp->groupoptions = 0; + sp->recvparams = 0; + sp->subaddress = NULL; + + if (tif->tif_mode == O_RDONLY) { + tif->tif_flags |= TIFF_NOBITREV;/* decoder does bit reversal */ + DecoderState(tif)->runs = NULL; + TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); + } else + EncoderState(tif)->refline = NULL; + + /* + * Install codec methods. + */ + tif->tif_setupdecode = Fax3SetupState; + tif->tif_predecode = Fax3PreDecode; + tif->tif_decoderow = Fax3Decode1D; + tif->tif_decodestrip = Fax3Decode1D; + tif->tif_decodetile = Fax3Decode1D; + tif->tif_setupencode = Fax3SetupState; + tif->tif_preencode = Fax3PreEncode; + tif->tif_postencode = Fax3PostEncode; + tif->tif_encoderow = Fax3Encode; + tif->tif_encodestrip = Fax3Encode; + tif->tif_encodetile = Fax3Encode; + tif->tif_close = Fax3Close; + tif->tif_cleanup = Fax3Cleanup; + + return (1); +} + +int +TIFFInitCCITTFax3(TIFF* tif, int scheme) +{ + if (InitCCITTFax3(tif)) { + _TIFFMergeFieldInfo(tif, fax3FieldInfo, N(fax3FieldInfo)); + + /* + * The default format is Class/F-style w/o RTC. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); + } else + return (0); +} + +/* + * CCITT Group 4 (T.6) Facsimile-compatible + * Compression Scheme Support. + */ + +#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +/* + * Decode the requested amount of G4-encoded data. + */ +static int +Fax4Decode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +{ + DECLARE_STATE_2D(tif, sp, "Fax4Decode"); + + (void) s; + CACHE_STATE(tif, sp); + while ((long)occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; + pb = sp->refruns; + b1 = *pb++; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); +#endif + EXPAND2D(EOFG4); + (*sp->fill)(buf, thisrun, pa, lastx); + SETVAL(0); /* imaginary change for reference */ + SWAP(uint16*, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + if (occ != 0) + tif->tif_row++; + continue; + EOFG4: + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} +#undef SWAP + +/* + * Encode the requested amount of data. + */ +static int +Fax4Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + Fax3EncodeState *sp = EncoderState(tif); + + (void) s; + while ((long)cc > 0) { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + if (cc != 0) + tif->tif_row++; + } + return (1); +} + +static int +Fax4PostEncode(TIFF* tif) +{ + Fax3EncodeState *sp = EncoderState(tif); + + /* terminate strip w/ EOFB */ + Fax3PutBits(tif, EOL, 12); + Fax3PutBits(tif, EOL, 12); + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); +} + +int +TIFFInitCCITTFax4(TIFF* tif, int scheme) +{ + if (InitCCITTFax3(tif)) { /* reuse G3 support */ + _TIFFMergeFieldInfo(tif, fax4FieldInfo, N(fax4FieldInfo)); + + tif->tif_decoderow = Fax4Decode; + tif->tif_decodestrip = Fax4Decode; + tif->tif_decodetile = Fax4Decode; + tif->tif_encoderow = Fax4Encode; + tif->tif_encodestrip = Fax4Encode; + tif->tif_encodetile = Fax4Encode; + tif->tif_postencode = Fax4PostEncode; + /* + * Suppress RTC at the end of each strip. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); + } else + return (0); +} + +/* + * CCITT Group 3 1-D Modified Huffman RLE Compression Support. + * (Compression algorithms 2 and 32771) + */ + +/* + * Decode the requested amount of RLE-encoded data. + */ +static int +Fax3DecodeRLE(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +{ + DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); + int mode = sp->b.mode; + + (void) s; + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while ((long)occ > 0) { + a0 = 0; + RunLength = 0; + pa = thisrun; +#ifdef FAX3_DEBUG + printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); +#endif + EXPAND1D(EOFRLE); + (*sp->fill)(buf, thisrun, pa, lastx); + /* + * Cleanup at the end of the row. + */ + if (mode & FAXMODE_BYTEALIGN) { + int n = BitsAvail - (BitsAvail &~ 7); + ClrBits(n); + } else if (mode & FAXMODE_WORDALIGN) { + int n = BitsAvail - (BitsAvail &~ 15); + ClrBits(n); + if (BitsAvail == 0 && !isAligned(cp, uint16)) + cp++; + } + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + if (occ != 0) + tif->tif_row++; + continue; + EOFRLE: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); +} + +int +TIFFInitCCITTRLE(TIFF* tif, int scheme) +{ + if (InitCCITTFax3(tif)) { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and byte-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN); + } else + return (0); +} + +int +TIFFInitCCITTRLEW(TIFF* tif, int scheme) +{ + if (InitCCITTFax3(tif)) { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and word-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN); + } else + return (0); +} +#endif /* CCITT_SUPPORT */ diff --git a/libtiff/tif_fax3.h b/libtiff/tif_fax3.h new file mode 100644 index 00000000..5e68e386 --- /dev/null +++ b/libtiff/tif_fax3.h @@ -0,0 +1,522 @@ +/* $Id: tif_fax3.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _FAX3_ +#define _FAX3_ +/* + * TIFF Library. + * + * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support. + * + * Decoder support is derived, with permission, from the code + * in Frank Cringle's viewfax program; + * Copyright (C) 1990, 1995 Frank D. Cringle. + */ +#include "tiff.h" + +/* + * To override the default routine used to image decoded + * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC. + * The routine must have the type signature given below; + * for example: + * + * fillruns(unsigned char* buf, uint16* runs, uint16* erun, uint32 lastx) + * + * where buf is place to set the bits, runs is the array of b&w run + * lengths (white then black), erun is the last run in the array, and + * lastx is the width of the row in pixels. Fill routines can assume + * the run array has room for at least lastx runs and can overwrite + * data in the run array as needed (e.g. to append zero runs to bring + * the count up to a nice multiple). + */ +typedef void (*TIFFFaxFillFunc)(unsigned char*, uint16*, uint16*, uint32); + +/* + * The default run filler; made external for other decoders. + */ +#if defined(__cplusplus) +extern "C" { +#endif +extern void _TIFFFax3fillruns(unsigned char*, uint16*, uint16*, uint32); +#if defined(__cplusplus) +} +#endif + + +/* finite state machine codes */ +#define S_Null 0 +#define S_Pass 1 +#define S_Horiz 2 +#define S_V0 3 +#define S_VR 4 +#define S_VL 5 +#define S_Ext 6 +#define S_TermW 7 +#define S_TermB 8 +#define S_MakeUpW 9 +#define S_MakeUpB 10 +#define S_MakeUp 11 +#define S_EOL 12 + +typedef struct { /* state table entry */ + unsigned char State; /* see above */ + unsigned char Width; /* width of code in bits */ + uint16 Param; /* unsigned 16-bit run length in bits */ +} TIFFFaxTabEnt; + +extern const TIFFFaxTabEnt TIFFFaxMainTable[]; +extern const TIFFFaxTabEnt TIFFFaxWhiteTable[]; +extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; + +/* + * The following macros define the majority of the G3/G4 decoder + * algorithm using the state tables defined elsewhere. To build + * a decoder you need some setup code and some glue code. Note + * that you may also need/want to change the way the NeedBits* + * macros get input data if, for example, you know the data to be + * decoded is properly aligned and oriented (doing so before running + * the decoder can be a big performance win). + * + * Consult the decoder in the TIFF library for an idea of what you + * need to define and setup to make use of these definitions. + * + * NB: to enable a debugging version of these macros define FAX3_DEBUG + * before including this file. Trace output goes to stdout. + */ + +#ifndef EndOfData +#define EndOfData() (cp >= ep) +#endif +/* + * Need <=8 or <=16 bits of input data. Unlike viewfax we + * cannot use/assume a word-aligned, properly bit swizzled + * input data set because data may come from an arbitrarily + * aligned, read-only source such as a memory-mapped file. + * Note also that the viewfax decoder does not check for + * running off the end of the input data buffer. This is + * possible for G3-encoded data because it prescans the input + * data to count EOL markers, but can cause problems for G4 + * data. In any event, we don't prescan and must watch for + * running out of data since we can't permit the library to + * scan past the end of the input data buffer. + * + * Finally, note that we must handle remaindered data at the end + * of a strip specially. The coder asks for a fixed number of + * bits when scanning for the next code. This may be more bits + * than are actually present in the data stream. If we appear + * to run out of data but still have some number of valid bits + * remaining then we makeup the requested amount with zeros and + * return successfully. If the returned data is incorrect then + * we should be called again and get a premature EOF error; + * otherwise we should get the right answer. + */ +#ifndef NeedBits8 +#define NeedBits8(n,eoflab) do { \ + if (BitsAvail < (n)) { \ + if (EndOfData()) { \ + if (BitsAvail == 0) /* no valid bits */ \ + goto eoflab; \ + BitsAvail = (n); /* pad with zeros */ \ + } else { \ + BitAcc |= ((uint32) bitmap[*cp++])<>= (n); \ +} while (0) + +#ifdef FAX3_DEBUG +static const char* StateNames[] = { + "Null ", + "Pass ", + "Horiz ", + "V0 ", + "VR ", + "VL ", + "Ext ", + "TermW ", + "TermB ", + "MakeUpW", + "MakeUpB", + "MakeUp ", + "EOL ", +}; +#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0') +#define LOOKUP8(wid,tab,eoflab) do { \ + int t; \ + NeedBits8(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ +} while (0) +#define LOOKUP16(wid,tab,eoflab) do { \ + int t; \ + NeedBits16(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ +} while (0) + +#define SETVAL(x) do { \ + *pa++ = RunLength + (x); \ + printf("SETVAL: %d\t%d\n", RunLength + (x), a0); \ + a0 += x; \ + RunLength = 0; \ +} while (0) +#else +#define LOOKUP8(wid,tab,eoflab) do { \ + NeedBits8(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ +} while (0) +#define LOOKUP16(wid,tab,eoflab) do { \ + NeedBits16(wid,eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ +} while (0) + +/* + * Append a run to the run length array for the + * current row and reset decoding state. + */ +#define SETVAL(x) do { \ + *pa++ = RunLength + (x); \ + a0 += (x); \ + RunLength = 0; \ +} while (0) +#endif + +/* + * Synchronize input decoding at the start of each + * row by scanning for an EOL (if appropriate) and + * skipping any trash data that might be present + * after a decoding error. Note that the decoding + * done elsewhere that recognizes an EOL only consumes + * 11 consecutive zero bits. This means that if EOLcnt + * is non-zero then we still need to scan for the final flag + * bit that is part of the EOL code. + */ +#define SYNC_EOL(eoflab) do { \ + if (EOLcnt == 0) { \ + for (;;) { \ + NeedBits16(11,eoflab); \ + if (GetBits(11) == 0) \ + break; \ + ClrBits(1); \ + } \ + } \ + for (;;) { \ + NeedBits8(8,eoflab); \ + if (GetBits(8)) \ + break; \ + ClrBits(8); \ + } \ + while (GetBits(1) == 0) \ + ClrBits(1); \ + ClrBits(1); /* EOL bit */ \ + EOLcnt = 0; /* reset EOL counter/flag */ \ +} while (0) + +/* + * Cleanup the array of runs after decoding a row. + * We adjust final runs to insure the user buffer is not + * overwritten and/or undecoded area is white filled. + */ +#define CLEANUP_RUNS() do { \ + if (RunLength) \ + SETVAL(0); \ + if (a0 != lastx) { \ + badlength(a0, lastx); \ + while (a0 > lastx && pa > thisrun) \ + a0 -= *--pa; \ + if (a0 < lastx) { \ + if (a0 < 0) \ + a0 = 0; \ + if ((pa-thisrun)&1) \ + SETVAL(0); \ + SETVAL(lastx - a0); \ + } else if (a0 > lastx) { \ + SETVAL(lastx); \ + SETVAL(0); \ + } \ + } \ +} while (0) + +/* + * Decode a line of 1D-encoded data. + * + * The line expanders are written as macros so that they can be reused + * but still have direct access to the local variables of the "calling" + * function. + * + * Note that unlike the original version we have to explicitly test for + * a0 >= lastx after each black/white run is decoded. This is because + * the original code depended on the input data being zero-padded to + * insure the decoder recognized an EOL before running out of data. + */ +#define EXPAND1D(eoflab) do { \ + for (;;) { \ + for (;;) { \ + LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ + switch (TabEnt->State) { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermW: \ + SETVAL(TabEnt->Param); \ + goto doneWhite1d; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("WhiteTable", a0); \ + goto done1d; \ + } \ + } \ + doneWhite1d: \ + if (a0 >= lastx) \ + goto done1d; \ + for (;;) { \ + LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ + switch (TabEnt->State) { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermB: \ + SETVAL(TabEnt->Param); \ + goto doneBlack1d; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("BlackTable", a0); \ + goto done1d; \ + } \ + } \ + doneBlack1d: \ + if (a0 >= lastx) \ + goto done1d; \ + } \ +eof1d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ +done1d: \ + CLEANUP_RUNS(); \ +} while (0) + +/* + * Update the value of b1 using the array + * of runs for the reference line. + */ +#define CHECK_b1 do { \ + if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \ + b1 += pb[0] + pb[1]; \ + pb += 2; \ + } \ +} while (0) + +/* + * Expand a row of 2D-encoded data. + */ +#define EXPAND2D(eoflab) do { \ + while (a0 < lastx) { \ + LOOKUP8(7, TIFFFaxMainTable, eof2d); \ + switch (TabEnt->State) { \ + case S_Pass: \ + CHECK_b1; \ + b1 += *pb++; \ + RunLength += b1 - a0; \ + a0 = b1; \ + b1 += *pb++; \ + break; \ + case S_Horiz: \ + if ((pa-thisrun)&1) { \ + for (;;) { /* black first */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermB: \ + SETVAL(TabEnt->Param); \ + goto doneWhite2da; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneWhite2da:; \ + for (;;) { /* then white */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermW: \ + SETVAL(TabEnt->Param); \ + goto doneBlack2da; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneBlack2da:; \ + } else { \ + for (;;) { /* white first */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermW: \ + SETVAL(TabEnt->Param); \ + goto doneWhite2db; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneWhite2db:; \ + for (;;) { /* then black */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) { \ + case S_TermB: \ + SETVAL(TabEnt->Param); \ + goto doneBlack2db; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneBlack2db:; \ + } \ + CHECK_b1; \ + break; \ + case S_V0: \ + CHECK_b1; \ + SETVAL(b1 - a0); \ + b1 += *pb++; \ + break; \ + case S_VR: \ + CHECK_b1; \ + SETVAL(b1 - a0 + TabEnt->Param); \ + b1 += *pb++; \ + break; \ + case S_VL: \ + CHECK_b1; \ + SETVAL(b1 - a0 - TabEnt->Param); \ + b1 -= *--pb; \ + break; \ + case S_Ext: \ + *pa++ = lastx - a0; \ + extension(a0); \ + goto eol2d; \ + case S_EOL: \ + *pa++ = lastx - a0; \ + NeedBits8(5,eof2d); \ + if (GetBits(5)) \ + unexpected("EOL", a0); \ + EOLcnt = 1; \ + goto eol2d; \ + default: \ + badMain2d: \ + unexpected("MainTable", a0); \ + goto eol2d; \ + badBlack2d: \ + unexpected("BlackTable", a0); \ + goto eol2d; \ + badWhite2d: \ + unexpected("WhiteTable", a0); \ + goto eol2d; \ + eof2d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ + } \ + } \ + if (RunLength) { \ + if (RunLength + a0 < lastx) { \ + /* expect a final V0 */ \ + NeedBits8(1,eof2d); \ + if (!GetBits(1)) \ + goto badMain2d; \ + ClrBits(1); \ + } \ + SETVAL(0); \ + } \ +eol2d: \ + CLEANUP_RUNS(); \ +} while (0) +#endif /* _FAX3_ */ diff --git a/libtiff/tif_flush.c b/libtiff/tif_flush.c new file mode 100644 index 00000000..e93196d1 --- /dev/null +++ b/libtiff/tif_flush.c @@ -0,0 +1,60 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_flush.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +int +TIFFFlush(TIFF* tif) +{ + + if (tif->tif_mode != O_RDONLY) { + if (!TIFFFlushData(tif)) + return (0); + if ((tif->tif_flags & TIFF_DIRTYDIRECT) && + !TIFFWriteDirectory(tif)) + return (0); + } + return (1); +} + +/* + * Flush buffered data to the file. + */ +int +TIFFFlushData(TIFF* tif) +{ + if ((tif->tif_flags & TIFF_BEENWRITING) == 0) + return (0); + if (tif->tif_flags & TIFF_POSTENCODE) { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + return (0); + } + return (TIFFFlushData1(tif)); +} diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c new file mode 100644 index 00000000..c07fdbca --- /dev/null +++ b/libtiff/tif_getimage.c @@ -0,0 +1,1850 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_getimage.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library + * + * Read and return a packed RGBA image. + */ +#include "tiffiop.h" +#include +#include + +static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); +static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); +static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32); +static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); +static int pickTileContigCase(TIFFRGBAImage*); +static int pickTileSeparateCase(TIFFRGBAImage*); + +static const char photoTag[] = "PhotometricInterpretation"; + +/* + * Check the image to see if TIFFReadRGBAImage can deal with it. + * 1/0 is returned according to whether or not the image can + * be handled. If 0 is returned, emsg contains the reason + * why it is being rejected. + */ +int +TIFFRGBAImageOK(TIFF* tif, char emsg[1024]) +{ + TIFFDirectory* td = &tif->tif_dir; + uint16 photometric; + int colorchannels; + + switch (td->td_bitspersample) { + case 1: case 2: case 4: + case 8: case 16: + break; + default: + sprintf(emsg, "Sorry, can not handle images with %d-bit samples", + td->td_bitspersample); + return (0); + } + colorchannels = td->td_samplesperpixel - td->td_extrasamples; + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + switch (colorchannels) { + case 1: + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + photometric = PHOTOMETRIC_RGB; + break; + default: + sprintf(emsg, "Missing needed %s tag", photoTag); + return (0); + } + } + switch (photometric) { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_samplesperpixel != 1) { + sprintf(emsg, + "Sorry, can not handle contiguous data with %s=%d, and %s=%d", + photoTag, photometric, + "Samples/pixel", td->td_samplesperpixel); + return (0); + } + break; + case PHOTOMETRIC_YCBCR: + if (td->td_planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d", + "Planarconfiguration", td->td_planarconfig); + return (0); + } + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) { + sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + return (0); + } + break; +#ifdef CMYK_SUPPORT + case PHOTOMETRIC_SEPARATED: + if (td->td_inkset != INKSET_CMYK) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "InkSet", td->td_inkset); + return (0); + } + if (td->td_samplesperpixel != 4) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "Samples/pixel", td->td_samplesperpixel); + return (0); + } + break; +#endif + case PHOTOMETRIC_LOGL: + if (td->td_compression != COMPRESSION_SGILOG) { + sprintf(emsg, "Sorry, LogL data must have %s=%d", + "Compression", COMPRESSION_SGILOG); + return (0); + } + break; + case PHOTOMETRIC_LOGLUV: + if (td->td_compression != COMPRESSION_SGILOG && + td->td_compression != COMPRESSION_SGILOG24) { + sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); + return (0); + } + if (td->td_planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", + "Planarconfiguration", td->td_planarconfig); + return (0); + } + break; + default: + sprintf(emsg, "Sorry, can not handle image with %s=%d", + photoTag, photometric); + return (0); + } + return (1); +} + +void +TIFFRGBAImageEnd(TIFFRGBAImage* img) +{ + if (img->Map) + _TIFFfree(img->Map), img->Map = NULL; + if (img->BWmap) + _TIFFfree(img->BWmap), img->BWmap = NULL; + if (img->PALmap) + _TIFFfree(img->PALmap), img->PALmap = NULL; + if (img->ycbcr) + _TIFFfree(img->ycbcr), img->ycbcr = NULL; +} + +static int +isCCITTCompression(TIFF* tif) +{ + uint16 compress; + TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); + return (compress == COMPRESSION_CCITTFAX3 || + compress == COMPRESSION_CCITTFAX4 || + compress == COMPRESSION_CCITTRLE || + compress == COMPRESSION_CCITTRLEW); +} + +int +TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024]) +{ + uint16* sampleinfo; + uint16 extrasamples; + uint16 planarconfig; + uint16 compress; + int colorchannels; + + img->tif = tif; + img->stoponerr = stop; + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); + switch (img->bitspersample) { + case 1: case 2: case 4: + case 8: case 16: + break; + default: + sprintf(emsg, "Sorry, can not image with %d-bit samples", + img->bitspersample); + return (0); + } + img->alpha = 0; + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, + &extrasamples, &sampleinfo); + if (extrasamples == 1) + switch (sampleinfo[0]) { + case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ + case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ + img->alpha = sampleinfo[0]; + break; + } + colorchannels = img->samplesperpixel - extrasamples; + TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); + TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { + switch (colorchannels) { + case 1: + if (isCCITTCompression(tif)) + img->photometric = PHOTOMETRIC_MINISWHITE; + else + img->photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + img->photometric = PHOTOMETRIC_RGB; + break; + default: + sprintf(emsg, "Missing needed %s tag", photoTag); + return (0); + } + } + switch (img->photometric) { + case PHOTOMETRIC_PALETTE: + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, + &img->redcmap, &img->greencmap, &img->bluecmap)) { + TIFFError(TIFFFileName(tif), "Missing required \"Colormap\" tag"); + return (0); + } + /* fall thru... */ + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (planarconfig == PLANARCONFIG_CONTIG && img->samplesperpixel != 1) { + sprintf(emsg, + "Sorry, can not handle contiguous data with %s=%d, and %s=%d", + photoTag, img->photometric, + "Samples/pixel", img->samplesperpixel); + return (0); + } + break; + case PHOTOMETRIC_YCBCR: + if (planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d", + "Planarconfiguration", planarconfig); + return (0); + } + /* It would probably be nice to have a reality check here. */ + if (compress == COMPRESSION_JPEG && planarconfig == PLANARCONFIG_CONTIG) { + /* can rely on libjpeg to convert to RGB */ + /* XXX should restore current state on exit */ + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); + img->photometric = PHOTOMETRIC_RGB; + } + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) { + sprintf(emsg, "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + return (0); + } + break; + case PHOTOMETRIC_SEPARATED: { + uint16 inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "InkSet", inkset); + return (0); + } + if (img->samplesperpixel != 4) { + sprintf(emsg, "Sorry, can not handle separated image with %s=%d", + "Samples/pixel", img->samplesperpixel); + return (0); + } + break; + } + case PHOTOMETRIC_LOGL: + if (compress != COMPRESSION_SGILOG) { + sprintf(emsg, "Sorry, LogL data must have %s=%d", + "Compression", COMPRESSION_SGILOG); + return (0); + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_LOGLUV: + if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { + sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); + return (0); + } + if (planarconfig != PLANARCONFIG_CONTIG) { + sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d", + "Planarconfiguration", planarconfig); + return (0); + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_RGB; /* little white lie */ + img->bitspersample = 8; + break; + default: + sprintf(emsg, "Sorry, can not handle image with %s=%d", + photoTag, img->photometric); + return (0); + } + img->Map = NULL; + img->BWmap = NULL; + img->PALmap = NULL; + img->ycbcr = NULL; + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); + TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); + img->isContig = + !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1); + if (img->isContig) { + img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig; + (void) pickTileContigCase(img); + } else { + img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate; + (void) pickTileSeparateCase(img); + } + return (1); +} + +int +TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + if (img->get == NULL) { + TIFFError(TIFFFileName(img->tif), "No \"get\" routine setup"); + return (0); + } + if (img->put.any == NULL) { + TIFFError(TIFFFileName(img->tif), + "No \"put\" routine setupl; probably can not handle image format"); + return (0); + } + return (*img->get)(img, raster, w, h); +} + +/* + * Read the specified image into an ABGR-format raster. + */ +int +TIFFReadRGBAImage(TIFF* tif, + uint32 rwidth, uint32 rheight, uint32* raster, int stop) +{ + char emsg[1024]; + TIFFRGBAImage img; + int ok; + + if (TIFFRGBAImageBegin(&img, tif, stop, emsg)) { + /* XXX verify rwidth and rheight against width and height */ + ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, + rwidth, img.height); + TIFFRGBAImageEnd(&img); + } else { + TIFFError(TIFFFileName(tif), emsg); + ok = 0; + } + return (ok); +} + +static uint32 +setorientation(TIFFRGBAImage* img, uint32 h) +{ + TIFF* tif = img->tif; + uint32 y; + + switch (img->orientation) { + case ORIENTATION_BOTRIGHT: + case ORIENTATION_RIGHTBOT: /* XXX */ + case ORIENTATION_LEFTBOT: /* XXX */ + TIFFWarning(TIFFFileName(tif), "using bottom-left orientation"); + img->orientation = ORIENTATION_BOTLEFT; + /* fall thru... */ + case ORIENTATION_BOTLEFT: + y = 0; + break; + case ORIENTATION_TOPRIGHT: + case ORIENTATION_RIGHTTOP: /* XXX */ + case ORIENTATION_LEFTTOP: /* XXX */ + default: + TIFFWarning(TIFFFileName(tif), "using top-left orientation"); + img->orientation = ORIENTATION_TOPLEFT; + /* fall thru... */ + case ORIENTATION_TOPLEFT: + y = h-1; + break; + } + return (y); +} + +/* + * Get an tile-organized image that has + * PlanarConfiguration contiguous if SamplesPerPixel > 1 + * or + * SamplesPerPixel == 1 + */ +static int +gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileContigRoutine put = img->put.contig; + uint16 orientation; + uint32 col, row, y; + uint32 tw, th; + u_char* buf; + int32 fromskew, toskew; + uint32 nrow; + + buf = (u_char*) _TIFFmalloc(TIFFTileSize(tif)); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + y = setorientation(img, h); + orientation = img->orientation; + toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? tw+w : tw-w); + for (row = 0; row < h; row += th) { + nrow = (row + th > h ? h - row : th); + for (col = 0; col < w; col += tw) { + if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 && img->stoponerr) + break; + if (col + tw > w) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + uint32 npix = w - col; + fromskew = tw - npix; + (*put)(img, raster+y*w+col, col, y, + npix, nrow, fromskew, toskew + fromskew, buf); + } else { + (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf); + } + } + y += (orientation == ORIENTATION_TOPLEFT ? + -(int32) nrow : (int32) nrow); + } + _TIFFfree(buf); + return (1); +} + +/* + * Get an tile-organized image that has + * SamplesPerPixel > 1 + * PlanarConfiguration separated + * We assume that all such images are RGB. + */ +static int +gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileSeparateRoutine put = img->put.separate; + uint16 orientation; + uint32 col, row, y; + uint32 tw, th; + u_char* buf; + u_char* r; + u_char* g; + u_char* b; + u_char* a; + tsize_t tilesize; + int32 fromskew, toskew; + int alpha = img->alpha; + uint32 nrow; + + tilesize = TIFFTileSize(tif); + buf = (u_char*) _TIFFmalloc(4*tilesize); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + r = buf; + g = r + tilesize; + b = g + tilesize; + a = b + tilesize; + if (!alpha) + memset(a, 0xff, tilesize); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + y = setorientation(img, h); + orientation = img->orientation; + toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? tw+w : tw-w); + for (row = 0; row < h; row += th) { + nrow = (row + th > h ? h - row : th); + for (col = 0; col < w; col += tw) { + if (TIFFReadTile(tif, r, col, row,0,0) < 0 && img->stoponerr) + break; + if (TIFFReadTile(tif, g, col, row,0,1) < 0 && img->stoponerr) + break; + if (TIFFReadTile(tif, b, col, row,0,2) < 0 && img->stoponerr) + break; + if (alpha && TIFFReadTile(tif,a,col,row,0,3) < 0 && img->stoponerr) + break; + if (col + tw > w) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + uint32 npix = w - col; + fromskew = tw - npix; + (*put)(img, raster+y*w+col, col, y, + npix, nrow, fromskew, toskew + fromskew, r, g, b, a); + } else { + (*put)(img, raster+y*w+col, col, y, + tw, nrow, 0, toskew, r, g, b, a); + } + } + y += (orientation == ORIENTATION_TOPLEFT ? + -(int32) nrow : (int32) nrow); + } + _TIFFfree(buf); + return (1); +} + +/* + * Get a strip-organized image that has + * PlanarConfiguration contiguous if SamplesPerPixel > 1 + * or + * SamplesPerPixel == 1 + */ +static int +gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileContigRoutine put = img->put.contig; + uint16 orientation; + uint32 row, y, nrow; + u_char* buf; + uint32 rowsperstrip; + uint32 imagewidth = img->width; + tsize_t scanline; + int32 fromskew, toskew; + + buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif)); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for strip buffer"); + return (0); + } + y = setorientation(img, h); + orientation = img->orientation; + toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w); + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += rowsperstrip) { + nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), + buf, nrow*scanline) < 0 && img->stoponerr) + break; + (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf); + y += (orientation == ORIENTATION_TOPLEFT ? + -(int32) nrow : (int32) nrow); + } + _TIFFfree(buf); + return (1); +} + +/* + * Get a strip-organized image with + * SamplesPerPixel > 1 + * PlanarConfiguration separated + * We assume that all such images are RGB. + */ +static int +gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) +{ + TIFF* tif = img->tif; + tileSeparateRoutine put = img->put.separate; + uint16 orientation; + u_char *buf; + u_char *r, *g, *b, *a; + uint32 row, y, nrow; + tsize_t scanline; + uint32 rowsperstrip; + uint32 imagewidth = img->width; + tsize_t stripsize; + int32 fromskew, toskew; + int alpha = img->alpha; + + stripsize = TIFFStripSize(tif); + r = buf = (u_char *)_TIFFmalloc(4*stripsize); + if (buf == 0) { + TIFFError(TIFFFileName(tif), "No space for tile buffer"); + return (0); + } + g = r + stripsize; + b = g + stripsize; + a = b + stripsize; + if (!alpha) + memset(a, 0xff, stripsize); + y = setorientation(img, h); + orientation = img->orientation; + toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w); + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += rowsperstrip) { + nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), + r, nrow*scanline) < 0 && img->stoponerr) + break; + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1), + g, nrow*scanline) < 0 && img->stoponerr) + break; + if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2), + b, nrow*scanline) < 0 && img->stoponerr) + break; + if (alpha && + (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3), + a, nrow*scanline) < 0 && img->stoponerr)) + break; + (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, r, g, b, a); + y += (orientation == ORIENTATION_TOPLEFT ? + -(int32) nrow : (int32) nrow); + } + _TIFFfree(buf); + return (1); +} + +/* + * The following routines move decoded data returned + * from the TIFF library into rasters filled with packed + * ABGR pixels (i.e. suitable for passing to lrecwrite.) + * + * The routines have been created according to the most + * important cases and optimized. pickTileContigCase and + * pickTileSeparateCase analyze the parameters and select + * the appropriate "put" routine to use. + */ +#define REPEAT8(op) REPEAT4(op); REPEAT4(op) +#define REPEAT4(op) REPEAT2(op); REPEAT2(op) +#define REPEAT2(op) op; op +#define CASE8(x,op) \ + switch (x) { \ + case 7: op; case 6: op; case 5: op; \ + case 4: op; case 3: op; case 2: op; \ + case 1: op; \ + } +#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; } +#define NOP + +#define UNROLL8(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 8; _x -= 8) { \ + op1; \ + REPEAT8(op2); \ + } \ + if (_x > 0) { \ + op1; \ + CASE8(_x,op2); \ + } \ +} +#define UNROLL4(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 4; _x -= 4) { \ + op1; \ + REPEAT4(op2); \ + } \ + if (_x > 0) { \ + op1; \ + CASE4(_x,op2); \ + } \ +} +#define UNROLL2(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 2; _x -= 2) { \ + op1; \ + REPEAT2(op2); \ + } \ + if (_x) { \ + op1; \ + op2; \ + } \ +} + +#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } +#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } + +#define A1 ((uint32)(0xffL<<24)) +#define PACK(r,g,b) \ + ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) +#define PACK4(r,g,b,a) \ + ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) +#define W2B(v) (((v)>>8)&0xff) +#define PACKW(r,g,b) \ + ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) +#define PACKW4(r,g,b,a) \ + ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) + +#define DECLAREContigPutFunc(name) \ +static void name(\ + TIFFRGBAImage* img, \ + uint32* cp, \ + uint32 x, uint32 y, \ + uint32 w, uint32 h, \ + int32 fromskew, int32 toskew, \ + u_char* pp \ +) + +/* + * 8-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put8bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + while (h-- > 0) { + UNROLL8(w, NOP, *cp++ = PALmap[*pp++][0]); + cp += toskew; + pp += fromskew; + } +} + +/* + * 4-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put4bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + fromskew /= 2; + while (h-- > 0) { + uint32* bw; + UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 2-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put2bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + fromskew /= 4; + while (h-- > 0) { + uint32* bw; + UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 1-bit palette => colormap/RGB + */ +DECLAREContigPutFunc(put1bitcmaptile) +{ + uint32** PALmap = img->PALmap; + + (void) x; (void) y; + fromskew /= 8; + while (h-- > 0) { + uint32* bw; + UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(putgreytile) +{ + uint32** BWmap = img->BWmap; + + (void) y; + while (h-- > 0) { + for (x = w; x-- > 0;) + *cp++ = BWmap[*pp++][0]; + cp += toskew; + pp += fromskew; + } +} + +/* + * 1-bit bilevel => colormap/RGB + */ +DECLAREContigPutFunc(put1bitbwtile) +{ + uint32** BWmap = img->BWmap; + + (void) x; (void) y; + fromskew /= 8; + while (h-- > 0) { + uint32* bw; + UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 2-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(put2bitbwtile) +{ + uint32** BWmap = img->BWmap; + + (void) x; (void) y; + fromskew /= 4; + while (h-- > 0) { + uint32* bw; + UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 4-bit greyscale => colormap/RGB + */ +DECLAREContigPutFunc(put4bitbwtile) +{ + uint32** BWmap = img->BWmap; + + (void) x; (void) y; + fromskew /= 2; + while (h-- > 0) { + uint32* bw; + UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed samples, no Map => RGB + */ +DECLAREContigPutFunc(putRGBcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + + (void) x; (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + UNROLL8(w, NOP, + *cp++ = PACK(pp[0], pp[1], pp[2]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed samples, w/ Map => RGB + */ +DECLAREContigPutFunc(putRGBcontig8bitMaptile) +{ + TIFFRGBValue* Map = img->Map; + int samplesperpixel = img->samplesperpixel; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]); + pp += samplesperpixel; + } + pp += fromskew; + cp += toskew; + } +} + +/* + * 8-bit packed samples => RGBA w/ associated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBAAcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + + (void) x; (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + UNROLL8(w, NOP, + *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed samples => RGBA w/ unassociated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBUAcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + uint32 r, g, b, a; + for (x = w; x-- > 0;) { + a = pp[3]; + r = (pp[0] * a) / 255; + g = (pp[1] * a) / 255; + b = (pp[2] * a) / 255; + *cp++ = PACK4(r,g,b,a); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } +} + +/* + * 16-bit packed samples => RGB + */ +DECLAREContigPutFunc(putRGBcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 *wp = (uint16 *)pp; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = PACKW(wp[0], wp[1], wp[2]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } +} + +/* + * 16-bit packed samples => RGBA w/ associated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBAAcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 *wp = (uint16 *)pp; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = PACKW4(wp[0], wp[1], wp[2], wp[3]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } +} + +/* + * 16-bit packed samples => RGBA w/ unassociated alpha + * (known to have Map == NULL) + */ +DECLAREContigPutFunc(putRGBUAcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 *wp = (uint16 *)pp; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + uint32 r,g,b,a; + /* + * We shift alpha down four bits just in case unsigned + * arithmetic doesn't handle the full range. + * We still have plenty of accuracy, since the output is 8 bits. + * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff) + * Since we want r*a * 0xff for eight bit output, + * we divide by (0xffff * 0xfff) / 0xff == 0x10eff. + */ + for (x = w; x-- > 0;) { + a = wp[3] >> 4; + r = (wp[0] * a) / 0x10eff; + g = (wp[1] * a) / 0x10eff; + b = (wp[2] * a) / 0x10eff; + *cp++ = PACK4(r,g,b,a); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } +} + +/* + * 8-bit packed CMYK samples w/o Map => RGB + * + * NB: The conversion of CMYK->RGB is *very* crude. + */ +DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) +{ + int samplesperpixel = img->samplesperpixel; + uint16 r, g, b, k; + + (void) x; (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + UNROLL8(w, NOP, + k = 255 - pp[3]; + r = (k*(255-pp[0]))/255; + g = (k*(255-pp[1]))/255; + b = (k*(255-pp[2]))/255; + *cp++ = PACK(r, g, b); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } +} + +/* + * 8-bit packed CMYK samples w/Map => RGB + * + * NB: The conversion of CMYK->RGB is *very* crude. + */ +DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) +{ + int samplesperpixel = img->samplesperpixel; + TIFFRGBValue* Map = img->Map; + uint16 r, g, b, k; + + (void) y; + fromskew *= samplesperpixel; + while (h-- > 0) { + for (x = w; x-- > 0;) { + k = 255 - pp[3]; + r = (k*(255-pp[0]))/255; + g = (k*(255-pp[1]))/255; + b = (k*(255-pp[2]))/255; + *cp++ = PACK(Map[r], Map[g], Map[b]); + pp += samplesperpixel; + } + pp += fromskew; + cp += toskew; + } +} + +#define DECLARESepPutFunc(name) \ +static void name(\ + TIFFRGBAImage* img,\ + uint32* cp,\ + uint32 x, uint32 y, \ + uint32 w, uint32 h,\ + int32 fromskew, int32 toskew,\ + u_char* r, u_char* g, u_char* b, u_char* a\ +) + +/* + * 8-bit unpacked samples => RGB + */ +DECLARESepPutFunc(putRGBseparate8bittile) +{ + (void) img; (void) x; (void) y; (void) a; + while (h-- > 0) { + UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); + SKEW(r, g, b, fromskew); + cp += toskew; + } +} + +/* + * 8-bit unpacked samples => RGB + */ +DECLARESepPutFunc(putRGBseparate8bitMaptile) +{ + TIFFRGBValue* Map = img->Map; + + (void) y; (void) a; + while (h-- > 0) { + for (x = w; x > 0; x--) + *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]); + SKEW(r, g, b, fromskew); + cp += toskew; + } +} + +/* + * 8-bit unpacked samples => RGBA w/ associated alpha + */ +DECLARESepPutFunc(putRGBAAseparate8bittile) +{ + (void) img; (void) x; (void) y; + while (h-- > 0) { + UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } +} + +/* + * 8-bit unpacked samples => RGBA w/ unassociated alpha + */ +DECLARESepPutFunc(putRGBUAseparate8bittile) +{ + (void) img; (void) y; + while (h-- > 0) { + uint32 rv, gv, bv, av; + for (x = w; x-- > 0;) { + av = *a++; + rv = (*r++ * av) / 255; + gv = (*g++ * av) / 255; + bv = (*b++ * av) / 255; + *cp++ = PACK4(rv,gv,bv,av); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } +} + +/* + * 16-bit unpacked samples => RGB + */ +DECLARESepPutFunc(putRGBseparate16bittile) +{ + uint16 *wr = (uint16*) r; + uint16 *wg = (uint16*) g; + uint16 *wb = (uint16*) b; + + (void) img; (void) y; (void) a; + while (h-- > 0) { + for (x = 0; x < w; x++) + *cp++ = PACKW(*wr++, *wg++, *wb++); + SKEW(wr, wg, wb, fromskew); + cp += toskew; + } +} + +/* + * 16-bit unpacked samples => RGBA w/ associated alpha + */ +DECLARESepPutFunc(putRGBAAseparate16bittile) +{ + uint16 *wr = (uint16*) r; + uint16 *wg = (uint16*) g; + uint16 *wb = (uint16*) b; + uint16 *wa = (uint16*) a; + + (void) img; (void) y; + while (h-- > 0) { + for (x = 0; x < w; x++) + *cp++ = PACKW4(*wr++, *wg++, *wb++, *wa++); + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } +} + +/* + * 16-bit unpacked samples => RGBA w/ unassociated alpha + */ +DECLARESepPutFunc(putRGBUAseparate16bittile) +{ + uint16 *wr = (uint16*) r; + uint16 *wg = (uint16*) g; + uint16 *wb = (uint16*) b; + uint16 *wa = (uint16*) a; + + (void) img; (void) y; + while (h-- > 0) { + uint32 r,g,b,a; + /* + * We shift alpha down four bits just in case unsigned + * arithmetic doesn't handle the full range. + * We still have plenty of accuracy, since the output is 8 bits. + * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff) + * Since we want r*a * 0xff for eight bit output, + * we divide by (0xffff * 0xfff) / 0xff == 0x10eff. + */ + for (x = w; x-- > 0;) { + a = *wa++ >> 4; + r = (*wr++ * a) / 0x10eff; + g = (*wg++ * a) / 0x10eff; + b = (*wb++ * a) / 0x10eff; + *cp++ = PACK4(r,g,b,a); + } + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } +} + +/* + * YCbCr -> RGB conversion and packing routines. The colorspace + * conversion algorithm comes from the IJG v5a code; see below + * for more information on how it works. + */ + +#define YCbCrtoRGB(dst, yc) { \ + int Y = (yc); \ + dst = PACK( \ + clamptab[Y+Crrtab[Cr]], \ + clamptab[Y + (int)((Cbgtab[Cb]+Crgtab[Cr])>>16)], \ + clamptab[Y+Cbbtab[Cb]]); \ +} +#define YCbCrSetup \ + TIFFYCbCrToRGB* ycbcr = img->ycbcr; \ + int* Crrtab = ycbcr->Cr_r_tab; \ + int* Cbbtab = ycbcr->Cb_b_tab; \ + int32* Crgtab = ycbcr->Cr_g_tab; \ + int32* Cbgtab = ycbcr->Cb_g_tab; \ + TIFFRGBValue* clamptab = ycbcr->clamptab + +/* + * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr44tile) +{ + YCbCrSetup; + uint32* cp1 = cp+w+toskew; + uint32* cp2 = cp1+w+toskew; + uint32* cp3 = cp2+w+toskew; + int32 incr = 3*w+4*toskew; + + (void) y; + /* XXX adjust fromskew */ + for (; h >= 4; h -= 4) { + x = w>>2; + do { + int Cb = pp[16]; + int Cr = pp[17]; + + YCbCrtoRGB(cp [0], pp[ 0]); + YCbCrtoRGB(cp [1], pp[ 1]); + YCbCrtoRGB(cp [2], pp[ 2]); + YCbCrtoRGB(cp [3], pp[ 3]); + YCbCrtoRGB(cp1[0], pp[ 4]); + YCbCrtoRGB(cp1[1], pp[ 5]); + YCbCrtoRGB(cp1[2], pp[ 6]); + YCbCrtoRGB(cp1[3], pp[ 7]); + YCbCrtoRGB(cp2[0], pp[ 8]); + YCbCrtoRGB(cp2[1], pp[ 9]); + YCbCrtoRGB(cp2[2], pp[10]); + YCbCrtoRGB(cp2[3], pp[11]); + YCbCrtoRGB(cp3[0], pp[12]); + YCbCrtoRGB(cp3[1], pp[13]); + YCbCrtoRGB(cp3[2], pp[14]); + YCbCrtoRGB(cp3[3], pp[15]); + + cp += 4, cp1 += 4, cp2 += 4, cp3 += 4; + pp += 18; + } while (--x); + cp += incr, cp1 += incr, cp2 += incr, cp3 += incr; + pp += fromskew; + } +} + +/* + * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr42tile) +{ + YCbCrSetup; + uint32* cp1 = cp+w+toskew; + int32 incr = 2*toskew+w; + + (void) y; + /* XXX adjust fromskew */ + for (; h >= 2; h -= 2) { + x = w>>2; + do { + int Cb = pp[8]; + int Cr = pp[9]; + + YCbCrtoRGB(cp [0], pp[0]); + YCbCrtoRGB(cp [1], pp[1]); + YCbCrtoRGB(cp [2], pp[2]); + YCbCrtoRGB(cp [3], pp[3]); + YCbCrtoRGB(cp1[0], pp[4]); + YCbCrtoRGB(cp1[1], pp[5]); + YCbCrtoRGB(cp1[2], pp[6]); + YCbCrtoRGB(cp1[3], pp[7]); + + cp += 4, cp1 += 4; + pp += 10; + } while (--x); + cp += incr, cp1 += incr; + pp += fromskew; + } +} + +/* + * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr41tile) +{ + YCbCrSetup; + + (void) y; + /* XXX adjust fromskew */ + do { + x = w>>2; + do { + int Cb = pp[4]; + int Cr = pp[5]; + + YCbCrtoRGB(cp [0], pp[0]); + YCbCrtoRGB(cp [1], pp[1]); + YCbCrtoRGB(cp [2], pp[2]); + YCbCrtoRGB(cp [3], pp[3]); + + cp += 4; + pp += 6; + } while (--x); + cp += toskew; + pp += fromskew; + } while (--h); +} + +/* + * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr22tile) +{ + YCbCrSetup; + uint32* cp1 = cp+w+toskew; + int32 incr = 2*toskew+w; + + (void) y; + /* XXX adjust fromskew */ + for (; h >= 2; h -= 2) { + x = w>>1; + do { + int Cb = pp[4]; + int Cr = pp[5]; + + YCbCrtoRGB(cp [0], pp[0]); + YCbCrtoRGB(cp [1], pp[1]); + YCbCrtoRGB(cp1[0], pp[2]); + YCbCrtoRGB(cp1[1], pp[3]); + + cp += 2, cp1 += 2; + pp += 6; + } while (--x); + cp += incr, cp1 += incr; + pp += fromskew; + } +} + +/* + * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr21tile) +{ + YCbCrSetup; + + (void) y; + /* XXX adjust fromskew */ + do { + x = w>>1; + do { + int Cb = pp[2]; + int Cr = pp[3]; + + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + + cp += 2; + pp += 4; + } while (--x); + cp += toskew; + pp += fromskew; + } while (--h); +} + +/* + * 8-bit packed YCbCr samples w/ no subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr11tile) +{ + YCbCrSetup; + + (void) y; + /* XXX adjust fromskew */ + do { + x = w>>1; + do { + int Cb = pp[1]; + int Cr = pp[2]; + + YCbCrtoRGB(*cp++, pp[0]); + + pp += 3; + } while (--x); + cp += toskew; + pp += fromskew; + } while (--h); +} +#undef YCbCrSetup +#undef YCbCrtoRGB + +#define LumaRed coeffs[0] +#define LumaGreen coeffs[1] +#define LumaBlue coeffs[2] +#define SHIFT 16 +#define FIX(x) ((int32)((x) * (1L<RGB conversion tables. The conversion + * is done according to the 6.0 spec: + * + * R = Y + Cr*(2 - 2*LumaRed) + * B = Y + Cb*(2 - 2*LumaBlue) + * G = Y + * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen + * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen + * + * To avoid floating point arithmetic the fractional constants that + * come out of the equations are represented as fixed point values + * in the range 0...2^16. We also eliminate multiplications by + * pre-calculating possible values indexed by Cb and Cr (this code + * assumes conversion is being done for 8-bit samples). + */ +static void +TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, TIFF* tif) +{ + TIFFRGBValue* clamptab; + float* coeffs; + int i; + + clamptab = (TIFFRGBValue*)( + (tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))); + _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ + ycbcr->clamptab = (clamptab += 256); + for (i = 0; i < 256; i++) + clamptab[i] = i; + _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */ + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &coeffs); + _TIFFmemcpy(ycbcr->coeffs, coeffs, 3*sizeof (float)); + { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1); + float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2); + float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3); + float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4); + int x; + + ycbcr->Cr_r_tab = (int*) (clamptab + 3*256); + ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256; + ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256); + ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; + /* + * i is the actual input pixel value in the range 0..255 + * Cb and Cr values are in the range -128..127 (actually + * they are in a range defined by the ReferenceBlackWhite + * tag) so there is some range shifting to do here when + * constructing tables indexed by the raw pixel data. + * + * XXX handle ReferenceBlackWhite correctly to calculate + * Cb/Cr values to use in constructing the tables. + */ + for (i = 0, x = -128; i < 256; i++, x++) { + ycbcr->Cr_r_tab[i] = (int)((D1*x + ONE_HALF)>>SHIFT); + ycbcr->Cb_b_tab[i] = (int)((D3*x + ONE_HALF)>>SHIFT); + ycbcr->Cr_g_tab[i] = D2*x; + ycbcr->Cb_g_tab[i] = D4*x + ONE_HALF; + } + } +} +#undef SHIFT +#undef ONE_HALF +#undef FIX +#undef LumaBlue +#undef LumaGreen +#undef LumaRed + +static tileContigRoutine +initYCbCrConversion(TIFFRGBAImage* img) +{ + uint16 hs, vs; + + if (img->ycbcr == NULL) { + img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( + TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)) + + 4*256*sizeof (TIFFRGBValue) + + 2*256*sizeof (int) + + 2*256*sizeof (int32) + ); + if (img->ycbcr == NULL) { + TIFFError(TIFFFileName(img->tif), + "No space for YCbCr->RGB conversion state"); + return (NULL); + } + TIFFYCbCrToRGBInit(img->ycbcr, img->tif); + } else { + float* coeffs; + + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &coeffs); + if (_TIFFmemcmp(coeffs, img->ycbcr->coeffs, 3*sizeof (float)) != 0) + TIFFYCbCrToRGBInit(img->ycbcr, img->tif); + } + /* + * The 6.0 spec says that subsampling must be + * one of 1, 2, or 4, and that vertical subsampling + * must always be <= horizontal subsampling; so + * there are only a few possibilities and we just + * enumerate the cases. + */ + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); + switch ((hs<<4)|vs) { + case 0x44: return (putcontig8bitYCbCr44tile); + case 0x42: return (putcontig8bitYCbCr42tile); + case 0x41: return (putcontig8bitYCbCr41tile); + case 0x22: return (putcontig8bitYCbCr22tile); + case 0x21: return (putcontig8bitYCbCr21tile); + case 0x11: return (putcontig8bitYCbCr11tile); + } + return (NULL); +} + +/* + * Greyscale images with less than 8 bits/sample are handled + * with a table to avoid lots of shifts and masks. The table + * is setup so that put*bwtile (below) can retrieve 8/bitspersample + * pixel values simply by indexing into the table with one + * number. + */ +static int +makebwmap(TIFFRGBAImage* img) +{ + TIFFRGBValue* Map = img->Map; + int bitspersample = img->bitspersample; + int nsamples = 8 / bitspersample; + int i; + uint32* p; + + img->BWmap = (uint32**) _TIFFmalloc( + 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); + if (img->BWmap == NULL) { + TIFFError(TIFFFileName(img->tif), "No space for B&W mapping table"); + return (0); + } + p = (uint32*)(img->BWmap + 256); + for (i = 0; i < 256; i++) { + TIFFRGBValue c; + img->BWmap[i] = p; + switch (bitspersample) { +#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); + case 1: + GREY(i>>7); + GREY((i>>6)&1); + GREY((i>>5)&1); + GREY((i>>4)&1); + GREY((i>>3)&1); + GREY((i>>2)&1); + GREY((i>>1)&1); + GREY(i&1); + break; + case 2: + GREY(i>>6); + GREY((i>>4)&3); + GREY((i>>2)&3); + GREY(i&3); + break; + case 4: + GREY(i>>4); + GREY(i&0xf); + break; + case 8: + GREY(i); + break; + } +#undef GREY + } + return (1); +} + +/* + * Construct a mapping table to convert from the range + * of the data samples to [0,255] --for display. This + * process also handles inverting B&W images when needed. + */ +static int +setupMap(TIFFRGBAImage* img) +{ + int32 x, range; + + range = (int32)((1L<bitspersample)-1); + img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); + if (img->Map == NULL) { + TIFFError(TIFFFileName(img->tif), + "No space for photometric conversion table"); + return (0); + } + if (img->photometric == PHOTOMETRIC_MINISWHITE) { + for (x = 0; x <= range; x++) + img->Map[x] = ((range - x) * 255) / range; + } else { + for (x = 0; x <= range; x++) + img->Map[x] = (x * 255) / range; + } + if (img->bitspersample <= 8 && + (img->photometric == PHOTOMETRIC_MINISBLACK || + img->photometric == PHOTOMETRIC_MINISWHITE)) { + /* + * Use photometric mapping table to construct + * unpacking tables for samples <= 8 bits. + */ + if (!makebwmap(img)) + return (0); + /* no longer need Map, free it */ + _TIFFfree(img->Map), img->Map = NULL; + } + return (1); +} + +static int +checkcmap(TIFFRGBAImage* img) +{ + uint16* r = img->redcmap; + uint16* g = img->greencmap; + uint16* b = img->bluecmap; + long n = 1L<bitspersample; + + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + return (8); +} + +static void +cvtcmap(TIFFRGBAImage* img) +{ + uint16* r = img->redcmap; + uint16* g = img->greencmap; + uint16* b = img->bluecmap; + long i; + + for (i = (1L<bitspersample)-1; i >= 0; i--) { +#define CVT(x) ((uint16)((x)>>8)) + r[i] = CVT(r[i]); + g[i] = CVT(g[i]); + b[i] = CVT(b[i]); +#undef CVT + } +} + +/* + * Palette images with <= 8 bits/sample are handled + * with a table to avoid lots of shifts and masks. The table + * is setup so that put*cmaptile (below) can retrieve 8/bitspersample + * pixel values simply by indexing into the table with one + * number. + */ +static int +makecmap(TIFFRGBAImage* img) +{ + int bitspersample = img->bitspersample; + int nsamples = 8 / bitspersample; + uint16* r = img->redcmap; + uint16* g = img->greencmap; + uint16* b = img->bluecmap; + uint32 *p; + int i; + + img->PALmap = (uint32**) _TIFFmalloc( + 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); + if (img->PALmap == NULL) { + TIFFError(TIFFFileName(img->tif), "No space for Palette mapping table"); + return (0); + } + p = (uint32*)(img->PALmap + 256); + for (i = 0; i < 256; i++) { + TIFFRGBValue c; + img->PALmap[i] = p; +#define CMAP(x) c = x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); + switch (bitspersample) { + case 1: + CMAP(i>>7); + CMAP((i>>6)&1); + CMAP((i>>5)&1); + CMAP((i>>4)&1); + CMAP((i>>3)&1); + CMAP((i>>2)&1); + CMAP((i>>1)&1); + CMAP(i&1); + break; + case 2: + CMAP(i>>6); + CMAP((i>>4)&3); + CMAP((i>>2)&3); + CMAP(i&3); + break; + case 4: + CMAP(i>>4); + CMAP(i&0xf); + break; + case 8: + CMAP(i); + break; + } +#undef CMAP + } + return (1); +} + +/* + * Construct any mapping table used + * by the associated put routine. + */ +static int +buildMap(TIFFRGBAImage* img) +{ + switch (img->photometric) { + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8) + break; + /* fall thru... */ + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + if (!setupMap(img)) + return (0); + break; + case PHOTOMETRIC_PALETTE: + /* + * Convert 16-bit colormap to 8-bit (unless it looks + * like an old-style 8-bit colormap). + */ + if (checkcmap(img) == 16) + cvtcmap(img); + else + TIFFWarning(TIFFFileName(img->tif), "Assuming 8-bit colormap"); + /* + * Use mapping table and colormap to construct + * unpacking tables for samples < 8 bits. + */ + if (img->bitspersample <= 8 && !makecmap(img)) + return (0); + break; + } + return (1); +} + +/* + * Select the appropriate conversion routine for packed data. + */ +static int +pickTileContigCase(TIFFRGBAImage* img) +{ + tileContigRoutine put = 0; + + if (buildMap(img)) { + switch (img->photometric) { + case PHOTOMETRIC_RGB: + switch (img->bitspersample) { + case 8: + if (!img->Map) { + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + put = putRGBAAcontig8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + put = putRGBUAcontig8bittile; + else + put = putRGBcontig8bittile; + } else + put = putRGBcontig8bitMaptile; + break; + case 16: + put = putRGBcontig16bittile; + if (!img->Map) { + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + put = putRGBAAcontig16bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + put = putRGBUAcontig16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8) { + if (!img->Map) + put = putRGBcontig8bitCMYKtile; + else + put = putRGBcontig8bitCMYKMaptile; + } + break; + case PHOTOMETRIC_PALETTE: + switch (img->bitspersample) { + case 8: put = put8bitcmaptile; break; + case 4: put = put4bitcmaptile; break; + case 2: put = put2bitcmaptile; break; + case 1: put = put1bitcmaptile; break; + } + break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + switch (img->bitspersample) { + case 8: put = putgreytile; break; + case 4: put = put4bitbwtile; break; + case 2: put = put2bitbwtile; break; + case 1: put = put1bitbwtile; break; + } + break; + case PHOTOMETRIC_YCBCR: + if (img->bitspersample == 8) + put = initYCbCrConversion(img); + break; + } + } + return ((img->put.contig = put) != 0); +} + +/* + * Select the appropriate conversion routine for unpacked data. + * + * NB: we assume that unpacked single channel data is directed + * to the "packed routines. + */ +static int +pickTileSeparateCase(TIFFRGBAImage* img) +{ + tileSeparateRoutine put = 0; + + if (buildMap(img)) { + switch (img->photometric) { + case PHOTOMETRIC_RGB: + switch (img->bitspersample) { + case 8: + if (!img->Map) { + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + put = putRGBAAseparate8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + put = putRGBUAseparate8bittile; + else + put = putRGBseparate8bittile; + } else + put = putRGBseparate8bitMaptile; + break; + case 16: + put = putRGBseparate16bittile; + if (!img->Map) { + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + put = putRGBAAseparate16bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + put = putRGBUAseparate16bittile; + } + break; + } + break; + } + } + return ((img->put.separate = put) != 0); +} diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c new file mode 100644 index 00000000..060cae0c --- /dev/null +++ b/libtiff/tif_jpeg.c @@ -0,0 +1,1477 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_jpeg.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1994-1997 Sam Leffler + * Copyright (c) 1994-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef JPEG_SUPPORT +/* + * TIFF Library + * + * JPEG Compression support per TIFF Technical Note #2 + * (*not* per the original TIFF 6.0 spec). + * + * This file is simply an interface to the libjpeg library written by + * the Independent JPEG Group. You need release 5 or later of the IJG + * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/. + * + * Contributed by Tom Lane . + */ +#include +#include +#include +#include "jpeglib.h" +#include "jerror.h" + +/* + * On some machines it may be worthwhile to use _setjmp or sigsetjmp + * in place of plain setjmp. These macros will make it easier. + */ +#define SETJMP(jbuf) setjmp(jbuf) +#define LONGJMP(jbuf,code) longjmp(jbuf,code) +#define JMP_BUF jmp_buf + +typedef struct jpeg_destination_mgr jpeg_destination_mgr; +typedef struct jpeg_source_mgr jpeg_source_mgr; +typedef struct jpeg_error_mgr jpeg_error_mgr; + +/* + * State block for each open TIFF file using + * libjpeg to do JPEG compression/decompression. + * + * libjpeg's visible state is either a jpeg_compress_struct + * or jpeg_decompress_struct depending on which way we + * are going. comm can be used to refer to the fields + * which are common to both. + * + * NB: cinfo is required to be the first member of JPEGState, + * so we can safely cast JPEGState* -> jpeg_xxx_struct* + * and vice versa! + */ +typedef struct { + union { + struct jpeg_compress_struct c; + struct jpeg_decompress_struct d; + struct jpeg_common_struct comm; + } cinfo; /* NB: must be first */ + jpeg_error_mgr err; /* libjpeg error manager */ + JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ + /* + * The following two members could be a union, but + * they're small enough that it's not worth the effort. + */ + jpeg_destination_mgr dest; /* data dest for compression */ + jpeg_source_mgr src; /* data source for decompression */ + /* private state */ + TIFF* tif; /* back link needed by some code */ + uint16 photometric; /* copy of PhotometricInterpretation */ + uint16 h_sampling; /* luminance sampling factors */ + uint16 v_sampling; + tsize_t bytesperline; /* decompressed bytes per scanline */ + /* pointers to intermediate buffers when processing downsampled data */ + JSAMPARRAY ds_buffer[MAX_COMPONENTS]; + int scancount; /* number of "scanlines" accumulated */ + int samplesperclump; + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFStripMethod defsparent; /* super-class method */ + TIFFTileMethod deftparent; /* super-class method */ + /* pseudo-tag fields */ + void* jpegtables; /* JPEGTables tag value, or NULL */ + uint32 jpegtables_length; /* number of bytes in same */ + int jpegquality; /* Compression quality level */ + int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ + int jpegtablesmode; /* What to put in JPEGTables */ +} JPEGState; + +#define JState(tif) ((JPEGState*)(tif)->tif_data) + +static int JPEGDecode(TIFF*, tidata_t, tsize_t, tsample_t); +static int JPEGDecodeRaw(TIFF*, tidata_t, tsize_t, tsample_t); +static int JPEGEncode(TIFF*, tidata_t, tsize_t, tsample_t); +static int JPEGEncodeRaw(TIFF*, tidata_t, tsize_t, tsample_t); + +#define FIELD_JPEGTABLES (FIELD_CODEC+0) + +static const TIFFFieldInfo jpegFieldInfo[] = { + { TIFFTAG_JPEGTABLES, -1,-1, TIFF_UNDEFINED, FIELD_JPEGTABLES, + FALSE, TRUE, "JPEGTables" }, + { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, FIELD_PSEUDO, + TRUE, FALSE, "" }, + { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, + FALSE, FALSE, "" }, + { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, FIELD_PSEUDO, + FALSE, FALSE, "" }, +}; +#define N(a) (sizeof (a) / sizeof (a[0])) + +/* + * libjpeg interface layer. + * + * We use setjmp/longjmp to return control to libtiff + * when a fatal error is encountered within the JPEG + * library. We also direct libjpeg error and warning + * messages through the appropriate libtiff handlers. + */ + +/* + * Error handling routines (these replace corresponding + * IJG routines from jerror.c). These are used for both + * compression and decompression. + */ +static void +TIFFjpeg_error_exit(j_common_ptr cinfo) +{ + JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */ + char buffer[JMSG_LENGTH_MAX]; + + (*cinfo->err->format_message) (cinfo, buffer); + TIFFError("JPEGLib", buffer); /* display the error message */ + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ +} + +/* + * This routine is invoked only for warning messages, + * since error_exit does its own thing and trace_level + * is never set > 0. + */ +static void +TIFFjpeg_output_message(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + (*cinfo->err->format_message) (cinfo, buffer); + TIFFWarning("JPEGLib", buffer); +} + +/* + * Interface routines. This layer of routines exists + * primarily to limit side-effects from using setjmp. + * Also, normal/error returns are converted into return + * values per libtiff practice. + */ +#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) +#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op),1)) + +static int +TIFFjpeg_create_compress(JPEGState* sp) +{ + /* initialize JPEG error handling */ + sp->cinfo.c.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; + + return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); +} + +static int +TIFFjpeg_create_decompress(JPEGState* sp) +{ + /* initialize JPEG error handling */ + sp->cinfo.d.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; + + return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); +} + +static int +TIFFjpeg_set_defaults(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); +} + +static int +TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace) +{ + return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); +} + +static int +TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline) +{ + return CALLVJPEG(sp, + jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); +} + +static int +TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress) +{ + return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); +} + +static int +TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables) +{ + return CALLVJPEG(sp, + jpeg_start_compress(&sp->cinfo.c, write_all_tables)); +} + +static int +TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c, + scanlines, (JDIMENSION) num_lines)); +} + +static int +TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c, + data, (JDIMENSION) num_lines)); +} + +static int +TIFFjpeg_finish_compress(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); +} + +static int +TIFFjpeg_write_tables(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); +} + +static int +TIFFjpeg_read_header(JPEGState* sp, boolean require_image) +{ + return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); +} + +static int +TIFFjpeg_start_decompress(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); +} + +static int +TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d, + scanlines, (JDIMENSION) max_lines)); +} + +static int +TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines) +{ + return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d, + data, (JDIMENSION) max_lines)); +} + +static int +TIFFjpeg_finish_decompress(JPEGState* sp) +{ + return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d)); +} + +static int +TIFFjpeg_abort(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); +} + +static int +TIFFjpeg_destroy(JPEGState* sp) +{ + return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); +} + +static JSAMPARRAY +TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id, + JDIMENSION samplesperrow, JDIMENSION numrows) +{ + return CALLJPEG(sp, (JSAMPARRAY) NULL, + (*sp->cinfo.comm.mem->alloc_sarray) + (&sp->cinfo.comm, pool_id, samplesperrow, numrows)); +} + +/* + * JPEG library destination data manager. + * These routines direct compressed data from libjpeg into the + * libtiff output buffer. + */ + +static void +std_init_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; +} + +static boolean +std_empty_output_buffer(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + /* the entire buffer has been filled */ + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize; + + return (TRUE); +} + +static void +std_term_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + tif->tif_rawcp = (tidata_t) sp->dest.next_output_byte; + tif->tif_rawcc = + tif->tif_rawdatasize - (tsize_t) sp->dest.free_in_buffer; + /* NB: libtiff does the final buffer flush */ +} + +static void +TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif) +{ + (void) tif; + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = std_init_destination; + sp->dest.empty_output_buffer = std_empty_output_buffer; + sp->dest.term_destination = std_term_destination; +} + +/* + * Alternate destination manager for outputting to JPEGTables field. + */ + +static void +tables_init_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + + /* while building, jpegtables_length is allocated buffer size */ + sp->dest.next_output_byte = (JOCTET*) sp->jpegtables; + sp->dest.free_in_buffer = (size_t) sp->jpegtables_length; +} + +static boolean +tables_empty_output_buffer(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + void* newbuf; + + /* the entire buffer has been filled; enlarge it by 1000 bytes */ + newbuf = _TIFFrealloc((tdata_t) sp->jpegtables, + (tsize_t) (sp->jpegtables_length + 1000)); + if (newbuf == NULL) + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); + sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length; + sp->dest.free_in_buffer = (size_t) 1000; + sp->jpegtables = newbuf; + sp->jpegtables_length += 1000; + return (TRUE); +} + +static void +tables_term_destination(j_compress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + + /* set tables length to number of bytes actually emitted */ + sp->jpegtables_length -= sp->dest.free_in_buffer; +} + +static int +TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif) +{ + (void) tif; + /* + * Allocate a working buffer for building tables. + * Initial size is 1000 bytes, which is usually adequate. + */ + if (sp->jpegtables) + _TIFFfree(sp->jpegtables); + sp->jpegtables_length = 1000; + sp->jpegtables = (void*) _TIFFmalloc((tsize_t) sp->jpegtables_length); + if (sp->jpegtables == NULL) { + sp->jpegtables_length = 0; + TIFFError("TIFFjpeg_tables_dest", "No space for JPEGTables"); + return (0); + } + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = tables_init_destination; + sp->dest.empty_output_buffer = tables_empty_output_buffer; + sp->dest.term_destination = tables_term_destination; + return (1); +} + +/* + * JPEG library source data manager. + * These routines supply compressed data to libjpeg. + */ + +static void +std_init_source(j_decompress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + TIFF* tif = sp->tif; + + sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata; + sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc; +} + +static boolean +std_fill_input_buffer(j_decompress_ptr cinfo) +{ + JPEGState* sp = (JPEGState* ) cinfo; + static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI }; + + /* + * Should never get here since entire strip/tile is + * read into memory before the decompressor is called, + * and thus was supplied by init_source. + */ + WARNMS(cinfo, JWRN_JPEG_EOF); + /* insert a fake EOI marker */ + sp->src.next_input_byte = dummy_EOI; + sp->src.bytes_in_buffer = 2; + return (TRUE); +} + +static void +std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + JPEGState* sp = (JPEGState*) cinfo; + + if (num_bytes > 0) { + if (num_bytes > (long) sp->src.bytes_in_buffer) { + /* oops, buffer overrun */ + (void) std_fill_input_buffer(cinfo); + } else { + sp->src.next_input_byte += (size_t) num_bytes; + sp->src.bytes_in_buffer -= (size_t) num_bytes; + } + } +} + +static void +std_term_source(j_decompress_ptr cinfo) +{ + /* No work necessary here */ + /* Or must we update tif->tif_rawcp, tif->tif_rawcc ??? */ + /* (if so, need empty tables_term_source!) */ + (void) cinfo; +} + +static void +TIFFjpeg_data_src(JPEGState* sp, TIFF* tif) +{ + (void) tif; + sp->cinfo.d.src = &sp->src; + sp->src.init_source = std_init_source; + sp->src.fill_input_buffer = std_fill_input_buffer; + sp->src.skip_input_data = std_skip_input_data; + sp->src.resync_to_restart = jpeg_resync_to_restart; + sp->src.term_source = std_term_source; + sp->src.bytes_in_buffer = 0; /* for safety */ + sp->src.next_input_byte = NULL; +} + +/* + * Alternate source manager for reading from JPEGTables. + * We can share all the code except for the init routine. + */ + +static void +tables_init_source(j_decompress_ptr cinfo) +{ + JPEGState* sp = (JPEGState*) cinfo; + + sp->src.next_input_byte = (const JOCTET*) sp->jpegtables; + sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length; +} + +static void +TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif) +{ + TIFFjpeg_data_src(sp, tif); + sp->src.init_source = tables_init_source; +} + +/* + * Allocate downsampled-data buffers needed for downsampled I/O. + * We use values computed in jpeg_start_compress or jpeg_start_decompress. + * We use libjpeg's allocator so that buffers will be released automatically + * when done with strip/tile. + * This is also a handy place to compute samplesperclump, bytesperline. + */ +static int +alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info, + int num_components) +{ + JPEGState* sp = JState(tif); + int ci; + jpeg_component_info* compptr; + JSAMPARRAY buf; + int samples_per_clump = 0; + + for (ci = 0, compptr = comp_info; ci < num_components; + ci++, compptr++) { + samples_per_clump += compptr->h_samp_factor * + compptr->v_samp_factor; + buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, + compptr->width_in_blocks * DCTSIZE, + (JDIMENSION) (compptr->v_samp_factor*DCTSIZE)); + if (buf == NULL) + return (0); + sp->ds_buffer[ci] = buf; + } + sp->samplesperclump = samples_per_clump; + /* Cb,Cr both have sampling factors 1 */ + /* so downsampled width of Cb is # of clumps per line */ + sp->bytesperline = sizeof(JSAMPLE) * samples_per_clump * + comp_info[1].downsampled_width; + return (1); +} + + +/* + * JPEG Decoding. + */ + +static int +JPEGSetupDecode(TIFF* tif) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + assert(sp != NULL); + assert(sp->cinfo.comm.is_decompressor); + + /* Read JPEGTables if it is present */ + if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) { + TIFFjpeg_tables_src(sp, tif); + if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) { + TIFFError("JPEGSetupDecode", "Bogus JPEGTables field"); + return (0); + } + } + + /* Grab parameters that are same for all strips/tiles */ + sp->photometric = td->td_photometric; + switch (sp->photometric) { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + break; + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Set up for reading normal data */ + TIFFjpeg_data_src(sp, tif); + tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ + return (1); +} + +/* + * Set up for decoding a strip or tile. + */ +static int +JPEGPreDecode(TIFF* tif, tsample_t s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreDecode"; + uint32 segment_width, segment_height; + int downsampled_output; + int ci; + + assert(sp != NULL); + assert(sp->cinfo.comm.is_decompressor); + /* + * Reset decoder state from any previous strip/tile, + * in case application didn't read the whole strip. + */ + if (!TIFFjpeg_abort(sp)) + return (0); + /* + * Read the header for this strip/tile. + */ + if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) + return (0); + /* + * Check image parameters and set decompression parameters. + */ + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { + /* + * For PC 2, scale down the expected strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany(segment_width, sp->h_sampling); + segment_height = TIFFhowmany(segment_height, sp->v_sampling); + } + if (sp->cinfo.d.image_width != segment_width || + sp->cinfo.d.image_height != segment_height) { + TIFFError(module, "Improper JPEG strip/tile size"); + return (0); + } + if (sp->cinfo.d.num_components != + (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1)) { + TIFFError(module, "Improper JPEG component count"); + return (0); + } + if (sp->cinfo.d.data_precision != td->td_bitspersample) { + TIFFError(module, "Improper JPEG data precision"); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + /* Component 0 should have expected sampling factors */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || + sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { + TIFFError(module, "Improper JPEG sampling factors"); + return (0); + } + /* Rest should have sampling factors 1,1 */ + for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { + if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || + sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { + TIFFError(module, "Improper JPEG sampling factors"); + return (0); + } + } + } else { + /* PC 2's single component should have sampling factors 1,1 */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || + sp->cinfo.d.comp_info[0].v_samp_factor != 1) { + TIFFError(module, "Improper JPEG sampling factors"); + return (0); + } + } + downsampled_output = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + sp->photometric == PHOTOMETRIC_YCBCR && + sp->jpegcolormode == JPEGCOLORMODE_RGB) { + /* Convert YCbCr to RGB */ + sp->cinfo.d.jpeg_color_space = JCS_YCbCr; + sp->cinfo.d.out_color_space = JCS_RGB; + } else { + /* Suppress colorspace handling */ + sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; + sp->cinfo.d.out_color_space = JCS_UNKNOWN; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + (sp->h_sampling != 1 || sp->v_sampling != 1)) + downsampled_output = TRUE; + /* XXX what about up-sampling? */ + } + if (downsampled_output) { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.d.raw_data_out = TRUE; + tif->tif_decoderow = JPEGDecodeRaw; + tif->tif_decodestrip = JPEGDecodeRaw; + tif->tif_decodetile = JPEGDecodeRaw; + } else { + /* Use normal interface to libjpeg */ + sp->cinfo.d.raw_data_out = FALSE; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + } + /* Start JPEG decompressor */ + if (!TIFFjpeg_start_decompress(sp)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_output) { + if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, + sp->cinfo.d.num_components)) + return (0); + sp->scancount = DCTSIZE; /* mark buffer empty */ + } + return (1); +} + +/* + * Decode a chunk of pixels. + * "Standard" case: returned data is not downsampled. + */ +static int +JPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +{ + JPEGState *sp = JState(tif); + tsize_t nrows; + JSAMPROW bufptr[1]; + + (void) s; + assert(sp != NULL); + /* data is expected to be read in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarning(tif->tif_name, "fractional scanline not read"); + + while (nrows-- > 0) { + bufptr[0] = (JSAMPROW) buf; + if (TIFFjpeg_read_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + /* Close down the decompressor if we've finished the strip or tile. */ + if (sp->cinfo.d.output_scanline == sp->cinfo.d.output_height) { + if (TIFFjpeg_finish_decompress(sp) != TRUE) + return (0); + } + return (1); +} + +/* + * Decode a chunk of pixels. + * Returned data is downsampled per sampling factors. + */ +static int +JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +{ + JPEGState *sp = JState(tif); + JSAMPLE* inptr; + JSAMPLE* outptr; + tsize_t nrows; + JDIMENSION clumps_per_line, nclump; + int clumpoffset, ci, xpos, ypos; + jpeg_component_info* compptr; + int samples_per_clump = sp->samplesperclump; + + (void) s; + assert(sp != NULL); + /* data is expected to be read in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarning(tif->tif_name, "fractional scanline not read"); + + /* Cb,Cr both have sampling factors 1, so this is correct */ + clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; + + while (nrows-- > 0) { + /* Reload downsampled-data buffer if needed */ + if (sp->scancount >= DCTSIZE) { + int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; + /* Close down the decompressor if done. */ + if (sp->cinfo.d.output_scanline >= + sp->cinfo.d.output_height) { + if (TIFFjpeg_finish_decompress(sp) != TRUE) + return (0); + } + } + /* + * Fastest way to unseparate the data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.d.comp_info; + ci < sp->cinfo.d.num_components; + ci++, compptr++) { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + for (ypos = 0; ypos < vsamp; ypos++) { + inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; + outptr = ((JSAMPLE*) buf) + clumpoffset; + if (hsamp == 1) { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + outptr[0] = *inptr++; + outptr += samples_per_clump; + } + } else { + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + for (xpos = 0; xpos < hsamp; xpos++) + outptr[xpos] = *inptr++; + outptr += samples_per_clump; + } + } + clumpoffset += hsamp; + } + } + sp->scancount++; + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + return (1); +} + + +/* + * JPEG Encoding. + */ + +static void +unsuppress_quant_table (JPEGState* sp, int tblno) +{ + JQUANT_TBL* qtbl; + + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = FALSE; +} + +static void +unsuppress_huff_table (JPEGState* sp, int tblno) +{ + JHUFF_TBL* htbl; + + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; +} + +static int +prepare_JPEGTables(TIFF* tif) +{ + JPEGState* sp = JState(tif); + + /* Initialize quant tables for current quality setting */ + if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) + return (0); + /* Mark only the tables we want for output */ + /* NB: chrominance tables are currently used only with YCbCr */ + if (!TIFFjpeg_suppress_tables(sp, TRUE)) + return (0); + if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) { + unsuppress_quant_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_quant_table(sp, 1); + } + if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) { + unsuppress_huff_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_huff_table(sp, 1); + } + /* Direct libjpeg output into jpegtables */ + if (!TIFFjpeg_tables_dest(sp, tif)) + return (0); + /* Emit tables-only datastream */ + if (!TIFFjpeg_write_tables(sp)) + return (0); + + return (1); +} + +static int +JPEGSetupEncode(TIFF* tif) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGSetupEncode"; + + assert(sp != NULL); + assert(!sp->cinfo.comm.is_decompressor); + + /* + * Initialize all JPEG parameters to default values. + * Note that jpeg_set_defaults needs legal values for + * in_color_space and input_components. + */ + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + sp->cinfo.c.input_components = 1; + if (!TIFFjpeg_set_defaults(sp)) + return (0); + /* Set per-file parameters */ + sp->photometric = td->td_photometric; + switch (sp->photometric) { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + /* + * A ReferenceBlackWhite field *must* be present since the + * default value is inappropriate for YCbCr. Fill in the + * proper value if application didn't set it. + */ +#ifdef COLORIMETRY_SUPPORT + if (!TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) { + float refbw[6]; + long top = 1L << td->td_bitspersample; + refbw[0] = 0; + refbw[1] = (float)(top-1L); + refbw[2] = (float)(top>>1); + refbw[3] = refbw[1]; + refbw[4] = refbw[2]; + refbw[5] = refbw[1]; + TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); + } +#endif + break; + case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ + case PHOTOMETRIC_MASK: + TIFFError(module, + "PhotometricInterpretation %d not allowed for JPEG", + (int) sp->photometric); + return (0); + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Verify miscellaneous parameters */ + + /* + * This would need work if libtiff ever supports different + * depths for different components, or if libjpeg ever supports + * run-time selection of depth. Neither is imminent. + */ + if (td->td_bitspersample != BITS_IN_JSAMPLE) { + TIFFError(module, "BitsPerSample %d not allowed for JPEG", + (int) td->td_bitspersample); + return (0); + } + sp->cinfo.c.data_precision = td->td_bitspersample; + if (isTiled(tif)) { + if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { + TIFFError(module, + "JPEG tile height must be multiple of %d", + sp->v_sampling * DCTSIZE); + return (0); + } + if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { + TIFFError(module, + "JPEG tile width must be multiple of %d", + sp->h_sampling * DCTSIZE); + return (0); + } + } else { + if (td->td_rowsperstrip < td->td_imagelength && + (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { + TIFFError(module, + "RowsPerStrip must be multiple of %d for JPEG", + sp->v_sampling * DCTSIZE); + return (0); + } + } + + /* Create a JPEGTables field if appropriate */ + if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) { + if (!prepare_JPEGTables(tif)) + return (0); + /* Mark the field present */ + /* Can't use TIFFSetField since BEENWRITING is already set! */ + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + tif->tif_flags |= TIFF_DIRTYDIRECT; + } else { + /* We do not support application-supplied JPEGTables, */ + /* so mark the field not present */ + TIFFClrFieldBit(tif, FIELD_JPEGTABLES); + } + + /* Direct libjpeg output to libtiff's output buffer */ + TIFFjpeg_data_dest(sp, tif); + + return (1); +} + +/* + * Set encoding state at the start of a strip or tile. + */ +static int +JPEGPreEncode(TIFF* tif, tsample_t s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreEncode"; + uint32 segment_width, segment_height; + int downsampled_input; + + assert(sp != NULL); + assert(!sp->cinfo.comm.is_decompressor); + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } else { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { + /* for PC 2, scale down the strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany(segment_width, sp->h_sampling); + segment_height = TIFFhowmany(segment_height, sp->v_sampling); + } + if (segment_width > 65535 || segment_height > 65535) { + TIFFError(module, "Strip/tile too large for JPEG"); + return (0); + } + sp->cinfo.c.image_width = segment_width; + sp->cinfo.c.image_height = segment_height; + downsampled_input = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) { + if (sp->jpegcolormode == JPEGCOLORMODE_RGB) { + sp->cinfo.c.in_color_space = JCS_RGB; + } else { + sp->cinfo.c.in_color_space = JCS_YCbCr; + if (sp->h_sampling != 1 || sp->v_sampling != 1) + downsampled_input = TRUE; + } + if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) + return (0); + /* + * Set Y sampling factors; + * we assume jpeg_set_colorspace() set the rest to 1 + */ + sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; + sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; + } else { + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) + return (0); + /* jpeg_set_colorspace set all sampling factors to 1 */ + } + } else { + sp->cinfo.c.input_components = 1; + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) + return (0); + sp->cinfo.c.comp_info[0].component_id = s; + /* jpeg_set_colorspace() set sampling factors to 1 */ + if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { + sp->cinfo.c.comp_info[0].quant_tbl_no = 1; + sp->cinfo.c.comp_info[0].dc_tbl_no = 1; + sp->cinfo.c.comp_info[0].ac_tbl_no = 1; + } + } + /* ensure libjpeg won't write any extraneous markers */ + sp->cinfo.c.write_JFIF_header = FALSE; + sp->cinfo.c.write_Adobe_marker = FALSE; + /* set up table handling correctly */ + if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) { + if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE)) + return (0); + unsuppress_quant_table(sp, 0); + unsuppress_quant_table(sp, 1); + } + if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) + sp->cinfo.c.optimize_coding = FALSE; + else + sp->cinfo.c.optimize_coding = TRUE; + if (downsampled_input) { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.c.raw_data_in = TRUE; + tif->tif_encoderow = JPEGEncodeRaw; + tif->tif_encodestrip = JPEGEncodeRaw; + tif->tif_encodetile = JPEGEncodeRaw; + } else { + /* Use normal interface to libjpeg */ + sp->cinfo.c.raw_data_in = FALSE; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + } + /* Start JPEG compressor */ + if (!TIFFjpeg_start_compress(sp, FALSE)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_input) { + if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, + sp->cinfo.c.num_components)) + return (0); + } + sp->scancount = 0; + + return (1); +} + +/* + * Encode a chunk of pixels. + * "Standard" case: incoming data is not downsampled. + */ +static int +JPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +{ + JPEGState *sp = JState(tif); + tsize_t nrows; + JSAMPROW bufptr[1]; + + (void) s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarning(tif->tif_name, "fractional scanline discarded"); + + while (nrows-- > 0) { + bufptr[0] = (JSAMPROW) buf; + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + return (1); +} + +/* + * Encode a chunk of pixels. + * Incoming data is expected to be downsampled per sampling factors. + */ +static int +JPEGEncodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +{ + JPEGState *sp = JState(tif); + JSAMPLE* inptr; + JSAMPLE* outptr; + tsize_t nrows; + JDIMENSION clumps_per_line, nclump; + int clumpoffset, ci, xpos, ypos; + jpeg_component_info* compptr; + int samples_per_clump = sp->samplesperclump; + + (void) s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarning(tif->tif_name, "fractional scanline discarded"); + + /* Cb,Cr both have sampling factors 1, so this is correct */ + clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; + + while (nrows-- > 0) { + /* + * Fastest way to separate the data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; + ci++, compptr++) { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int padding = (int) (compptr->width_in_blocks * DCTSIZE - + clumps_per_line * hsamp); + for (ypos = 0; ypos < vsamp; ypos++) { + inptr = ((JSAMPLE*) buf) + clumpoffset; + outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos]; + if (hsamp == 1) { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + *outptr++ = inptr[0]; + inptr += samples_per_clump; + } + } else { + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0; ) { + for (xpos = 0; xpos < hsamp; xpos++) + *outptr++ = inptr[xpos]; + inptr += samples_per_clump; + } + } + /* pad each scanline as needed */ + for (xpos = 0; xpos < padding; xpos++) { + *outptr = outptr[-1]; + outptr++; + } + clumpoffset += hsamp; + } + } + sp->scancount++; + if (sp->scancount >= DCTSIZE) { + int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; + } + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; + } + return (1); +} + +/* + * Finish up at the end of a strip or tile. + */ +static int +JPEGPostEncode(TIFF* tif) +{ + JPEGState *sp = JState(tif); + + if (sp->scancount > 0) { + /* + * Need to emit a partial bufferload of downsampled data. + * Pad the data vertically. + */ + int ci, ypos, n; + jpeg_component_info* compptr; + + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; + ci++, compptr++) { + int vsamp = compptr->v_samp_factor; + tsize_t row_width = compptr->width_in_blocks * DCTSIZE + * sizeof(JSAMPLE); + for (ypos = sp->scancount * vsamp; + ypos < DCTSIZE * vsamp; ypos++) { + _TIFFmemcpy((tdata_t)sp->ds_buffer[ci][ypos], + (tdata_t)sp->ds_buffer[ci][ypos-1], + row_width); + + } + } + n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + } + + return (TIFFjpeg_finish_compress(JState(tif))); +} + +static void +JPEGCleanup(TIFF* tif) +{ + if (tif->tif_data) { + JPEGState *sp = JState(tif); + TIFFjpeg_destroy(sp); /* release libjpeg resources */ + if (sp->jpegtables) /* tag value */ + _TIFFfree(sp->jpegtables); + _TIFFfree(tif->tif_data); /* release local state */ + tif->tif_data = NULL; + } +} + +static int +JPEGVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + JPEGState* sp = JState(tif); + TIFFDirectory* td = &tif->tif_dir; + uint32 v32; + + switch (tag) { + case TIFFTAG_JPEGTABLES: + v32 = va_arg(ap, uint32); + if (v32 == 0) { + /* XXX */ + return (0); + } + _TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), + (long) v32); + sp->jpegtables_length = v32; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + break; + case TIFFTAG_JPEGQUALITY: + sp->jpegquality = va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_JPEGCOLORMODE: + sp->jpegcolormode = va_arg(ap, int); + /* + * Mark whether returned data is up-sampled or not + * so TIFFStripSize and TIFFTileSize return values + * that reflect the true amount of data. + */ + tif->tif_flags &= ~TIFF_UPSAMPLED; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + if (td->td_photometric == PHOTOMETRIC_YCBCR && + sp->jpegcolormode == JPEGCOLORMODE_RGB) { + tif->tif_flags |= TIFF_UPSAMPLED; + } else { + if (td->td_ycbcrsubsampling[0] != 1 || + td->td_ycbcrsubsampling[1] != 1) + ; /* XXX what about up-sampling? */ + } + } + /* + * Must recalculate cached tile size + * in case sampling state changed. + */ + tif->tif_tilesize = TIFFTileSize(tif); + return (1); /* pseudo tag */ + case TIFFTAG_JPEGTABLESMODE: + sp->jpegtablesmode = va_arg(ap, int); + return (1); /* pseudo tag */ + default: + return (*sp->vsetparent)(tif, tag, ap); + } + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); +} + +static int +JPEGVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + JPEGState* sp = JState(tif); + + switch (tag) { + case TIFFTAG_JPEGTABLES: + /* u_short is bogus --- should be uint32 ??? */ + /* TIFFWriteNormalTag needs fixed XXX */ + *va_arg(ap, u_short*) = (u_short) sp->jpegtables_length; + *va_arg(ap, void**) = sp->jpegtables; + break; + case TIFFTAG_JPEGQUALITY: + *va_arg(ap, int*) = sp->jpegquality; + break; + case TIFFTAG_JPEGCOLORMODE: + *va_arg(ap, int*) = sp->jpegcolormode; + break; + case TIFFTAG_JPEGTABLESMODE: + *va_arg(ap, int*) = sp->jpegtablesmode; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static void +JPEGPrintDir(TIFF* tif, FILE* fd, long flags) +{ + JPEGState* sp = JState(tif); + + (void) flags; + if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) + fprintf(fd, " JPEG Tables: (%lu bytes)\n", + (u_long) sp->jpegtables_length); +} + +static uint32 +JPEGDefaultStripSize(TIFF* tif, uint32 s) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + s = (*sp->defsparent)(tif, s); + if (s < td->td_imagelength) + s = TIFFroundup(s, td->td_ycbcrsubsampling[1] * DCTSIZE); + return (s); +} + +static void +JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +{ + JPEGState* sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + + (*sp->deftparent)(tif, tw, th); + *tw = TIFFroundup(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); + *th = TIFFroundup(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); +} + +int +TIFFInitJPEG(TIFF* tif, int scheme) +{ + JPEGState* sp; + + assert(scheme == COMPRESSION_JPEG); + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (JPEGState)); + if (tif->tif_data == NULL) { + TIFFError("TIFFInitJPEG", "No space for JPEG state block"); + return (0); + } + sp = JState(tif); + sp->tif = tif; /* back link */ + + /* + * Merge codec-specific tag information and + * override parent get/set field methods. + */ + _TIFFMergeFieldInfo(tif, jpegFieldInfo, N(jpegFieldInfo)); + sp->vgetparent = tif->tif_vgetfield; + tif->tif_vgetfield = JPEGVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_vsetfield; + tif->tif_vsetfield = JPEGVSetField; /* hook for codec tags */ + tif->tif_printdir = JPEGPrintDir; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->jpegtables = NULL; + sp->jpegtables_length = 0; + sp->jpegquality = 75; /* Default IJG quality */ + sp->jpegcolormode = JPEGCOLORMODE_RAW; + sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; + + /* + * Install codec methods. + */ + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; + sp->defsparent = tif->tif_defstripsize; + tif->tif_defstripsize = JPEGDefaultStripSize; + sp->deftparent = tif->tif_deftilesize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + + /* + * Initialize libjpeg. + */ + if (tif->tif_mode == O_RDONLY) { + if (!TIFFjpeg_create_decompress(sp)) + return (0); + } else { + if (!TIFFjpeg_create_compress(sp)) + return (0); + } + + return (1); +} +#endif /* JPEG_SUPPORT */ diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c new file mode 100644 index 00000000..682e618e --- /dev/null +++ b/libtiff/tif_luv.c @@ -0,0 +1,1428 @@ +/* + * Copyright (c) 1997 Greg Ward Larson + * Copyright (c) 1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any + * advertising or publicity relating to the software without the specific, + * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE + * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LOGLUV_SUPPORT + +/* + * TIFF Library. + * LogLuv compression support for high dynamic range images. + * + * Contributed by Greg Larson. + * + * LogLuv image support uses the TIFF library to store 16 or 10-bit + * log luminance values with 8 bits each of u and v or a 14-bit index. + * + * The codec can take as input and produce as output 32-bit IEEE float values + * as well as 16-bit integer values. A 16-bit luminance is interpreted + * as a sign bit followed by a 15-bit integer that is converted + * to and from a linear magnitude using the transformation: + * + * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit + * + * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real + * + * The actual conversion to world luminance units in candelas per sq. meter + * requires an additional multiplier, which is stored in the TIFFTAG_STONITS. + * This value is usually set such that a reasonable exposure comes from + * clamping decoded luminances above 1 to 1 in the displayed image. + * + * The 16-bit values for u and v may be converted to real values by dividing + * each by 32768. (This allows for negative values, which aren't useful as + * far as we know, but are left in case of future improvements in human + * color vision.) + * + * Conversion from (u,v), which is actually the CIE (u',v') system for + * you color scientists, is accomplished by the following transformation: + * + * u = 4*x / (-2*x + 12*y + 3) + * v = 9*y / (-2*x + 12*y + 3) + * + * x = 9*u / (6*u - 16*v + 12) + * y = 4*v / (6*u - 16*v + 12) + * + * This process is greatly simplified by passing 32-bit IEEE floats + * for each of three CIE XYZ coordinates. The codec then takes care + * of conversion to and from LogLuv, though the application is still + * responsible for interpreting the TIFFTAG_STONITS calibration factor. + * + * The information is compressed into one of two basic encodings, depending on + * the setting of the compression tag, which is one of COMPRESSION_SGILOG + * or COMPRESSION_SGILOG24. For COMPRESSION_SGILOG, greyscale data is + * stored as: + * + * 1 15 + * |-+---------------| + * + * COMPRESSION_SGILOG color data is stored as: + * + * 1 15 8 8 + * |-+---------------|--------+--------| + * S Le ue ve + * + * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as: + * + * 10 14 + * |----------|--------------| + * Le' Ce + * + * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is + * encoded as an index for optimal color resolution. The 10 log bits are + * defined by the following conversions: + * + * L = 2^((Le'+.5)/64 - 12) # real from 10-bit + * + * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real + * + * The 10 bits of the smaller format may be converted into the 15 bits of + * the larger format by multiplying by 4 and adding 13314. Obviously, + * a smaller range of magnitudes is covered (about 5 orders of magnitude + * instead of 38), and the lack of a sign bit means that negative luminances + * are not allowed. (Well, they aren't allowed in the real world, either, + * but they are useful for certain types of image processing.) + * + * The desired user format is controlled by the setting the internal + * pseudo tag TIFFTAG_SGILOGDATAFMT to one of: + * SGILOGDATAFMT_FLOAT = IEEE 32-bit float XYZ values + * SGILOGDATAFMT_16BIT = 16-bit integer encodings of logL, u and v + * Raw data i/o is also possible using: + * SGILOGDATAFMT_RAW = 32-bit unsigned integer with encoded pixel + * In addition, the following decoding is provided for ease of display: + * SGILOGDATAFMT_8BIT = 8-bit default RGB gamma-corrected values + * + * For grayscale images, we provide the following data formats: + * SGILOGDATAFMT_FLOAT = IEEE 32-bit float Y values + * SGILOGDATAFMT_16BIT = 16-bit integer w/ encoded luminance + * SGILOGDATAFMT_8BIT = 8-bit gray monitor values + * + * Note that the COMPRESSION_SGILOG applies a simple run-length encoding + * scheme by separating the logL, u and v bytes for each row and applying + * a PackBits type of compression. Since the 24-bit encoding is not + * adaptive, the 32-bit color format takes less space in many cases. + */ + +#include +#include +#include +#include + +/* + * State block for each open TIFF + * file using LogLuv compression/decompression. + */ +typedef struct logLuvState LogLuvState; + +struct logLuvState { + int user_datafmt; /* user data format */ + int pixel_size; /* bytes per pixel */ + + tidata_t* tbuf; /* translation buffer */ + short tbuflen; /* buffer length */ + void (*tfunc)(LogLuvState*, tidata_t, int); + + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +}; + +#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) +#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) + +#define N(a) (sizeof(a)/sizeof(a[0])) +#define SGILOGDATAFMT_UNKNOWN -1 + +#define MINRUN 4 /* minimum run length */ + +/* + * Decode a string of 16-bit gray pixels. + */ +static int +LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +{ + LogLuvState* sp = DecoderState(tif); + int shft, i, npixels; + u_char* bp; + int16* tp; + int16 b; + int cc, rc; + + assert(s == 0); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16*) op; + else { + assert(sp->tbuflen >= npixels); + tp = (int16*) sp->tbuf; + } + _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0])); + + bp = (u_char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 2*8; (shft -= 8) >= 0; ) { + for (i = 0; i < npixels && cc > 0; ) + if (*bp >= 128) { /* run */ + rc = *bp++ + (2-128); + b = (int16)*bp++ << shft; + cc -= 2; + while (rc--) + tp[i++] |= b; + } else { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc--) + tp[i++] |= (int16)*bp++ << shft; + } + if (i != npixels) { + TIFFError(tif->tif_name, + "LogL16Decode: Not enough data at row %d (short %d pixels)", + tif->tif_row, npixels - i); + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + return (1); +} + +/* + * Decode a string of 24-bit pixels. + */ +static int +LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +{ + LogLuvState* sp = DecoderState(tif); + int cc, i, npixels; + u_char* bp; + uint32* tp; + + assert(s == 0); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32 *)op; + else { + assert(sp->tbuflen >= npixels); + tp = (uint32 *) sp->tbuf; + } + _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0])); + /* copy to array of uint32 */ + bp = (u_char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + for (i = 0; i < npixels && cc > 0; i++) { + tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; + bp += 3; + cc -= 3; + } + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + if (i != npixels) { + TIFFError(tif->tif_name, + "LogLuvDecode24: Not enough data at row %d (short %d pixels)", + tif->tif_row, npixels - i); + return (0); + } + (*sp->tfunc)(sp, op, npixels); + return (1); +} + +/* + * Decode a string of 32-bit pixels. + */ +static int +LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +{ + LogLuvState* sp; + int shft, i, npixels; + u_char* bp; + uint32* tp; + uint32 b; + int cc, rc; + + assert(s == 0); + sp = DecoderState(tif); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32*) op; + else { + assert(sp->tbuflen >= npixels); + tp = (uint32*) sp->tbuf; + } + _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0])); + + bp = (u_char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 4*8; (shft -= 8) >= 0; ) { + for (i = 0; i < npixels && cc > 0; ) + if (*bp >= 128) { /* run */ + rc = *bp++ + (2-128); + b = (uint32)*bp++ << shft; + cc -= 2; + while (rc--) + tp[i++] |= b; + } else { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc--) + tp[i++] |= (uint32)*bp++ << shft; + } + if (i != npixels) { + TIFFError(tif->tif_name, + "LogLuvDecode32: Not enough data at row %d (short %d pixels)", + tif->tif_row, npixels - i); + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + return (1); +} + +/* + * Decode a strip of pixels. We break it into rows to + * maintain synchrony with the encode algorithm, which + * is row by row. + */ +static int +LogLuvDecodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + tsize_t rowlen = TIFFScanlineSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Decode a tile of pixels. We break it into rows to + * maintain synchrony with the encode algorithm, which + * is row by row. + */ +static int +LogLuvDecodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + tsize_t rowlen = TIFFTileRowSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Encode a row of 16-bit pixels. + */ +static int +LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + TIFFDirectory* td = &tif->tif_dir; + LogLuvState* sp = EncoderState(tif); + int shft, i, j, npixels; + tidata_t op; + int16* tp; + int16 b; + int occ, rc, mask, beg; + + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16*) bp; + else { + tp = (int16*) sp->tbuf; + assert(sp->tbuflen >= npixels); + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 2*8; (shft -= 8) >= 0; ) + for (i = 0; i < npixels; i += rc) { + if (occ < 4) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + mask = 0xff << shft; /* find next run */ + for (beg = i; beg < npixels; beg += rc) { + b = tp[beg] & mask; + rc = 1; + while (rc < 127+2 && beg+rc < npixels && + (tp[beg+rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg-i > 1 && beg-i < MINRUN) { + b = tp[i] & mask; /* check short run */ + j = i+1; + while ((tp[j++] & mask) == b) + if (j == beg) { + *op++ = 128-2+j-i; + *op++ = b >> shft; + occ -= 2; + i = beg; + break; + } + } + while (i < beg) { /* write out non-run */ + if ((j = beg-i) > 127) j = 127; + if (occ < j+3) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = j; occ--; + while (j--) { + *op++ = tp[i++] >> shft & 0xff; + occ--; + } + } + if (rc >= MINRUN) { /* write out run */ + *op++ = 128-2+rc; + *op++ = tp[beg] >> shft & 0xff; + occ -= 2; + } else + rc = 0; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (0); +} + +/* + * Encode a row of 24-bit pixels. + */ +static int +LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + TIFFDirectory* td = &tif->tif_dir; + LogLuvState* sp = EncoderState(tif); + int i, npixels, occ; + tidata_t op; + uint32* tp; + + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32*) bp; + else { + tp = (uint32*) sp->tbuf; + assert(sp->tbuflen >= npixels); + (*sp->tfunc)(sp, bp, npixels); + } + /* write out encoded pixels */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (i = npixels; i--; ) { + if (occ < 3) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = *tp >> 16; + *op++ = *tp >> 8 & 0xff; + *op++ = *tp++ & 0xff; + occ -= 3; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (0); +} + +/* + * Encode a row of 32-bit pixels. + */ +static int +LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + TIFFDirectory* td = &tif->tif_dir; + LogLuvState* sp = EncoderState(tif); + int shft, i, j, npixels; + tidata_t op; + uint32* tp; + uint32 b; + int occ, rc, mask, beg; + + assert(s == 0); + assert(sp != NULL); + + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32*) bp; + else { + tp = (uint32*) sp->tbuf; + assert(sp->tbuflen >= npixels); + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 4*8; (shft -= 8) >= 0; ) + for (i = 0; i < npixels; i += rc) { + if (occ < 4) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + mask = 0xff << shft; /* find next run */ + for (beg = i; beg < npixels; beg += rc) { + b = tp[beg] & mask; + rc = 1; + while (rc < 127+2 && beg+rc < npixels && + (tp[beg+rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg-i > 1 && beg-i < MINRUN) { + b = tp[i] & mask; /* check short run */ + j = i+1; + while ((tp[j++] & mask) == b) + if (j == beg) { + *op++ = 128-2+j-i; + *op++ = b >> shft; + occ -= 2; + i = beg; + break; + } + } + while (i < beg) { /* write out non-run */ + if ((j = beg-i) > 127) j = 127; + if (occ < j+3) { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = j; occ--; + while (j--) { + *op++ = tp[i++] >> shft & 0xff; + occ--; + } + } + if (rc >= MINRUN) { /* write out run */ + *op++ = 128-2+rc; + *op++ = tp[beg] >> shft & 0xff; + occ -= 2; + } else + rc = 0; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (0); +} + +/* + * Encode a strip of pixels. We break it into rows to + * avoid encoding runs across row boundaries. + */ +static int +LogLuvEncodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + tsize_t rowlen = TIFFScanlineSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 0) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Encode a tile of pixels. We break it into rows to + * avoid encoding runs across row boundaries. + */ +static int +LogLuvEncodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + tsize_t rowlen = TIFFTileRowSize(tif); + + assert(cc%rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 0) + bp += rowlen, cc -= rowlen; + return (cc == 0); +} + +/* + * Encode/Decode functions for converting to and from user formats. + */ +#include "uvcode.h" + +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 + +#ifdef M_LN2 +#define LOGOF2 M_LN2 +#else +#define LOGOF2 0.69314718055994530942 +#endif +#define log2(x) ((1./LOGOF2)*log(x)) +#define exp2(x) exp(LOGOF2*(x)) + +#define UVSCALE 410. + +static double +pix16toY(int p16) +{ + int Le = p16 & 0x7fff; + double Y; + + if (!Le) + return (0.); + Y = exp(LOGOF2/256.*(Le+.5) - LOGOF2*64.); + if (p16 & 0x8000) + return (-Y); + return (Y); +} + +static int +pix16fromY(double Y) +{ + if (Y >= 1.84467e19) + return (0x7fff); + if (Y <= -1.84467e19) + return (0xffff); + if (Y > 5.43571e-20) + return (int)(256.*(log2(Y) + 64.)); + if (Y < -5.43571e-20) + return (~0x7fff | (int)(256.*(log2(-Y) + 64.))); + return (0); +} + +static void +L16toY(LogLuvState* sp, tidata_t op, int n) +{ + int16* l16 = (int16*) sp->tbuf; + float* yp = (float*) op; + + while (n-- > 0) + *yp++ = pix16toY(*l16++); +} + +static void +L16toGry(LogLuvState* sp, tidata_t op, int n) +{ + int16* l16 = (int16*) sp->tbuf; + uint8* gp = (uint8*) op; + + while (n-- > 0) { + double Y = pix16toY(*l16++); + *gp++ = (Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)); + } +} + +static void +L16fromY(LogLuvState* sp, tidata_t op, int n) +{ + int16* l16 = (int16*) sp->tbuf; + float* yp = (float*) op; + + while (n-- > 0) + *l16++ = pix16fromY(*yp++); +} + +static void +XYZtoRGB24(float xyz[3], uint8 rgb[3]) +{ + double r, g, b; + /* assume CCIR-709 primaries */ + r = 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2]; + g = -1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2]; + b = 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2]; + /* assume 2.0 gamma for speed */ + /* could use integer sqrt approx., but this is probably faster */ + rgb[0] = (r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)); + rgb[1] = (g <= 0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)); + rgb[2] = (b <= 0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)); +} + +static int +uv_encode(double u, double v) /* encode (u',v') coordinates */ +{ + register int vi, ui; + + if (v < UV_VSTART) + return(-1); + vi = (v - UV_VSTART)*(1./UV_SQSIZ); + if (vi >= UV_NVS) + return(-1); + if (u < uv_row[vi].ustart) + return(-1); + ui = (u - uv_row[vi].ustart)*(1./UV_SQSIZ); + if (ui >= uv_row[vi].nus) + return(-1); + return(uv_row[vi].ncum + ui); +} + +static int +uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ +{ + int upper, lower; + register int ui, vi; + + if (c < 0 || c >= UV_NDIVS) + return(-1); + lower = 0; /* binary search */ + upper = UV_NVS; + do { + vi = (lower + upper) >> 1; + ui = c - uv_row[vi].ncum; + if (ui > 0) + lower = vi; + else if (ui < 0) + upper = vi; + else + break; + } while (upper - lower > 1); + vi = lower; + ui = c - uv_row[vi].ncum; + *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; + *vp = UV_VSTART + (vi+.5)*UV_SQSIZ; + return(0); +} + +static void +pix24toXYZ(uint32 p, float XYZ[3]) +{ + int Le, Ce; + double L, u, v, s, x, y; + /* decode luminance */ + Le = p >> 14 & 0x3ff; + if (Le == 0) { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + L = exp(LOGOF2/64.*(Le+.5) - LOGOF2*12.); + /* decode color */ + Ce = p & 0x3fff; + if (uv_decode(&u, &v, Ce) < 0) { + u = U_NEU; v = V_NEU; + } + s = 1./(6.*u - 16.*v + 12.); + x = 9.*u * s; + y = 4.*v * s; + /* convert to XYZ */ + XYZ[0] = x/y * L; + XYZ[1] = L; + XYZ[2] = (1.-x-y)/y * L; +} + +static uint32 +pix24fromXYZ(float XYZ[3]) +{ + int Le, Ce; + double L, u, v, s; + /* encode luminance */ + L = XYZ[1]; + if (L >= 16.) + Le = 0x3ff; + else if (L <= 1./4096.) + Le = 0; + else + Le = 64.*(log2(L) + 12.); + /* encode color */ + s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; + if (s == 0.) { + u = U_NEU; + v = V_NEU; + } else { + u = 4.*XYZ[0] / s; + v = 9.*XYZ[1] / s; + } + Ce = uv_encode(u, v); + if (Ce < 0) + Ce = uv_encode(U_NEU, V_NEU); + /* combine encodings */ + return (Le << 14 | Ce); +} + +static void +Luv24toXYZ(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + pix24toXYZ(*luv, xyz); + xyz += 3; + luv++; + } +} + +static void +Luv24toLuv48(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + double u, v; + + *luv3++ = (*luv >> 12 & 0xffd) + 13314; + if (uv_decode(&u, &v, *luv&0x3fff) < 0) { + u = U_NEU; + v = V_NEU; + } + *luv3++ = u * (1L<<15); + *luv3++ = v * (1L<<15); + luv++; + } +} + +static void +Luv24toRGB(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + uint8* rgb = (uint8*) op; + + while (n-- > 0) { + float xyz[3]; + + pix24toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } +} + +static void +Luv24fromXYZ(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + *luv++ = pix24fromXYZ(xyz); + xyz += 3; + } +} + +static void +Luv24fromLuv48(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + int Le, Ce; + + if (luv3[0] <= 0) + Le = 0; + else if (luv3[0] >= (1<<12)+3314) + Le = (1<<10) - 1; + else + Le = (luv3[0]-3314) >> 2; + Ce = uv_encode((luv[1]+.5)/(1<<15), (luv[2]+.5)/(1<<15)); + if (Ce < 0) + Ce = uv_encode(U_NEU, V_NEU); + *luv++ = (uint32)Le << 14 | Ce; + luv3 += 3; + } +} + +static void +pix32toXYZ(uint32 p, float XYZ[3]) +{ + double L, u, v, s, x, y; + /* decode luminance */ + L = pix16toY((int)p >> 16); + if (L == 0.) { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + u = 1./UVSCALE * ((p>>8 & 0xff) + .5); + v = 1./UVSCALE * ((p & 0xff) + .5); + s = 1./(6.*u - 16.*v + 12.); + x = 9.*u * s; + y = 4.*v * s; + /* convert to XYZ */ + XYZ[0] = x/y * L; + XYZ[1] = L; + XYZ[2] = (1.-x-y)/y * L; +} + +static uint32 +pix32fromXYZ(float XYZ[3]) +{ + unsigned int Le, ue, ve; + double u, v, s; + /* encode luminance */ + Le = (unsigned int)pix16fromY(XYZ[1]); + /* encode color */ + s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; + if (s == 0.) { + u = U_NEU; + v = V_NEU; + } else { + u = 4.*XYZ[0] / s; + v = 9.*XYZ[1] / s; + } + if (u <= 0.) ue = 0; + else ue = UVSCALE * u; + if (ue > 255) ue = 255; + if (v <= 0.) ve = 0; + else ve = UVSCALE * v; + if (ve > 255) ve = 255; + /* combine encodings */ + return (Le << 16 | ue << 8 | ve); +} + +static void +Luv32toXYZ(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + pix32toXYZ(*luv++, xyz); + xyz += 3; + } +} + +static void +Luv32toLuv48(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + double u, v; + + *luv3++ = *luv >> 16; + u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5); + v = 1./UVSCALE * ((*luv & 0xff) + .5); + *luv3++ = u * (1L<<15); + *luv3++ = v * (1L<<15); + luv++; + } +} + +static void +Luv32toRGB(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + uint8* rgb = (uint8*) op; + + while (n-- > 0) { + float xyz[3]; + + pix32toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } +} + +static void +Luv32fromXYZ(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + float* xyz = (float*) op; + + while (n-- > 0) { + *luv++ = pix32fromXYZ(xyz); + xyz += 3; + } +} + +static void +Luv32fromLuv48(LogLuvState* sp, tidata_t op, int n) +{ + uint32* luv = (uint32*) sp->tbuf; + int16* luv3 = (int16*) op; + + while (n-- > 0) { + *luv++ = (uint32)luv3[0] << 16 | + (luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) | + (luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff); + luv3 += 3; + } +} + +static void +_logLuvNop(LogLuvState* sp, tidata_t op, int n) +{ + (void) sp; (void) op; (void) n; +} + +static int +LogL16GuessDataFmt(TIFFDirectory *td) +{ +#define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f)) + switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) { + case PACK(1, 32, SAMPLEFORMAT_IEEEFP): + return (SGILOGDATAFMT_FLOAT); + case PACK(1, 16, SAMPLEFORMAT_VOID): + case PACK(1, 16, SAMPLEFORMAT_INT): + case PACK(1, 16, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_16BIT); + case PACK(1, 8, SAMPLEFORMAT_VOID): + case PACK(1, 8, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_8BIT); + } +#undef PACK + return (SGILOGDATAFMT_UNKNOWN); +} + +static int +LogL16InitState(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + LogLuvState* sp = DecoderState(tif); + static const char module[] = "LogL16InitState"; + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGL); + + /* for some reason, we can't do this in TIFFInitLogL16 */ + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogL16GuessDataFmt(td); + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = sizeof (float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = sizeof (int16); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = sizeof (uint8); + break; + default: + TIFFError(tif->tif_name, + "No support for converting user data format to LogL"); + return (0); + } + sp->tbuflen = td->td_imagewidth * td->td_rowsperstrip; + sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16)); + if (sp->tbuf == NULL) { + TIFFError(module, "%s: No space for SGILog translation buffer", + tif->tif_name); + return (0); + } + return (1); +} + +static int +LogLuvGuessDataFmt(TIFFDirectory *td) +{ + int guess; + + /* + * If the user didn't tell us their datafmt, + * take our best guess from the bitspersample. + */ +#define PACK(a,b) (((a)<<3)|(b)) + switch (PACK(td->td_bitspersample, td->td_sampleformat)) { + case PACK(32, SAMPLEFORMAT_IEEEFP): + guess = SGILOGDATAFMT_FLOAT; + break; + case PACK(32, SAMPLEFORMAT_VOID): + case PACK(32, SAMPLEFORMAT_UINT): + case PACK(32, SAMPLEFORMAT_INT): + guess = SGILOGDATAFMT_RAW; + break; + case PACK(16, SAMPLEFORMAT_VOID): + case PACK(16, SAMPLEFORMAT_INT): + case PACK(16, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_16BIT; + break; + case PACK( 8, SAMPLEFORMAT_VOID): + case PACK( 8, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_8BIT; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; +#undef PACK + } + /* + * Double-check samples per pixel. + */ + switch (td->td_samplesperpixel) { + case 1: + if (guess != SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + case 3: + if (guess == SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; + } + return (guess); +} + +static int +LogLuvInitState(TIFF* tif) +{ + TIFFDirectory* td = &tif->tif_dir; + LogLuvState* sp = DecoderState(tif); + static const char module[] = "LogLuvInitState"; + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGLUV); + + /* for some reason, we can't do this in TIFFInitLogLuv */ + if (td->td_planarconfig != PLANARCONFIG_CONTIG) { + TIFFError(module, + "SGILog compression cannot handle non-contiguous data"); + return (0); + } + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogLuvGuessDataFmt(td); + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = 3*sizeof (float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = 3*sizeof (int16); + break; + case SGILOGDATAFMT_RAW: + sp->pixel_size = sizeof (uint32); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = 3*sizeof (uint8); + break; + default: + TIFFError(tif->tif_name, + "No support for converting user data format to LogLuv"); + return (0); + } + sp->tbuflen = td->td_imagewidth * td->td_rowsperstrip; + sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32)); + if (sp->tbuf == NULL) { + TIFFError(module, "%s: No space for SGILog translation buffer", + tif->tif_name); + return (0); + } + return (1); +} + +static int +LogLuvSetupDecode(TIFF* tif) +{ + LogLuvState* sp = DecoderState(tif); + TIFFDirectory* td = &tif->tif_dir; + + tif->tif_postdecode = _TIFFNoPostDecode; + switch (td->td_photometric) { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + break; + if (td->td_compression == COMPRESSION_SGILOG24) { + tif->tif_decoderow = LogLuvDecode24; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv24toRGB; + break; + } + } else { + tif->tif_decoderow = LogLuvDecode32; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv32toRGB; + break; + } + } + return (1); + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + break; + tif->tif_decoderow = LogL16Decode; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16toY; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = L16toGry; + break; + } + return (1); + default: + TIFFError(tif->tif_name, + "Inappropriate photometric interpretation %d for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + break; + } + return (0); +} + +static int +LogLuvSetupEncode(TIFF* tif) +{ + LogLuvState* sp = EncoderState(tif); + TIFFDirectory* td = &tif->tif_dir; + + switch (td->td_photometric) { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + break; + if (td->td_compression == COMPRESSION_SGILOG24) { + tif->tif_encoderow = LogLuvEncode24; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } else { + tif->tif_encoderow = LogLuvEncode32; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } + break; + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + break; + tif->tif_encoderow = LogL16Encode; + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16fromY; + break; + case SGILOGDATAFMT_16BIT: + break; + default: + goto notsupported; + } + break; + default: + TIFFError(tif->tif_name, + "Inappropriate photometric interpretation %d for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + break; + } + return (1); +notsupported: + TIFFError(tif->tif_name, + "SGILog compression supported only for %s, or raw data", + td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); + return (0); +} + +static void +LogLuvClose(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + + /* + * For consistency, we always want to write out the same + * bitspersample and sampleformat for our TIFF file, + * regardless of the data format being used by the application. + * Since this routine is called after tags have been set but + * before they have been recorded in the file, we reset them here. + */ + td->td_samplesperpixel = + (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; + td->td_bitspersample = 16; + td->td_sampleformat = SAMPLEFORMAT_INT; +} + +static void +LogLuvCleanup(TIFF* tif) +{ + LogLuvState* sp = (LogLuvState *)tif->tif_data; + + if (sp) { + if (sp->tbuf) + _TIFFfree(sp->tbuf); + _TIFFfree(sp); + tif->tif_data = NULL; + } +} + +static int +LogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + LogLuvState* sp = DecoderState(tif); + int bps, fmt; + + switch (tag) { + case TIFFTAG_SGILOGDATAFMT: + sp->user_datafmt = va_arg(ap, int); + /* + * Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) { + case SGILOGDATAFMT_FLOAT: + bps = 32, fmt = SAMPLEFORMAT_IEEEFP; + break; + case SGILOGDATAFMT_16BIT: + bps = 16, fmt = SAMPLEFORMAT_INT; + break; + case SGILOGDATAFMT_RAW: + bps = 32, fmt = SAMPLEFORMAT_UINT; + break; + case SGILOGDATAFMT_8BIT: + bps = 8, fmt = SAMPLEFORMAT_UINT; + break; + default: + TIFFError(tif->tif_name, + "Unknown data format %d for LogLuv compression", + sp->user_datafmt); + return (0); + } + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = TIFFTileSize(tif); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + return (1); + default: + return (*sp->vsetparent)(tif, tag, ap); + } +} + +static int +LogLuvVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + LogLuvState *sp = (LogLuvState *)tif->tif_data; + + switch (tag) { + case TIFFTAG_SGILOGDATAFMT: + *va_arg(ap, int*) = sp->user_datafmt; + return (1); + default: + return (*sp->vgetparent)(tif, tag, ap); + } +} + +static const TIFFFieldInfo LogLuvFieldInfo[] = { + { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, FIELD_PSEUDO, + TRUE, FALSE, "SGILogDataFmt"} +}; + +int +TIFFInitSGILog(TIFF* tif, int scheme) +{ + static const char module[] = "TIFFInitSGILog"; + LogLuvState* sp; + + assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LogLuvState)); + if (tif->tif_data == NULL) + goto bad; + sp = (LogLuvState*) tif->tif_data; + memset(sp, 0, sizeof (*sp)); + sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; + sp->tfunc = _logLuvNop; + + /* + * Install codec methods. + * NB: tif_decoderow & tif_encoderow are filled + * in at setup time. + */ + tif->tif_setupdecode = LogLuvSetupDecode; + tif->tif_decodestrip = LogLuvDecodeStrip; + tif->tif_decodetile = LogLuvDecodeTile; + tif->tif_setupencode = LogLuvSetupEncode; + tif->tif_encodestrip = LogLuvEncodeStrip; + tif->tif_encodetile = LogLuvEncodeTile; + tif->tif_close = LogLuvClose; + tif->tif_cleanup = LogLuvCleanup; + + /* override SetField so we can handle our private pseudo-tag */ + _TIFFMergeFieldInfo(tif, LogLuvFieldInfo, N(LogLuvFieldInfo)); + sp->vgetparent = tif->tif_vgetfield; + tif->tif_vgetfield = LogLuvVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_vsetfield; + tif->tif_vsetfield = LogLuvVSetField; /* hook for codec tags */ + + return (1); +bad: + TIFFError(module, "%s: No space for LogLuv state block", tif->tif_name); + return (0); +} +#endif /* LOGLUV_SUPPORT */ diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c new file mode 100644 index 00000000..de7d7806 --- /dev/null +++ b/libtiff/tif_lzw.c @@ -0,0 +1,1013 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_lzw.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef LZW_SUPPORT +/* + * TIFF Library. + * Rev 5.0 Lempel-Ziv & Welch Compression Support + * + * This code is derived from the compress program whose code is + * derived from software contributed to Berkeley by James A. Woods, + * derived from original work by Spencer Thomas and Joseph Orost. + * + * The original Berkeley copyright notice appears below in its entirety. + */ +#include "tif_predict.h" + +#include +#include + +/* + * NB: The 5.0 spec describes a different algorithm than Aldus + * implements. Specifically, Aldus does code length transitions + * one code earlier than should be done (for real LZW). + * Earlier versions of this library implemented the correct + * LZW algorithm, but emitted codes in a bit order opposite + * to the TIFF spec. Thus, to maintain compatibility w/ Aldus + * we interpret MSB-LSB ordered codes to be images written w/ + * old versions of this library, but otherwise adhere to the + * Aldus "off by one" algorithm. + * + * Future revisions to the TIFF spec are expected to "clarify this issue". + */ +#define LZW_COMPAT /* include backwards compatibility code */ +/* + * Each strip of data is supposed to be terminated by a CODE_EOI. + * If the following #define is included, the decoder will also + * check for end-of-strip w/o seeing this code. This makes the + * library more robust, but also slower. + */ +#define LZW_CHECKEOS /* include checks for strips w/o EOI code */ + +#define MAXCODE(n) ((1L<<(n))-1) +/* + * The TIFF spec specifies that encoded bit + * strings range from 9 to 12 bits. + */ +#define BITS_MIN 9 /* start with 9 bits */ +#define BITS_MAX 12 /* max of 12 bit strings */ +/* predefined codes */ +#define CODE_CLEAR 256 /* code to clear string table */ +#define CODE_EOI 257 /* end-of-information code */ +#define CODE_FIRST 258 /* first free code entry */ +#define CODE_MAX MAXCODE(BITS_MAX) +#define HSIZE 9001L /* 91% occupancy */ +#define HSHIFT (13-8) +#ifdef LZW_COMPAT +/* NB: +1024 is for compatibility with old files */ +#define CSIZE (MAXCODE(BITS_MAX)+1024L) +#else +#define CSIZE (MAXCODE(BITS_MAX)+1L) +#endif + +/* + * State block for each open TIFF file using LZW + * compression/decompression. Note that the predictor + * state block must be first in this data structure. + */ +typedef struct { + TIFFPredictorState predict; /* predictor super class */ + + u_short nbits; /* # of bits/code */ + u_short maxcode; /* maximum code for lzw_nbits */ + u_short free_ent; /* next free entry in hash table */ + long nextdata; /* next bits of i/o */ + long nextbits; /* # of valid bits in lzw_nextdata */ +} LZWBaseState; + +#define lzw_nbits base.nbits +#define lzw_maxcode base.maxcode +#define lzw_free_ent base.free_ent +#define lzw_nextdata base.nextdata +#define lzw_nextbits base.nextbits + +/* + * Decoding-specific state. + */ +typedef struct code_ent { + struct code_ent *next; + u_short length; /* string len, including this token */ + u_char value; /* data value */ + u_char firstchar; /* first token of string */ +} code_t; + +typedef int (*decodeFunc)(TIFF*, tidata_t, tsize_t, tsample_t); + +typedef struct { + LZWBaseState base; + long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ + long dec_restart; /* restart count */ +#ifdef LZW_CHECKEOS + long dec_bitsleft; /* available bits in raw data */ +#endif + decodeFunc dec_decode; /* regular or backwards compatible */ + code_t* dec_codep; /* current recognized code */ + code_t* dec_oldcodep; /* previously recognized code */ + code_t* dec_free_entp; /* next free entry */ + code_t* dec_maxcodep; /* max available entry */ + code_t* dec_codetab; /* kept separate for small machines */ +} LZWDecodeState; + +/* + * Encoding-specific state. + */ +typedef uint16 hcode_t; /* codes fit in 16 bits */ +typedef struct { + long hash; + hcode_t code; +} hash_t; + +typedef struct { + LZWBaseState base; + int enc_oldcode; /* last code encountered */ + long enc_checkpoint; /* point at which to clear table */ +#define CHECK_GAP 10000 /* enc_ratio check interval */ + long enc_ratio; /* current compression ratio */ + long enc_incount; /* (input) data bytes encoded */ + long enc_outcount; /* encoded (output) bytes */ + tidata_t enc_rawlimit; /* bound on tif_rawdata buffer */ + hash_t* enc_hashtab; /* kept separate for small machines */ +} LZWEncodeState; + +#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data) +#define DecoderState(tif) ((LZWDecodeState*) LZWState(tif)) +#define EncoderState(tif) ((LZWEncodeState*) LZWState(tif)) + +static int LZWDecode(TIFF*, tidata_t, tsize_t, tsample_t); +#ifdef LZW_COMPAT +static int LZWDecodeCompat(TIFF*, tidata_t, tsize_t, tsample_t); +#endif +static void cl_hash(LZWEncodeState*); + +/* + * LZW Decoder. + */ + +#ifdef LZW_CHECKEOS +/* + * This check shouldn't be necessary because each + * strip is suppose to be terminated with CODE_EOI. + */ +#define NextCode(_tif, _sp, _bp, _code, _get) { \ + if ((_sp)->dec_bitsleft < nbits) { \ + TIFFWarning(_tif->tif_name, \ + "LZWDecode: Strip %d not terminated with EOI code", \ + _tif->tif_curstrip); \ + _code = CODE_EOI; \ + } else { \ + _get(_sp,_bp,_code); \ + (_sp)->dec_bitsleft -= nbits; \ + } \ +} +#else +#define NextCode(tif, sp, bp, code, get) get(sp, bp, code) +#endif + +static int +LZWSetupDecode(TIFF* tif) +{ + LZWDecodeState* sp = DecoderState(tif); + static const char module[] = " LZWSetupDecode"; + int code; + + assert(sp != NULL); + if (sp->dec_codetab == NULL) { + sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t)); + if (sp->dec_codetab == NULL) { + TIFFError(module, "No space for LZW code table"); + return (0); + } + /* + * Pre-load the table. + */ + for (code = 255; code >= 0; code--) { + sp->dec_codetab[code].value = code; + sp->dec_codetab[code].firstchar = code; + sp->dec_codetab[code].length = 1; + sp->dec_codetab[code].next = NULL; + } + } + return (1); +} + +/* + * Setup state for decoding a strip. + */ +static int +LZWPreDecode(TIFF* tif, tsample_t s) +{ + LZWDecodeState *sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + /* + * Check for old bit-reversed codes. + */ + if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { +#ifdef LZW_COMPAT + if (!sp->dec_decode) { + TIFFWarning(tif->tif_name, + "Old-style LZW codes, convert file"); + /* + * Override default decoding methods with + * ones that deal with the old coding. + * Otherwise the predictor versions set + * above will call the compatibility routines + * through the dec_decode method. + */ + tif->tif_decoderow = LZWDecodeCompat; + tif->tif_decodestrip = LZWDecodeCompat; + tif->tif_decodetile = LZWDecodeCompat; + /* + * If doing horizontal differencing, must + * re-setup the predictor logic since we + * switched the basic decoder methods... + */ + (*tif->tif_setupdecode)(tif); + sp->dec_decode = LZWDecodeCompat; + } + sp->lzw_maxcode = MAXCODE(BITS_MIN); +#else /* !LZW_COMPAT */ + if (!sp->dec_decode) { + TIFFError(tif->tif_name, + "Old-style LZW codes not supported"); + sp->dec_decode = LZWDecode; + } + return (0); +#endif/* !LZW_COMPAT */ + } else { + sp->lzw_maxcode = MAXCODE(BITS_MIN)-1; + sp->dec_decode = LZWDecode; + } + sp->lzw_nbits = BITS_MIN; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + + sp->dec_restart = 0; + sp->dec_nbitsmask = MAXCODE(BITS_MIN); +#ifdef LZW_CHECKEOS + sp->dec_bitsleft = tif->tif_rawcc << 3; +#endif + sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; + /* + * Zero entries that are not yet filled in. We do + * this to guard against bogus input data that causes + * us to index into undefined entries. If you can + * come up with a way to safely bounds-check input codes + * while decoding then you can remove this operation. + */ + _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t)); + sp->dec_oldcodep = &sp->dec_codetab[-1]; + sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; + return (1); +} + +/* + * Decode a "hunk of data". + */ +#define GetNextCode(sp, bp, code) { \ + nextdata = (nextdata<<8) | *(bp)++; \ + nextbits += 8; \ + if (nextbits < nbits) { \ + nextdata = (nextdata<<8) | *(bp)++; \ + nextbits += 8; \ + } \ + code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \ + nextbits -= nbits; \ +} + +static void +codeLoop(TIFF* tif) +{ + TIFFError(tif->tif_name, + "LZWDecode: Bogus encoding, loop in the code table; scanline %d", + tif->tif_row); +} + +static int +LZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +{ + LZWDecodeState *sp = DecoderState(tif); + char *op = (char*) op0; + long occ = (long) occ0; + char *tp; + u_char *bp; + hcode_t code; + int len; + long nbits, nextbits, nextdata, nbitsmask; + code_t *codep, *free_entp, *maxcodep, *oldcodep; + + (void) s; + assert(sp != NULL); + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) { + long residue; + + codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do { + codep = codep->next; + } while (--residue > occ && codep); + if (codep) { + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ && codep); + } + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue, occ -= residue; + tp = op; + do { + int t; + --tp; + t = codep->value; + codep = codep->next; + *tp = t; + } while (--residue && codep); + sp->dec_restart = 0; + } + + bp = (u_char *)tif->tif_rawcp; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + + while (occ > 0) { + NextCode(tif, sp, bp, code, GetNextCode); + if (code == CODE_EOI) + break; + if (code == CODE_CLEAR) { + free_entp = sp->dec_codetab + CODE_FIRST; + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = sp->dec_codetab + nbitsmask-1; + NextCode(tif, sp, bp, code, GetNextCode); + if (code == CODE_EOI) + break; + *op++ = code, occ--; + oldcodep = sp->dec_codetab + code; + continue; + } + codep = sp->dec_codetab + code; + + /* + * Add the new entry to the code table. + */ + assert(&sp->dec_codetab[0] <= free_entp && free_entp < &sp->dec_codetab[CSIZE]); + free_entp->next = oldcodep; + free_entp->firstchar = free_entp->next->firstchar; + free_entp->length = free_entp->next->length+1; + free_entp->value = (codep < free_entp) ? + codep->firstchar : free_entp->firstchar; + if (++free_entp > maxcodep) { + if (++nbits > BITS_MAX) /* should not happen */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = sp->dec_codetab + nbitsmask-1; + } + oldcodep = codep; + if (code >= 256) { + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + if (codep->length > occ) { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do { + codep = codep->next; + } while (codep && codep->length > occ); + if (codep) { + sp->dec_restart = occ; + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ && codep); + if (codep) + codeLoop(tif); + } + break; + } + len = codep->length; + tp = op + len; + do { + int t; + --tp; + t = codep->value; + codep = codep->next; + *tp = t; + } while (codep && tp > op); + if (codep) { + codeLoop(tif); + break; + } + op += len, occ -= len; + } else + *op++ = code, occ--; + } + + tif->tif_rawcp = (tidata_t) bp; + sp->lzw_nbits = (u_short) nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) { + TIFFError(tif->tif_name, + "LZWDecode: Not enough data at scanline %d (short %d bytes)", + tif->tif_row, occ); + return (0); + } + return (1); +} + +#ifdef LZW_COMPAT +/* + * Decode a "hunk of data" for old images. + */ +#define GetNextCodeCompat(sp, bp, code) { \ + nextdata |= (u_long) *(bp)++ << nextbits; \ + nextbits += 8; \ + if (nextbits < nbits) { \ + nextdata |= (u_long) *(bp)++ << nextbits; \ + nextbits += 8; \ + } \ + code = (hcode_t)(nextdata & nbitsmask); \ + nextdata >>= nbits; \ + nextbits -= nbits; \ +} + +static int +LZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +{ + LZWDecodeState *sp = DecoderState(tif); + char *op = (char*) op0; + long occ = (long) occ0; + char *tp; + u_char *bp; + int code, nbits; + long nextbits, nextdata, nbitsmask; + code_t *codep, *free_entp, *maxcodep, *oldcodep; + + (void) s; + assert(sp != NULL); + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) { + long residue; + + codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do { + codep = codep->next; + } while (--residue > occ); + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue, occ -= residue; + tp = op; + do { + *--tp = codep->value; + codep = codep->next; + } while (--residue); + sp->dec_restart = 0; + } + + bp = (u_char *)tif->tif_rawcp; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + + while (occ > 0) { + NextCode(tif, sp, bp, code, GetNextCodeCompat); + if (code == CODE_EOI) + break; + if (code == CODE_CLEAR) { + free_entp = sp->dec_codetab + CODE_FIRST; + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = sp->dec_codetab + nbitsmask; + NextCode(tif, sp, bp, code, GetNextCodeCompat); + if (code == CODE_EOI) + break; + *op++ = code, occ--; + oldcodep = sp->dec_codetab + code; + continue; + } + codep = sp->dec_codetab + code; + + /* + * Add the new entry to the code table. + */ + assert(&sp->dec_codetab[0] <= free_entp && free_entp < &sp->dec_codetab[CSIZE]); + free_entp->next = oldcodep; + free_entp->firstchar = free_entp->next->firstchar; + free_entp->length = free_entp->next->length+1; + free_entp->value = (codep < free_entp) ? + codep->firstchar : free_entp->firstchar; + if (++free_entp > maxcodep) { + if (++nbits > BITS_MAX) /* should not happen */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = sp->dec_codetab + nbitsmask; + } + oldcodep = codep; + if (code >= 256) { + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + if (codep->length > occ) { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do { + codep = codep->next; + } while (codep->length > occ); + sp->dec_restart = occ; + tp = op + occ; + do { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + break; + } + op += codep->length, occ -= codep->length; + tp = op; + do { + *--tp = codep->value; + } while (codep = codep->next); + } else + *op++ = code, occ--; + } + + tif->tif_rawcp = (tidata_t) bp; + sp->lzw_nbits = nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) { + TIFFError(tif->tif_name, + "LZWDecodeCompat: Not enough data at scanline %d (short %d bytes)", + tif->tif_row, occ); + return (0); + } + return (1); +} +#endif /* LZW_COMPAT */ + +/* + * LZW Encoding. + */ + +static int +LZWSetupEncode(TIFF* tif) +{ + LZWEncodeState* sp = EncoderState(tif); + static const char module[] = "LZWSetupEncode"; + + assert(sp != NULL); + sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t)); + if (sp->enc_hashtab == NULL) { + TIFFError(module, "No space for LZW hash table"); + return (0); + } + return (1); +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +LZWPreEncode(TIFF* tif, tsample_t s) +{ + LZWEncodeState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + sp->lzw_nbits = BITS_MIN; + sp->lzw_maxcode = MAXCODE(BITS_MIN); + sp->lzw_free_ent = CODE_FIRST; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + sp->enc_checkpoint = CHECK_GAP; + sp->enc_ratio = 0; + sp->enc_incount = 0; + sp->enc_outcount = 0; + /* + * The 4 here insures there is space for 2 max-sized + * codes in LZWEncode and LZWPostDecode. + */ + sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4; + cl_hash(sp); /* clear hash table */ + sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */ + return (1); +} + +#define CALCRATIO(sp, rat) { \ + if (incount > 0x007fffff) { /* NB: shift will overflow */\ + rat = outcount >> 8; \ + rat = (rat == 0 ? 0x7fffffff : incount/rat); \ + } else \ + rat = (incount<<8) / outcount; \ +} +#define PutNextCode(op, c) { \ + nextdata = (nextdata << nbits) | c; \ + nextbits += nbits; \ + *op++ = (u_char)(nextdata >> (nextbits-8)); \ + nextbits -= 8; \ + if (nextbits >= 8) { \ + *op++ = (u_char)(nextdata >> (nextbits-8)); \ + nextbits -= 8; \ + } \ + outcount += nbits; \ +} + +/* + * Encode a chunk of pixels. + * + * Uses an open addressing double hashing (no chaining) on the + * prefix code/next character combination. We do a variant of + * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's + * relatively-prime secondary probe. Here, the modular division + * first probe is gives way to a faster exclusive-or manipulation. + * Also do block compression with an adaptive reset, whereby the + * code table is cleared when the compression ratio decreases, + * but after the table fills. The variable-length output codes + * are re-sized at this point, and a CODE_CLEAR is generated + * for the decoder. + */ +static int +LZWEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + register LZWEncodeState *sp = EncoderState(tif); + register long fcode; + register hash_t *hp; + register int h, c; + hcode_t ent; + long disp; + long incount, outcount, checkpoint; + long nextdata, nextbits; + int free_ent, maxcode, nbits; + tidata_t op, limit; + + (void) s; + if (sp == NULL) + return (0); + /* + * Load local state. + */ + incount = sp->enc_incount; + outcount = sp->enc_outcount; + checkpoint = sp->enc_checkpoint; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + free_ent = sp->lzw_free_ent; + maxcode = sp->lzw_maxcode; + nbits = sp->lzw_nbits; + op = tif->tif_rawcp; + limit = sp->enc_rawlimit; + ent = sp->enc_oldcode; + + if (ent == (hcode_t) -1 && cc > 0) { + /* + * NB: This is safe because it can only happen + * at the start of a strip where we know there + * is space in the data buffer. + */ + PutNextCode(op, CODE_CLEAR); + ent = *bp++; cc--; incount++; + } + while (cc > 0) { + c = *bp++; cc--; incount++; + fcode = ((long)c << BITS_MAX) + ent; + h = (c << HSHIFT) ^ ent; /* xor hashing */ +#ifdef _WINDOWS + /* + * Check hash index for an overflow. + */ + if (h >= HSIZE) + h -= HSIZE; +#endif + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) { + ent = hp->code; + continue; + } + if (hp->hash >= 0) { + /* + * Primary hash failed, check secondary hash. + */ + disp = HSIZE - h; + if (h == 0) + disp = 1; + do { + /* + * Avoid pointer arithmetic 'cuz of + * wraparound problems with segments. + */ + if ((h -= disp) < 0) + h += HSIZE; + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) { + ent = hp->code; + goto hit; + } + } while (hp->hash >= 0); + } + /* + * New entry, emit code and add to table. + */ + /* + * Verify there is space in the buffer for the code + * and any potential Clear code that might be emitted + * below. The value of limit is setup so that there + * are at least 4 bytes free--room for 2 codes. + */ + if (op > limit) { + tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); + TIFFFlushData1(tif); + op = tif->tif_rawdata; + } + PutNextCode(op, ent); + ent = c; + hp->code = free_ent++; + hp->hash = fcode; + if (free_ent == CODE_MAX-1) { + /* table is full, emit clear code and reset */ + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } else { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > maxcode) { + nbits++; + assert(nbits <= BITS_MAX); + maxcode = (int) MAXCODE(nbits); + } else if (incount >= checkpoint) { + long rat; + /* + * Check compression ratio and, if things seem + * to be slipping, clear the hash table and + * reset state. The compression ratio is a + * 24+8-bit fractional number. + */ + checkpoint = incount+CHECK_GAP; + CALCRATIO(sp, rat); + if (rat <= sp->enc_ratio) { + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } else + sp->enc_ratio = rat; + } + } + hit: + ; + } + + /* + * Restore global state. + */ + sp->enc_incount = incount; + sp->enc_outcount = outcount; + sp->enc_checkpoint = checkpoint; + sp->enc_oldcode = ent; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->lzw_free_ent = free_ent; + sp->lzw_maxcode = maxcode; + sp->lzw_nbits = nbits; + tif->tif_rawcp = op; + return (1); +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ +static int +LZWPostEncode(TIFF* tif) +{ + register LZWEncodeState *sp = EncoderState(tif); + tidata_t op = tif->tif_rawcp; + long nextbits = sp->lzw_nextbits; + long nextdata = sp->lzw_nextdata; + long outcount = sp->enc_outcount; + int nbits = sp->lzw_nbits; + + if (op > sp->enc_rawlimit) { + tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); + TIFFFlushData1(tif); + op = tif->tif_rawdata; + } + if (sp->enc_oldcode != (hcode_t) -1) { + PutNextCode(op, sp->enc_oldcode); + sp->enc_oldcode = (hcode_t) -1; + } + PutNextCode(op, CODE_EOI); + if (nextbits > 0) + *op++ = (u_char)(nextdata << (8-nextbits)); + tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata); + return (1); +} + +/* + * Reset encoding hash table. + */ +static void +cl_hash(LZWEncodeState* sp) +{ + register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; + register long i = HSIZE-8; + + do { + i -= 8; + hp[-7].hash = -1; + hp[-6].hash = -1; + hp[-5].hash = -1; + hp[-4].hash = -1; + hp[-3].hash = -1; + hp[-2].hash = -1; + hp[-1].hash = -1; + hp[ 0].hash = -1; + hp -= 8; + } while (i >= 0); + for (i += 8; i > 0; i--, hp--) + hp->hash = -1; +} + +static void +LZWCleanup(TIFF* tif) +{ + if (tif->tif_data) { + if (tif->tif_mode == O_RDONLY) { + if (DecoderState(tif)->dec_codetab) + _TIFFfree(DecoderState(tif)->dec_codetab); + } else { + if (EncoderState(tif)->enc_hashtab) + _TIFFfree(EncoderState(tif)->enc_hashtab); + } + _TIFFfree(tif->tif_data); + tif->tif_data = NULL; + } +} + +int +TIFFInitLZW(TIFF* tif, int scheme) +{ + assert(scheme == COMPRESSION_LZW); + /* + * Allocate state block so tag methods have storage to record values. + */ + if (tif->tif_mode == O_RDONLY) { + tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LZWDecodeState)); + if (tif->tif_data == NULL) + goto bad; + DecoderState(tif)->dec_codetab = NULL; + DecoderState(tif)->dec_decode = NULL; + } else { + tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LZWEncodeState)); + if (tif->tif_data == NULL) + goto bad; + EncoderState(tif)->enc_hashtab = NULL; + } + /* + * Install codec methods. + */ + tif->tif_setupdecode = LZWSetupDecode; + tif->tif_predecode = LZWPreDecode; + tif->tif_decoderow = LZWDecode; + tif->tif_decodestrip = LZWDecode; + tif->tif_decodetile = LZWDecode; + tif->tif_setupencode = LZWSetupEncode; + tif->tif_preencode = LZWPreEncode; + tif->tif_postencode = LZWPostEncode; + tif->tif_encoderow = LZWEncode; + tif->tif_encodestrip = LZWEncode; + tif->tif_encodetile = LZWEncode; + tif->tif_cleanup = LZWCleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return (1); +bad: + TIFFError("TIFFInitLZW", "No space for LZW state block"); + return (0); +} + +/* + * Copyright (c) 1985, 1986 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * James A. Woods, derived from original work by Spencer Thomas + * and Joseph Orost. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#endif /* LZW_SUPPORT */ diff --git a/libtiff/tif_msdos.c b/libtiff/tif_msdos.c new file mode 100644 index 00000000..5b33b088 --- /dev/null +++ b/libtiff/tif_msdos.c @@ -0,0 +1,179 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_msdos.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library MSDOS-specific Routines. + */ +#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER) +#include /* for open, close, etc. function prototypes */ +#include +#endif +#include "tiffiop.h" + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (read((int) fd, buf, size)); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (write((int) fd, buf, size)); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + return (lseek((int) fd, (off_t) off, whence)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (close((int) fd)); +} + +#include + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + struct stat sb; + return (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size); +} + +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ +} + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (void*) fd, + _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, + _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); + fd = open(name, m|O_BINARY, 0666); + if (fd < 0) { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF*)0); + } + return (TIFFFdOpen(fd, name, mode)); +} + +#ifdef __GNUC__ +extern char* malloc(); +extern char* realloc(); +#else +#include +#endif + +tdata_t +_TIFFmalloc(tsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(tdata_t p) +{ + free(p); +} + +tdata_t +_TIFFrealloc(tdata_t p, tsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(tdata_t p, int v, tsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +static void +msdosWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFwarningHandler = msdosWarningHandler; + +static void +msdosErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFerrorHandler = msdosErrorHandler; diff --git a/libtiff/tif_next.c b/libtiff/tif_next.c new file mode 100644 index 00000000..13616561 --- /dev/null +++ b/libtiff/tif_next.c @@ -0,0 +1,142 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_next.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef NEXT_SUPPORT +/* + * TIFF Library. + * + * NeXT 2-bit Grey Scale Compression Algorithm Support + */ + +#define SETPIXEL(op, v) { \ + switch (npixels++ & 3) { \ + case 0: op[0] = (v) << 6; break; \ + case 1: op[0] |= (v) << 4; break; \ + case 2: op[0] |= (v) << 2; break; \ + case 3: *op++ |= (v); break; \ + } \ +} + +#define LITERALROW 0x00 +#define LITERALSPAN 0x40 +#define WHITE ((1<<2)-1) + +static int +NeXTDecode(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +{ + register u_char *bp, *op; + register tsize_t cc; + register int n; + tidata_t row; + tsize_t scanline; + + (void) s; + /* + * Each scanline is assumed to start off as all + * white (we assume a PhotometricInterpretation + * of ``min-is-black''). + */ + for (op = buf, cc = occ; cc-- > 0;) + *op++ = 0xff; + + bp = (u_char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + scanline = tif->tif_scanlinesize; + for (row = buf; (long)occ > 0; occ -= scanline, row += scanline) { + n = *bp++, cc--; + switch (n) { + case LITERALROW: + /* + * The entire scanline is given as literal values. + */ + if (cc < scanline) + goto bad; + _TIFFmemcpy(row, bp, scanline); + bp += scanline; + cc -= scanline; + break; + case LITERALSPAN: { + int off; + /* + * The scanline has a literal span + * that begins at some offset. + */ + off = (bp[0] * 256) + bp[1]; + n = (bp[2] * 256) + bp[3]; + if (cc < 4+n) + goto bad; + _TIFFmemcpy(row+off, bp+4, n); + bp += 4+n; + cc -= 4+n; + break; + } + default: { + register int npixels = 0, grey; + u_long imagewidth = tif->tif_dir.td_imagewidth; + + /* + * The scanline is composed of a sequence + * of constant color ``runs''. We shift + * into ``run mode'' and interpret bytes + * as codes of the form + * until we've filled the scanline. + */ + op = row; + for (;;) { + grey = (n>>6) & 0x3; + n &= 0x3f; + while (n-- > 0) + SETPIXEL(op, grey); + if (npixels >= imagewidth) + break; + if (cc == 0) + goto bad; + n = *bp++, cc--; + } + break; + } + } + } + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + return (1); +bad: + TIFFError(tif->tif_name, "NeXTDecode: Not enough data for scanline %ld", + (long) tif->tif_row); + return (0); +} + +int +TIFFInitNeXT(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_decoderow = NeXTDecode; + tif->tif_decodestrip = NeXTDecode; + tif->tif_decodetile = NeXTDecode; + return (1); +} +#endif /* NEXT_SUPPORT */ diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c new file mode 100644 index 00000000..f13545ba --- /dev/null +++ b/libtiff/tif_open.c @@ -0,0 +1,475 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_open.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +static const long typemask[13] = { + 0L, /* TIFF_NOTYPE */ + 0x000000ffL, /* TIFF_BYTE */ + 0xffffffffL, /* TIFF_ASCII */ + 0x0000ffffL, /* TIFF_SHORT */ + 0xffffffffL, /* TIFF_LONG */ + 0xffffffffL, /* TIFF_RATIONAL */ + 0x000000ffL, /* TIFF_SBYTE */ + 0x000000ffL, /* TIFF_UNDEFINED */ + 0x0000ffffL, /* TIFF_SSHORT */ + 0xffffffffL, /* TIFF_SLONG */ + 0xffffffffL, /* TIFF_SRATIONAL */ + 0xffffffffL, /* TIFF_FLOAT */ + 0xffffffffL, /* TIFF_DOUBLE */ +}; +static const int bigTypeshift[13] = { + 0, /* TIFF_NOTYPE */ + 24, /* TIFF_BYTE */ + 0, /* TIFF_ASCII */ + 16, /* TIFF_SHORT */ + 0, /* TIFF_LONG */ + 0, /* TIFF_RATIONAL */ + 24, /* TIFF_SBYTE */ + 24, /* TIFF_UNDEFINED */ + 16, /* TIFF_SSHORT */ + 0, /* TIFF_SLONG */ + 0, /* TIFF_SRATIONAL */ + 0, /* TIFF_FLOAT */ + 0, /* TIFF_DOUBLE */ +}; +static const int litTypeshift[13] = { + 0, /* TIFF_NOTYPE */ + 0, /* TIFF_BYTE */ + 0, /* TIFF_ASCII */ + 0, /* TIFF_SHORT */ + 0, /* TIFF_LONG */ + 0, /* TIFF_RATIONAL */ + 0, /* TIFF_SBYTE */ + 0, /* TIFF_UNDEFINED */ + 0, /* TIFF_SSHORT */ + 0, /* TIFF_SLONG */ + 0, /* TIFF_SRATIONAL */ + 0, /* TIFF_FLOAT */ + 0, /* TIFF_DOUBLE */ +}; + +/* + * Initialize the shift & mask tables, and the + * byte swapping state according to the file + * contents and the machine architecture. + */ +static void +TIFFInitOrder(TIFF* tif, int magic, int bigendian) +{ + tif->tif_typemask = typemask; + if (magic == TIFF_BIGENDIAN) { + tif->tif_typeshift = bigTypeshift; + if (!bigendian) + tif->tif_flags |= TIFF_SWAB; + } else { + tif->tif_typeshift = litTypeshift; + if (bigendian) + tif->tif_flags |= TIFF_SWAB; + } +} + +int +_TIFFgetMode(const char* mode, const char* module) +{ + int m = -1; + + switch (mode[0]) { + case 'r': + m = O_RDONLY; + if (mode[1] == '+') + m = O_RDWR; + break; + case 'w': + case 'a': + m = O_RDWR|O_CREAT; + if (mode[0] == 'w') + m |= O_TRUNC; + break; + default: + TIFFError(module, "\"%s\": Bad mode", mode); + break; + } + return (m); +} + +TIFF* +TIFFClientOpen( + const char* name, const char* mode, + thandle_t clientdata, + TIFFReadWriteProc readproc, + TIFFReadWriteProc writeproc, + TIFFSeekProc seekproc, + TIFFCloseProc closeproc, + TIFFSizeProc sizeproc, + TIFFMapFileProc mapproc, + TIFFUnmapFileProc unmapproc +) +{ + static const char module[] = "TIFFClientOpen"; + TIFF *tif; + int m, bigendian; + const char* cp; + + m = _TIFFgetMode(mode, module); + if (m == -1) + goto bad2; + tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1); + if (tif == NULL) { + TIFFError(module, "%s: Out of memory (TIFF structure)", name); + goto bad2; + } + _TIFFmemset(tif, 0, sizeof (*tif)); + tif->tif_name = (char *)tif + sizeof (TIFF); + strcpy(tif->tif_name, name); + tif->tif_mode = m &~ (O_CREAT|O_TRUNC); + tif->tif_curdir = (tdir_t) -1; /* non-existent directory */ + tif->tif_curoff = 0; + tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */ + tif->tif_row = (uint32) -1; /* read/write pre-increment */ + tif->tif_clientdata = clientdata; + tif->tif_readproc = readproc; + tif->tif_writeproc = writeproc; + tif->tif_seekproc = seekproc; + tif->tif_closeproc = closeproc; + tif->tif_sizeproc = sizeproc; + tif->tif_mapproc = mapproc; + tif->tif_unmapproc = unmapproc; + _TIFFSetDefaultCompressionState(tif); /* setup default state */ + /* + * Default is to return data MSB2LSB and enable the + * use of memory-mapped files and strip chopping when + * a file is opened read-only. + */ + tif->tif_flags = FILLORDER_MSB2LSB; + if (m == O_RDONLY) +#ifdef STRIPCHOP_DEFAULT + tif->tif_flags |= TIFF_MAPPED|STRIPCHOP_DEFAULT; +#else + tif->tif_flags |= TIFF_MAPPED; +#endif + + { union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; } + /* + * Process library-specific flags in the open mode string. + * The following flags may be used to control intrinsic library + * behaviour that may or may not be desirable (usually for + * compatibility with some application that claims to support + * TIFF but only supports some braindead idea of what the + * vendor thinks TIFF is): + * + * 'l' use little-endian byte order for creating a file + * 'b' use big-endian byte order for creating a file + * 'L' read/write information using LSB2MSB bit order + * 'B' read/write information using MSB2LSB bit order + * 'H' read/write information using host bit order + * 'M' enable use of memory-mapped files when supported + * 'm' disable use of memory-mapped files + * 'C' enable strip chopping support when reading + * 'c' disable strip chopping support + * + * The use of the 'l' and 'b' flags is strongly discouraged. + * These flags are provided solely because numerous vendors, + * typically on the PC, do not correctly support TIFF; they + * only support the Intel little-endian byte order. This + * support is not configured by default because it supports + * the violation of the TIFF spec that says that readers *MUST* + * support both byte orders. It is strongly recommended that + * you not use this feature except to deal with busted apps + * that write invalid TIFF. And even in those cases you should + * bang on the vendors to fix their software. + * + * The 'L', 'B', and 'H' flags are intended for applications + * that can optimize operations on data by using a particular + * bit order. By default the library returns data in MSB2LSB + * bit order for compatibiltiy with older versions of this + * library. Returning data in the bit order of the native cpu + * makes the most sense but also requires applications to check + * the value of the FillOrder tag; something they probabyl do + * not do right now. + * + * The 'M' and 'm' flags are provided because some virtual memory + * systems exhibit poor behaviour when large images are mapped. + * These options permit clients to control the use of memory-mapped + * files on a per-file basis. + * + * The 'C' and 'c' flags are provided because the library support + * for chopping up large strips into multiple smaller strips is not + * application-transparent and as such can cause problems. The 'c' + * option permits applications that only want to look at the tags, + * for example, to get the unadulterated TIFF tag information. + */ + for (cp = mode; *cp; cp++) + switch (*cp) { + case 'b': + if ((m&O_CREAT) && !bigendian) + tif->tif_flags |= TIFF_SWAB; + break; + case 'l': + if ((m&O_CREAT) && bigendian) + tif->tif_flags |= TIFF_SWAB; + break; + case 'B': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + FILLORDER_MSB2LSB; + break; + case 'L': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + FILLORDER_LSB2MSB; + break; + case 'H': + tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | + HOST_FILLORDER; + break; + case 'M': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + break; + case 'm': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_MAPPED; + break; + case 'C': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_STRIPCHOP; + break; + case 'c': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_STRIPCHOP; + break; + } + /* + * Read in TIFF header. + */ + if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { + if (tif->tif_mode == O_RDONLY) { + TIFFError(name, "Cannot read TIFF header"); + goto bad; + } + /* + * Setup header and write. + */ + tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB + ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN) + : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN); + tif->tif_header.tiff_version = TIFF_VERSION; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.tiff_version); + tif->tif_header.tiff_diroff = 0; /* filled in later */ + if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { + TIFFError(name, "Error writing TIFF header"); + goto bad; + } + /* + * Setup the byte order handling. + */ + TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian); + /* + * Setup default directory. + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + tif->tif_diroff = 0; + return (tif); + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN && + tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) { + TIFFError(name, "Not a TIFF file, bad magic number %d (0x%x)", + tif->tif_header.tiff_magic, + tif->tif_header.tiff_magic); + goto bad; + } + TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian); + /* + * Swap header if required. + */ + if (tif->tif_flags & TIFF_SWAB) { + TIFFSwabShort(&tif->tif_header.tiff_version); + TIFFSwabLong(&tif->tif_header.tiff_diroff); + } + /* + * Now check version (if needed, it's been byte-swapped). + * Note that this isn't actually a version number, it's a + * magic number that doesn't change (stupid). + */ + if (tif->tif_header.tiff_version != TIFF_VERSION) { + TIFFError(name, + "Not a TIFF file, bad version number %d (0x%x)", + tif->tif_header.tiff_version, + tif->tif_header.tiff_version); + goto bad; + } + tif->tif_flags |= TIFF_MYBUFFER; + tif->tif_rawcp = tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; + /* + * Setup initial directory. + */ + switch (mode[0]) { + case 'r': + tif->tif_nextdiroff = tif->tif_header.tiff_diroff; + /* + * Try to use a memory-mapped file if the client + * has not explicitly suppressed usage with the + * 'm' flag in the open mode (see above). + */ + if ((tif->tif_flags & TIFF_MAPPED) && + !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size)) + tif->tif_flags &= ~TIFF_MAPPED; + if (TIFFReadDirectory(tif)) { + tif->tif_rawcc = -1; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (tif); + } + break; + case 'a': + /* + * New directories are automatically append + * to the end of the directory chain when they + * are written out (see TIFFWriteDirectory). + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + return (tif); + } +bad: + tif->tif_mode = O_RDONLY; /* XXX avoid flush */ + TIFFClose(tif); + return ((TIFF*)0); +bad2: + (void) (*closeproc)(clientdata); + return ((TIFF*)0); +} + +/* + * Query functions to access private data. + */ + +/* + * Return open file's name. + */ +const char * +TIFFFileName(TIFF* tif) +{ + return (tif->tif_name); +} + +/* + * Return open file's I/O descriptor. + */ +int +TIFFFileno(TIFF* tif) +{ + return (tif->tif_fd); +} + +/* + * Return read/write mode. + */ +int +TIFFGetMode(TIFF* tif) +{ + return (tif->tif_mode); +} + +/* + * Return nonzero if file is organized in + * tiles; zero if organized as strips. + */ +int +TIFFIsTiled(TIFF* tif) +{ + return (isTiled(tif)); +} + +/* + * Return current row being read/written. + */ +uint32 +TIFFCurrentRow(TIFF* tif) +{ + return (tif->tif_row); +} + +/* + * Return index of the current directory. + */ +tdir_t +TIFFCurrentDirectory(TIFF* tif) +{ + return (tif->tif_curdir); +} + +/* + * Return current strip. + */ +tstrip_t +TIFFCurrentStrip(TIFF* tif) +{ + return (tif->tif_curstrip); +} + +/* + * Return current tile. + */ +ttile_t +TIFFCurrentTile(TIFF* tif) +{ + return (tif->tif_curtile); +} + +/* + * Return nonzero if the file has byte-swapped data. + */ +int +TIFFIsByteSwapped(TIFF* tif) +{ + return ((tif->tif_flags & TIFF_SWAB) != 0); +} + +/* + * Return nonzero if the data is returned up-sampled. + */ +int +TIFFIsUpSampled(TIFF* tif) +{ + return (isUpSampled(tif)); +} + +/* + * Return nonzero if the data is returned in MSB-to-LSB bit order. + */ +int +TIFFIsMSB2LSB(TIFF* tif) +{ + return (isFillOrder(tif, FILLORDER_MSB2LSB)); +} diff --git a/libtiff/tif_packbits.c b/libtiff/tif_packbits.c new file mode 100644 index 00000000..9447aba2 --- /dev/null +++ b/libtiff/tif_packbits.c @@ -0,0 +1,261 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_packbits.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef PACKBITS_SUPPORT +/* + * TIFF Library. + * + * PackBits Compression Algorithm Support + */ +#include +#include + +static int +PackBitsPreEncode(TIFF* tif, tsample_t s) +{ + (void) s; + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + tif->tif_data = (tidata_t) TIFFTileRowSize(tif); + else + tif->tif_data = (tidata_t) TIFFScanlineSize(tif); + return (1); +} + +/* + * NB: tidata is the type representing *(tidata_t); + * if tidata_t is made signed then this type must + * be adjusted accordingly. + */ +typedef unsigned char tidata; + +/* + * Encode a run of pixels. + */ +static int +PackBitsEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s) +{ + u_char* bp = (u_char*) buf; + tidata_t op, ep, lastliteral; + long n, slop; + int b; + enum { BASE, LITERAL, RUN, LITERAL_RUN } state; + + (void) s; + op = tif->tif_rawcp; + ep = tif->tif_rawdata + tif->tif_rawdatasize; + state = BASE; + lastliteral = 0; + while (cc > 0) { + /* + * Find the longest string of identical bytes. + */ + b = *bp++, cc--, n = 1; + for (; cc > 0 && b == *bp; cc--, bp++) + n++; + again: + if (op + 2 >= ep) { /* insure space for new data */ + /* + * Be careful about writing the last + * literal. Must write up to that point + * and then copy the remainder to the + * front of the buffer. + */ + if (state == LITERAL || state == LITERAL_RUN) { + slop = op - lastliteral; + tif->tif_rawcc += lastliteral - tif->tif_rawcp; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + while (slop-- > 0) + *op++ = *lastliteral++; + lastliteral = tif->tif_rawcp; + } else { + tif->tif_rawcc += op - tif->tif_rawcp; + if (!TIFFFlushData1(tif)) + return (-1); + op = tif->tif_rawcp; + } + } + switch (state) { + case BASE: /* initial state, set run/literal */ + if (n > 1) { + state = RUN; + if (n > 128) { + *op++ = (tidata) -127; + *op++ = b; + n -= 128; + goto again; + } + *op++ = (tidataval_t)(-(n-1)); + *op++ = b; + } else { + lastliteral = op; + *op++ = 0; + *op++ = b; + state = LITERAL; + } + break; + case LITERAL: /* last object was literal string */ + if (n > 1) { + state = LITERAL_RUN; + if (n > 128) { + *op++ = (tidata) -127; + *op++ = b; + n -= 128; + goto again; + } + *op++ = (tidataval_t)(-(n-1)); /* encode run */ + *op++ = b; + } else { /* extend literal */ + if (++(*lastliteral) == 127) + state = BASE; + *op++ = b; + } + break; + case RUN: /* last object was run */ + if (n > 1) { + if (n > 128) { + *op++ = (tidata) -127; + *op++ = b; + n -= 128; + goto again; + } + *op++ = (tidataval_t)(-(n-1)); + *op++ = b; + } else { + lastliteral = op; + *op++ = 0; + *op++ = b; + state = LITERAL; + } + break; + case LITERAL_RUN: /* literal followed by a run */ + /* + * Check to see if previous run should + * be converted to a literal, in which + * case we convert literal-run-literal + * to a single literal. + */ + if (n == 1 && op[-2] == (tidata) -1 && + *lastliteral < 126) { + state = (((*lastliteral) += 2) == 127 ? + BASE : LITERAL); + op[-2] = op[-1]; /* replicate */ + } else + state = RUN; + goto again; + } + } + tif->tif_rawcc += op - tif->tif_rawcp; + tif->tif_rawcp = op; + return (1); +} + +/* + * Encode a rectangular chunk of pixels. We break it up + * into row-sized pieces to insure that encoded runs do + * not span rows. Otherwise, there can be problems with + * the decoder if data is read, for example, by scanlines + * when it was encoded by strips. + */ +static int +PackBitsEncodeChunk(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + tsize_t rowsize = (tsize_t) tif->tif_data; + + assert(rowsize > 0); + while ((long)cc > 0) { + if (PackBitsEncode(tif, bp, rowsize, s) < 0) + return (-1); + bp += rowsize; + cc -= rowsize; + } + return (1); +} + +static int +PackBitsDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +{ + char *bp; + tsize_t cc; + long n; + int b; + + (void) s; + bp = (char*) tif->tif_rawcp; + cc = tif->tif_rawcc; + while (cc > 0 && (long)occ > 0) { + n = (long) *bp++, cc--; + /* + * Watch out for compilers that + * don't sign extend chars... + */ + if (n >= 128) + n -= 256; + if (n < 0) { /* replicate next byte -n+1 times */ + if (n == -128) /* nop */ + continue; + n = -n + 1; + occ -= n; + b = *bp++, cc--; + while (n-- > 0) + *op++ = b; + } else { /* copy next n+1 bytes literally */ + _TIFFmemcpy(op, bp, ++n); + op += n; occ -= n; + bp += n; cc -= n; + } + } + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + if (occ > 0) { + TIFFError(tif->tif_name, + "PackBitsDecode: Not enough data for scanline %ld", + (long) tif->tif_row); + return (0); + } + /* check for buffer overruns? */ + return (1); +} + +int +TIFFInitPackBits(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_decoderow = PackBitsDecode; + tif->tif_decodestrip = PackBitsDecode; + tif->tif_decodetile = PackBitsDecode; + tif->tif_preencode = PackBitsPreEncode; + tif->tif_encoderow = PackBitsEncode; + tif->tif_encodestrip = PackBitsEncodeChunk; + tif->tif_encodetile = PackBitsEncodeChunk; + return (1); +} +#endif /* PACKBITS_SUPPORT */ diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c new file mode 100644 index 00000000..27f2a9d7 --- /dev/null +++ b/libtiff/tif_pixarlog.c @@ -0,0 +1,1309 @@ +/* + * Copyright (c) 1996-1997 Sam Leffler + * Copyright (c) 1996 Pixar + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Pixar, Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef PIXARLOG_SUPPORT + +/* + * TIFF Library. + * PixarLog Compression Support + * + * Contributed by Dan McCoy. + * + * PixarLog film support uses the TIFF library to store companded + * 11 bit values into a tiff file, which are compressed using the + * zip compressor. + * + * The codec can take as input and produce as output 32-bit IEEE float values + * as well as 16-bit or 8-bit unsigned integer values. + * + * On writing any of the above are converted into the internal + * 11-bit log format. In the case of 8 and 16 bit values, the + * input is assumed to be unsigned linear color values that represent + * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to + * be the normal linear color range, in addition over 1 values are + * accepted up to a value of about 25.0 to encode "hot" hightlights and such. + * The encoding is lossless for 8-bit values, slightly lossy for the + * other bit depths. The actual color precision should be better + * than the human eye can perceive with extra room to allow for + * error introduced by further image computation. As with any quantized + * color format, it is possible to perform image calculations which + * expose the quantization error. This format should certainly be less + * susceptable to such errors than standard 8-bit encodings, but more + * susceptable than straight 16-bit or 32-bit encodings. + * + * On reading the internal format is converted to the desired output format. + * The program can request which format it desires by setting the internal + * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values: + * PIXARLOGDATAFMT_FLOAT = provide IEEE float values. + * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values + * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values + * + * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer + * values with the difference that if there are exactly three or four channels + * (rgb or rgba) it swaps the channel order (bgr or abgr). + * + * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly + * packed in 16-bit values. However no tools are supplied for interpreting + * these values. + * + * "hot" (over 1.0) areas written in floating point get clamped to + * 1.0 in the integer data types. + * + * When the file is closed after writing, the bit depth and sample format + * are set always to appear as if 8-bit data has been written into it. + * That way a naive program unaware of the particulars of the encoding + * gets the format it is most likely able to handle. + * + * The codec does it's own horizontal differencing step on the coded + * values so the libraries predictor stuff should be turned off. + * The codec also handle byte swapping the encoded values as necessary + * since the library does not have the information necessary + * to know the bit depth of the raw unencoded buffer. + * + */ + +#include "tif_predict.h" +#include "zlib.h" +#include "zutil.h" + +#include +#include +#include +#include + +/* Tables for converting to/from 11 bit coded values */ + +#define TSIZE 2048 /* decode table size (11-bit tokens) */ +#define TSIZEP1 2049 /* Plus one for slop */ +#define ONE 1250 /* token value of 1.0 exactly */ +#define RATIO 1.004 /* nominal ratio for log part */ + +#define CODE_MASK 0x7ff /* 11 bits. */ + +static float Fltsize; +static float LogK1, LogK2; + +#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); } + +static void +horizontalAccumulateF(uint16 *wp, int n, int stride, float *op, + float *ToLinearF) +{ + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + t0 = ToLinearF[cr = wp[0]]; + t1 = ToLinearF[cg = wp[1]]; + t2 = ToLinearF[cb = wp[2]]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + } + } else if (stride == 4) { + t0 = ToLinearF[cr = wp[0]]; + t1 = ToLinearF[cg = wp[1]]; + t2 = ToLinearF[cb = wp[2]]; + t3 = ToLinearF[ca = wp[3]]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + t3 = ToLinearF[(ca += wp[3]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } else { + REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + +static void +horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op, + float *ToLinearF) +{ + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; + +#define SCALE12 2048.0 +#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071) + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + t0 = ToLinearF[cr = wp[0]] * SCALE12; + t1 = ToLinearF[cg = wp[1]] * SCALE12; + t2 = ToLinearF[cb = wp[2]] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + } + } else if (stride == 4) { + t0 = ToLinearF[cr = wp[0]] * SCALE12; + t1 = ToLinearF[cg = wp[1]] * SCALE12; + t2 = ToLinearF[cb = wp[2]] * SCALE12; + t3 = ToLinearF[ca = wp[3]] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + } + } else { + REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + } + } + } +} + +static void +horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op, + uint16 *ToLinear16) +{ + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = ToLinear16[cr = wp[0]]; + op[1] = ToLinear16[cg = wp[1]]; + op[2] = ToLinear16[cb = wp[2]]; + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + } + } else if (stride == 4) { + op[0] = ToLinear16[cr = wp[0]]; + op[1] = ToLinear16[cg = wp[1]]; + op[2] = ToLinear16[cb = wp[2]]; + op[3] = ToLinear16[ca = wp[3]]; + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + op[3] = ToLinear16[(ca += wp[3]) & mask]; + } + } else { + REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + +/* + * Returns the log encoded 11-bit values with the horizontal + * differencing undone. + */ +static void +horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op) +{ + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = cr = wp[0]; op[1] = cg = wp[1]; op[2] = cb = wp[2]; + n -= 3; + while (n > 0) { + wp += 3; + op += 3; + n -= 3; + op[0] = (cr += wp[0]) & mask; + op[1] = (cg += wp[1]) & mask; + op[2] = (cb += wp[2]) & mask; + } + } else if (stride == 4) { + op[0] = cr = wp[0]; op[1] = cg = wp[1]; + op[2] = cb = wp[2]; op[3] = ca = wp[3]; + n -= 4; + while (n > 0) { + wp += 4; + op += 4; + n -= 4; + op[0] = (cr += wp[0]) & mask; + op[1] = (cg += wp[1]) & mask; + op[2] = (cb += wp[2]) & mask; + op[3] = (ca += wp[3]) & mask; + } + } else { + REPEAT(stride, *op = *wp&mask; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = *wp&mask; wp++; op++) + n -= stride; + } + } + } +} + +static void +horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op, + unsigned char *ToLinear8) +{ + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = ToLinear8[cr = wp[0]]; + op[1] = ToLinear8[cg = wp[1]]; + op[2] = ToLinear8[cb = wp[2]]; + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + op += 3; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + } + } else if (stride == 4) { + op[0] = ToLinear8[cr = wp[0]]; + op[1] = ToLinear8[cg = wp[1]]; + op[2] = ToLinear8[cb = wp[2]]; + op[3] = ToLinear8[ca = wp[3]]; + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + op += 4; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + op[3] = ToLinear8[(ca += wp[3]) & mask]; + } + } else { + REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + + +static void +horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op, + unsigned char *ToLinear8) +{ + register unsigned int cr, cg, cb, ca, mask; + register unsigned char t0, t1, t2, t3; + + if (n >= stride) { + mask = CODE_MASK; + if (stride == 3) { + op[0] = 0; + t1 = ToLinear8[cb = wp[2]]; + t2 = ToLinear8[cg = wp[1]]; + t3 = ToLinear8[cr = wp[0]]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + op += 4; + op[0] = 0; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } else if (stride == 4) { + t0 = ToLinear8[ca = wp[3]]; + t1 = ToLinear8[cb = wp[2]]; + t2 = ToLinear8[cg = wp[1]]; + t3 = ToLinear8[cr = wp[0]]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + op += 4; + t0 = ToLinear8[(ca += wp[3]) & mask]; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } else { + REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + while (n > 0) { + REPEAT(stride, + wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) + n -= stride; + } + } + } +} + +/* + * State block for each open TIFF + * file using PixarLog compression/decompression. + */ +typedef struct { + TIFFPredictorState predict; + z_stream stream; + uint16 *tbuf; + uint16 stride; + int state; + int user_datafmt; + int quality; +#define PLSTATE_INIT 1 + + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + + float *ToLinearF; + uint16 *ToLinear16; + unsigned char *ToLinear8; + uint16 *FromLT2; + uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16 *From8; + +} PixarLogState; + +static int +PixarLogMakeTables(PixarLogState *sp) +{ + +/* + * We make several tables here to convert between various external + * representations (float, 16-bit, and 8-bit) and the internal + * 11-bit companded representation. The 11-bit representation has two + * distinct regions. A linear bottom end up through .018316 in steps + * of about .000073, and a region of constant ratio up to about 25. + * These floating point numbers are stored in the main table ToLinearF. + * All other tables are derived from this one. The tables (and the + * ratios) are continuous at the internal seam. + */ + + int nlin, lt2size; + int i, j; + double b, c, linstep, max; + double k, v, dv, r, lr2, r2; + float *ToLinearF; + uint16 *ToLinear16; + unsigned char *ToLinear8; + uint16 *FromLT2; + uint16 *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16 *From8; + + c = log(RATIO); + nlin = 1./c; /* nlin must be an integer */ + c = 1./nlin; + b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ + linstep = b*c*exp(1.); + + LogK1 = 1./c; /* if (v >= 2) token = k1*log(v*k2) */ + LogK2 = 1./b; + lt2size = (2./linstep)+1; + FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16)); + From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16)); + From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16)); + ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float)); + ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16)); + ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char)); + if (FromLT2 == NULL || From14 == NULL || From8 == NULL || + ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) { + if (FromLT2) _TIFFfree(FromLT2); + if (From14) _TIFFfree(From14); + if (From8) _TIFFfree(From8); + if (ToLinearF) _TIFFfree(ToLinearF); + if (ToLinear16) _TIFFfree(ToLinear16); + if (ToLinear8) _TIFFfree(ToLinear8); + sp->FromLT2 = NULL; + sp->From14 = NULL; + sp->From8 = NULL; + sp->ToLinearF = NULL; + sp->ToLinear16 = NULL; + sp->ToLinear8 = NULL; + return 0; + } + + j = 0; + + for (i = 0; i < nlin; i++) { + v = i * linstep; + ToLinearF[j++] = v; + } + + for (i = nlin; i < TSIZE; i++) + ToLinearF[j++] = b*exp(c*i); + + ToLinearF[2048] = ToLinearF[2047]; + + for (i = 0; i < TSIZEP1; i++) { + v = ToLinearF[i]*65535.0 + 0.5; + ToLinear16[i] = (v > 65535.0) ? 65535 : v; + v = ToLinearF[i]*255.0 + 0.5; + ToLinear8[i] = (v > 255.0) ? 255 : v; + } + + j = 0; + for (i = 0; i < lt2size; i++) { + if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1]) + j++; + FromLT2[i] = j; + } + + /* + * Since we lose info anyway on 16-bit data, we set up a 14-bit + * table and shift 16-bit values down two bits on input. + * saves a little table space. + */ + j = 0; + for (i = 0; i < 16384; i++) { + while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1]) + j++; + From14[i] = j; + } + + j = 0; + for (i = 0; i < 256; i++) { + while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1]) + j++; + From8[i] = j; + } + + Fltsize = lt2size/2; + + sp->ToLinearF = ToLinearF; + sp->ToLinear16 = ToLinear16; + sp->ToLinear8 = ToLinear8; + sp->FromLT2 = FromLT2; + sp->From14 = From14; + sp->From8 = From8; + + return 1; +} + +#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) +#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) + +static int PixarLogEncode(TIFF*, tidata_t, tsize_t, tsample_t); +static int PixarLogDecode(TIFF*, tidata_t, tsize_t, tsample_t); + +#define N(a) (sizeof(a)/sizeof(a[0])) +#define PIXARLOGDATAFMT_UNKNOWN -1 + +static int +PixarLogGuessDataFmt(TIFFDirectory *td) +{ + int guess = PIXARLOGDATAFMT_UNKNOWN; + int format = td->td_sampleformat; + + /* If the user didn't tell us his datafmt, + * take our best guess from the bitspersample. + */ + switch (td->td_bitspersample) { + case 32: + if (format == SAMPLEFORMAT_IEEEFP) + guess = PIXARLOGDATAFMT_FLOAT; + break; + case 16: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_16BIT; + break; + case 12: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) + guess = PIXARLOGDATAFMT_12BITPICIO; + break; + case 11: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_11BITLOG; + break; + case 8: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_8BIT; + break; + } + + return guess; +} + +static int +PixarLogSetupDecode(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = DecoderState(tif); + static const char module[] = "PixarLogSetupDecode"; + + assert(sp != NULL); + + /* Make sure no byte swapping happens on the data + * after decompression. */ + tif->tif_postdecode = _TIFFNoPostDecode; + + /* for some reason, we can't do this in TIFFInitPixarLog */ + + sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1); + sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride * + td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16)); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { + TIFFError(module, + "PixarLog compression can't handle bits depth/data format combination (depth: %d)", + td->td_bitspersample); + return (0); + } + + if (inflateInit(&sp->stream) != Z_OK) { + TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); + return (0); + } else { + sp->state |= PLSTATE_INIT; + return (1); + } +} + +/* + * Setup state for decoding a strip. + */ +static int +PixarLogPreDecode(TIFF* tif, tsample_t s) +{ + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + sp->stream.next_in = tif->tif_rawdata; + sp->stream.avail_in = tif->tif_rawcc; + return (inflateReset(&sp->stream) == Z_OK); +} + +static int +PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +{ + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = DecoderState(tif); + static const char module[] = "PixarLogDecode"; + int i, nsamples, llen; + uint16 *up; + + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + nsamples = occ / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + nsamples = occ; + break; + default: + TIFFError(tif->tif_name, + "%d bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; + + (void) s; + assert(sp != NULL); + sp->stream.next_out = (unsigned char *) sp->tbuf; + sp->stream.avail_out = nsamples * sizeof(uint16); + do { + int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + if (state == Z_STREAM_END) { + break; /* XXX */ + } + if (state == Z_DATA_ERROR) { + TIFFError(module, + "%s: Decoding error at scanline %d, %s", + tif->tif_name, tif->tif_row, sp->stream.msg); + if (inflateSync(&sp->stream) != Z_OK) + return (0); + continue; + } + if (state != Z_OK) { + TIFFError(module, "%s: zlib error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + } while (sp->stream.avail_out > 0); + + /* hopefully, we got all the bytes we needed */ + if (sp->stream.avail_out != 0) { + TIFFError(module, + "%s: Not enough data at scanline %d (short %d bytes)", + tif->tif_name, tif->tif_row, sp->stream.avail_out); + return (0); + } + + up = sp->tbuf; + /* Swap bytes in the data if from a different endian machine. */ + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(up, nsamples); + + for (i = 0; i < nsamples; i += llen, up += llen) { + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + horizontalAccumulateF(up, llen, sp->stride, + (float *)op, sp->ToLinearF); + op += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalAccumulate16(up, llen, sp->stride, + (uint16 *)op, sp->ToLinear16); + op += llen * sizeof(uint16); + break; + case PIXARLOGDATAFMT_12BITPICIO: + horizontalAccumulate12(up, llen, sp->stride, + (int16 *)op, sp->ToLinearF); + op += llen * sizeof(int16); + break; + case PIXARLOGDATAFMT_11BITLOG: + horizontalAccumulate11(up, llen, sp->stride, + (uint16 *)op); + op += llen * sizeof(uint16); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalAccumulate8(up, llen, sp->stride, + (unsigned char *)op, sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + case PIXARLOGDATAFMT_8BITABGR: + horizontalAccumulate8abgr(up, llen, sp->stride, + (unsigned char *)op, sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + default: + TIFFError(tif->tif_name, + "PixarLogDecode: unsupported bits/sample: %d", + td->td_bitspersample); + return (0); + } + } + + return (1); +} + +static int +PixarLogSetupEncode(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + PixarLogState* sp = EncoderState(tif); + static const char module[] = "PixarLogSetupEncode"; + + assert(sp != NULL); + + /* for some reason, we can't do this in TIFFInitPixarLog */ + + sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1); + sp->tbuf = (uint16 *) _TIFFmalloc(sp->stride * + td->td_imagewidth * td->td_rowsperstrip * sizeof(uint16)); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { + TIFFError(module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample); + return (0); + } + + if (deflateInit(&sp->stream, sp->quality) != Z_OK) { + TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); + return (0); + } else { + sp->state |= PLSTATE_INIT; + return (1); + } +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +PixarLogPreEncode(TIFF* tif, tsample_t s) +{ + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = tif->tif_rawdatasize; + return (deflateReset(&sp->stream) == Z_OK); +} + +static void +horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2) +{ + + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + register float fltsize = Fltsize; + +#define CLAMP(v) ( (v<(float)0.) ? 0 \ + : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \ + : (v>(float)24.2) ? 2047 \ + : LogK1*log(v*LogK2) + 0.5 ) + + mask = CODE_MASK; + if (n >= stride) { + if (stride == 3) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + ip += 3; + r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + } + } else if (stride == 4) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + ip += 4; + r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1; + } + } else { + ip += n - 1; /* point to last one */ + wp += n - 1; /* point to last one */ + n -= stride; + while (n > 0) { + REPEAT(stride, wp[0] = CLAMP(ip[0]); + wp[stride] -= wp[0]; + wp[stride] &= mask; + wp--; ip--) + n -= stride; + } + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) + } + } +} + +static void +horizontalDifference16(unsigned short *ip, int n, int stride, + unsigned short *wp, uint16 *From14) +{ + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + +/* assumption is unsigned pixel values */ +#undef CLAMP +#define CLAMP(v) From14[(v) >> 2] + + mask = CODE_MASK; + if (n >= stride) { + if (stride == 3) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) { + n -= 3; + wp += 3; + ip += 3; + r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + } + } else if (stride == 4) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) { + n -= 4; + wp += 4; + ip += 4; + r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1; + a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1; + } + } else { + ip += n - 1; /* point to last one */ + wp += n - 1; /* point to last one */ + n -= stride; + while (n > 0) { + REPEAT(stride, wp[0] = CLAMP(ip[0]); + wp[stride] -= wp[0]; + wp[stride] &= mask; + wp--; ip--) + n -= stride; + } + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) + } + } +} + + +static void +horizontalDifference8(unsigned char *ip, int n, int stride, + unsigned short *wp, uint16 *From8) +{ + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + +#undef CLAMP +#define CLAMP(v) (From8[(v)]) + + mask = CODE_MASK; + if (n >= stride) { + if (stride == 3) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) { + n -= 3; + r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1; + wp += 3; + ip += 3; + } + } else if (stride == 4) { + r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) { + n -= 4; + r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1; + g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1; + b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1; + a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1; + wp += 4; + ip += 4; + } + } else { + wp += n + stride - 1; /* point to last one */ + ip += n + stride - 1; /* point to last one */ + n -= stride; + while (n > 0) { + REPEAT(stride, wp[0] = CLAMP(ip[0]); + wp[stride] -= wp[0]; + wp[stride] &= mask; + wp--; ip--) + n -= stride; + } + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--) + } + } +} + +/* + * Encode a chunk of pixels. + */ +static int +PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + static const char module[] = "PixarLogEncode"; + int i, n, llen; + unsigned short * up; + + (void) s; + + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + n = cc / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + n = cc; + break; + default: + TIFFError(tif->tif_name, + "%d bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; + + for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_FLOAT: + horizontalDifferenceF((float *)bp, llen, + sp->stride, up, sp->FromLT2); + bp += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalDifference16((uint16 *)bp, llen, + sp->stride, up, sp->From14); + bp += llen * sizeof(uint16); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalDifference8((unsigned char *)bp, llen, + sp->stride, up, sp->From8); + bp += llen * sizeof(unsigned char); + break; + default: + TIFFError(tif->tif_name, + "%d bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + } + + sp->stream.next_in = (unsigned char *) sp->tbuf; + sp->stream.avail_in = n * sizeof(uint16); + + do { + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { + TIFFError(module, "%s: Encoder error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + if (sp->stream.avail_out == 0) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = tif->tif_rawdatasize; + } + } while (sp->stream.avail_in > 0); + return (1); +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ + +static int +PixarLogPostEncode(TIFF* tif) +{ + PixarLogState *sp = EncoderState(tif); + static const char module[] = "PixarLogPostEncode"; + int state; + + sp->stream.avail_in = 0; + + do { + state = deflate(&sp->stream, Z_FINISH); + switch (state) { + case Z_STREAM_END: + case Z_OK: + if (sp->stream.avail_out != tif->tif_rawdatasize) { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = tif->tif_rawdatasize; + } + break; + default: + TIFFError(module, "%s: zlib error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + } while (state != Z_STREAM_END); + return (1); +} + +static void +PixarLogClose(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + + /* In a really sneaky maneuver, on close, we covertly modify both + * bitspersample and sampleformat in the directory to indicate + * 8-bit linear. This way, the decode "just works" even for + * readers that don't know about PixarLog, or how to set + * the PIXARLOGDATFMT pseudo-tag. + */ + td->td_bitspersample = 8; + td->td_sampleformat = SAMPLEFORMAT_UINT; +} + +static void +PixarLogCleanup(TIFF* tif) +{ + PixarLogState* sp = (PixarLogState*) tif->tif_data; + + if (sp) { + if (sp->FromLT2) _TIFFfree(sp->FromLT2); + if (sp->From14) _TIFFfree(sp->From14); + if (sp->From8) _TIFFfree(sp->From8); + if (sp->ToLinearF) _TIFFfree(sp->ToLinearF); + if (sp->ToLinear16) _TIFFfree(sp->ToLinear16); + if (sp->ToLinear8) _TIFFfree(sp->ToLinear8); + if (sp->state&PLSTATE_INIT) { + if (tif->tif_mode == O_RDONLY) + inflateEnd(&sp->stream); + else + deflateEnd(&sp->stream); + } + if (sp->tbuf) + _TIFFfree(sp->tbuf); + _TIFFfree(sp); + tif->tif_data = NULL; + } +} + +static int +PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + PixarLogState *sp = (PixarLogState *)tif->tif_data; + int result; + static const char module[] = "PixarLogVSetField"; + + switch (tag) { + case TIFFTAG_PIXARLOGQUALITY: + sp->quality = va_arg(ap, int); + if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { + if (deflateParams(&sp->stream, + sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { + TIFFError(module, "%s: zlib error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + } + return (1); + case TIFFTAG_PIXARLOGDATAFMT: + sp->user_datafmt = va_arg(ap, int); + /* Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) { + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_11BITLOG: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_12BITPICIO: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); + break; + case PIXARLOGDATAFMT_16BIT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_FLOAT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); + break; + } + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = TIFFTileSize(tif); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + result = 1; /* NB: pseudo tag */ + break; + default: + result = (*sp->vsetparent)(tif, tag, ap); + } + return (result); +} + +static int +PixarLogVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + PixarLogState *sp = (PixarLogState *)tif->tif_data; + + switch (tag) { + case TIFFTAG_PIXARLOGQUALITY: + *va_arg(ap, int*) = sp->quality; + break; + case TIFFTAG_PIXARLOGDATAFMT: + *va_arg(ap, int*) = sp->user_datafmt; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static const TIFFFieldInfo pixarlogFieldInfo[] = { + {TIFFTAG_PIXARLOGDATAFMT,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""}, + {TIFFTAG_PIXARLOGQUALITY,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""} +}; + +int +TIFFInitPixarLog(TIFF* tif, int scheme) +{ + PixarLogState* sp; + + assert(scheme == COMPRESSION_PIXARLOG); + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (PixarLogState)); + if (tif->tif_data == NULL) + goto bad; + sp = (PixarLogState*) tif->tif_data; + memset(sp, 0, sizeof (*sp)); + sp->stream.data_type = Z_BINARY; + sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; + + /* + * Install codec methods. + */ + tif->tif_setupdecode = PixarLogSetupDecode; + tif->tif_predecode = PixarLogPreDecode; + tif->tif_decoderow = PixarLogDecode; + tif->tif_decodestrip = PixarLogDecode; + tif->tif_decodetile = PixarLogDecode; + tif->tif_setupencode = PixarLogSetupEncode; + tif->tif_preencode = PixarLogPreEncode; + tif->tif_postencode = PixarLogPostEncode; + tif->tif_encoderow = PixarLogEncode; + tif->tif_encodestrip = PixarLogEncode; + tif->tif_encodetile = PixarLogEncode; + tif->tif_close = PixarLogClose; + tif->tif_cleanup = PixarLogCleanup; + + /* Override SetField so we can handle our private pseudo-tag */ + _TIFFMergeFieldInfo(tif, pixarlogFieldInfo, N(pixarlogFieldInfo)); + sp->vgetparent = tif->tif_vgetfield; + tif->tif_vgetfield = PixarLogVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_vsetfield; + tif->tif_vsetfield = PixarLogVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; + + /* we don't wish to use the predictor, + * the default is none, which predictor value 1 + */ + (void) TIFFPredictorInit(tif); + + /* + * build the companding tables + */ + PixarLogMakeTables(sp); + + return (1); +bad: + TIFFError("TIFFInitPixarLog", "No space for PixarLog state block"); + return (0); +} +#endif /* PIXARLOG_SUPPORT */ diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c new file mode 100644 index 00000000..ec96a24d --- /dev/null +++ b/libtiff/tif_predict.c @@ -0,0 +1,461 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_predict.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Predictor Tag Support (used by multiple codecs). + */ +#include "tiffiop.h" +#include "tif_predict.h" + +#include + +#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) + +static void horAcc8(TIFF*, tidata_t, tsize_t); +static void horAcc16(TIFF*, tidata_t, tsize_t); +static void swabHorAcc16(TIFF*, tidata_t, tsize_t); +static void horDiff8(TIFF*, tidata_t, tsize_t); +static void horDiff16(TIFF*, tidata_t, tsize_t); +static int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t); +static int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t); +static int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t); +static int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t); + +static int +PredictorSetup(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + TIFFDirectory* td = &tif->tif_dir; + + if (sp->predictor == 1) /* no differencing */ + return (1); + if (sp->predictor != 2) { + TIFFError(tif->tif_name, "\"Predictor\" value %d not supported", + sp->predictor); + return (0); + } + if (td->td_bitspersample != 8 && td->td_bitspersample != 16) { + TIFFError(tif->tif_name, + "Horizontal differencing \"Predictor\" not supported with %d-bit samples", + td->td_bitspersample); + return (0); + } + sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? + td->td_samplesperpixel : 1); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + sp->rowsize = TIFFTileRowSize(tif); + else + sp->rowsize = TIFFScanlineSize(tif); + return (1); +} + +static int +PredictorSetupDecode(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + TIFFDirectory* td = &tif->tif_dir; + + if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) + return (0); + if (sp->predictor == 2) { + switch (td->td_bitspersample) { + case 8: sp->pfunc = horAcc8; break; + case 16: sp->pfunc = horAcc16; break; + } + /* + * Override default decoding method with + * one that does the predictor stuff. + */ + sp->coderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->codestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->codetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; + /* + * If the data is horizontally differenced + * 16-bit data that requires byte-swapping, + * then it must be byte swapped before the + * accumulation step. We do this with a + * special-purpose routine and override the + * normal post decoding logic that the library + * setup when the directory was read. + */ + if (tif->tif_flags&TIFF_SWAB) { + if (sp->pfunc == horAcc16) { + sp->pfunc = swabHorAcc16; + tif->tif_postdecode = _TIFFNoPostDecode; + } /* else handle 32-bit case... */ + } + } + return (1); +} + +static int +PredictorSetupEncode(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + TIFFDirectory* td = &tif->tif_dir; + + if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) + return (0); + if (sp->predictor == 2) { + switch (td->td_bitspersample) { + case 8: sp->pfunc = horDiff8; break; + case 16: sp->pfunc = horDiff16; break; + } + /* + * Override default encoding method with + * one that does the predictor stuff. + */ + sp->coderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->codestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->codetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + return (1); +} + +#define REPEAT4(n, op) \ + switch (n) { \ + default: { int i; for (i = n-4; i > 0; i--) { op; } } \ + case 4: op; \ + case 3: op; \ + case 2: op; \ + case 1: op; \ + case 0: ; \ + } + +static void +horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + u_int stride = sp->stride; + + char* cp = (char*) cp0; + if (cc > stride) { + cc -= stride; + /* + * Pipeline the most common cases. + */ + if (stride == 3) { + u_int cr = cp[0]; + u_int cg = cp[1]; + u_int cb = cp[2]; + do { + cc -= 3, cp += 3; + cp[0] = (cr += cp[0]); + cp[1] = (cg += cp[1]); + cp[2] = (cb += cp[2]); + } while ((int32) cc > 0); + } else if (stride == 4) { + u_int cr = cp[0]; + u_int cg = cp[1]; + u_int cb = cp[2]; + u_int ca = cp[3]; + do { + cc -= 4, cp += 4; + cp[0] = (cr += cp[0]); + cp[1] = (cg += cp[1]); + cp[2] = (cb += cp[2]); + cp[3] = (ca += cp[3]); + } while ((int32) cc > 0); + } else { + do { + REPEAT4(stride, cp[stride] += *cp; cp++) + cc -= stride; + } while ((int32) cc > 0); + } + } +} + +static void +swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + u_int stride = sp->stride; + uint16* wp = (uint16*) cp0; + tsize_t wc = cc / 2; + + if (wc > stride) { + TIFFSwabArrayOfShort(wp, wc); + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while ((int32) wc > 0); + } +} + +static void +horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc) +{ + u_int stride = PredictorState(tif)->stride; + uint16* wp = (uint16*) cp0; + tsize_t wc = cc / 2; + + if (wc > stride) { + wc -= stride; + do { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while ((int32) wc > 0); + } +} + +/* + * Decode a scanline and apply the predictor routine. + */ +static int +PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->coderow != NULL); + assert(sp->pfunc != NULL); + if ((*sp->coderow)(tif, op0, occ0, s)) { + (*sp->pfunc)(tif, op0, occ0); + return (1); + } else + return (0); +} + +/* + * Decode a tile/strip and apply the predictor routine. + * Note that horizontal differencing must be done on a + * row-by-row basis. The width of a "row" has already + * been calculated at pre-decode time according to the + * strip/tile dimensions. + */ +static int +PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->codetile != NULL); + if ((*sp->codetile)(tif, op0, occ0, s)) { + tsize_t rowsize = sp->rowsize; + assert(rowsize > 0); + assert(sp->pfunc != NULL); + while ((long)occ0 > 0) { + (*sp->pfunc)(tif, op0, (tsize_t) rowsize); + occ0 -= rowsize; + op0 += rowsize; + } + return (1); + } else + return (0); +} + +static void +horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + u_int stride = sp->stride; + char* cp = (char*) cp0; + + if (cc > stride) { + cc -= stride; + /* + * Pipeline the most common cases. + */ + if (stride == 3) { + int r1, g1, b1; + int r2 = cp[0]; + int g2 = cp[1]; + int b2 = cp[2]; + do { + r1 = cp[3]; cp[3] = r1-r2; r2 = r1; + g1 = cp[4]; cp[4] = g1-g2; g2 = g1; + b1 = cp[5]; cp[5] = b1-b2; b2 = b1; + cp += 3; + } while ((int32)(cc -= 3) > 0); + } else if (stride == 4) { + int r1, g1, b1, a1; + int r2 = cp[0]; + int g2 = cp[1]; + int b2 = cp[2]; + int a2 = cp[3]; + do { + r1 = cp[4]; cp[4] = r1-r2; r2 = r1; + g1 = cp[5]; cp[5] = g1-g2; g2 = g1; + b1 = cp[6]; cp[6] = b1-b2; b2 = b1; + a1 = cp[7]; cp[7] = a1-a2; a2 = a1; + cp += 4; + } while ((int32)(cc -= 4) > 0); + } else { + cp += cc - 1; + do { + REPEAT4(stride, cp[stride] -= cp[0]; cp--) + } while ((int32)(cc -= stride) > 0); + } + } +} + +static void +horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc) +{ + TIFFPredictorState* sp = PredictorState(tif); + u_int stride = sp->stride; + int16 *wp = (int16*) cp0; + tsize_t wc = cc/2; + + if (wc > stride) { + wc -= stride; + wp += wc - 1; + do { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while ((int32) wc > 0); + } +} + +static int +PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->pfunc != NULL); + assert(sp->coderow != NULL); +/* XXX horizontal differencing alters user's data XXX */ + (*sp->pfunc)(tif, bp, cc); + return ((*sp->coderow)(tif, bp, cc, s)); +} + +static int +PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s) +{ + TIFFPredictorState *sp = PredictorState(tif); + tsize_t cc = cc0, rowsize; + u_char* bp = bp0; + + assert(sp != NULL); + assert(sp->pfunc != NULL); + assert(sp->codetile != NULL); + rowsize = sp->rowsize; + assert(rowsize > 0); + while ((long)cc > 0) { + (*sp->pfunc)(tif, bp, (tsize_t) rowsize); + cc -= rowsize; + bp += rowsize; + } + return ((*sp->codetile)(tif, bp0, cc0, s)); +} + +#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ + +static const TIFFFieldInfo predictFieldInfo[] = { + { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, FIELD_PREDICTOR, + FALSE, FALSE, "Predictor" }, +}; +#define N(a) (sizeof (a) / sizeof (a[0])) + +static int +PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + TIFFPredictorState *sp = PredictorState(tif); + + switch (tag) { + case TIFFTAG_PREDICTOR: + sp->predictor = (uint16) va_arg(ap, int); + TIFFSetFieldBit(tif, FIELD_PREDICTOR); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); +} + +static int +PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + TIFFPredictorState *sp = PredictorState(tif); + + switch (tag) { + case TIFFTAG_PREDICTOR: + *va_arg(ap, uint16*) = sp->predictor; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static void +PredictorPrintDir(TIFF* tif, FILE* fd, long flags) +{ + TIFFPredictorState* sp = PredictorState(tif); + + (void) flags; + if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { + fprintf(fd, " Predictor: "); + switch (sp->predictor) { + case 1: fprintf(fd, "none "); break; + case 2: fprintf(fd, "horizontal differencing "); break; + } + fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); + } + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); +} + +int +TIFFPredictorInit(TIFF* tif) +{ + TIFFPredictorState* sp = PredictorState(tif); + + /* + * Merge codec-specific tag information and + * override parent get/set field methods. + */ + _TIFFMergeFieldInfo(tif, predictFieldInfo, N(predictFieldInfo)); + sp->vgetparent = tif->tif_vgetfield; + tif->tif_vgetfield = PredictorVGetField;/* hook for predictor tag */ + sp->vsetparent = tif->tif_vsetfield; + tif->tif_vsetfield = PredictorVSetField;/* hook for predictor tag */ + sp->printdir = tif->tif_printdir; + tif->tif_printdir = PredictorPrintDir; /* hook for predictor tag */ + + sp->setupdecode = tif->tif_setupdecode; + tif->tif_setupdecode = PredictorSetupDecode; + sp->setupencode = tif->tif_setupencode; + tif->tif_setupencode = PredictorSetupEncode; + + sp->predictor = 1; /* default value */ + sp->pfunc = NULL; /* no predictor routine */ + return (1); +} diff --git a/libtiff/tif_predict.h b/libtiff/tif_predict.h new file mode 100644 index 00000000..c4789bc4 --- /dev/null +++ b/libtiff/tif_predict.h @@ -0,0 +1,61 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_predict.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1995-1997 Sam Leffler + * Copyright (c) 1995-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFPREDICT_ +#define _TIFFPREDICT_ +/* + * ``Library-private'' Support for the Predictor Tag + */ + +/* + * Codecs that want to support the Predictor tag must place + * this structure first in their private state block so that + * the predictor code can cast tif_data to find its state. + */ +typedef struct { + int predictor; /* predictor tag value */ + int stride; /* sample stride over data */ + tsize_t rowsize; /* tile/strip row size */ + + TIFFPostMethod pfunc; /* horizontal differencer/accumulator */ + TIFFCodeMethod coderow; /* parent codec encode/decode row */ + TIFFCodeMethod codestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod codetile; /* parent codec encode/decode tile */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFBoolMethod setupdecode; /* super-class method */ + TIFFBoolMethod setupencode; /* super-class method */ +} TIFFPredictorState; + +#if defined(__cplusplus) +extern "C" { +#endif +extern int TIFFPredictorInit(TIFF*); +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFPREDICT_ */ diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c new file mode 100644 index 00000000..48d3a10f --- /dev/null +++ b/libtiff/tif_print.c @@ -0,0 +1,483 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_print.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Directory Printing Support + */ +#include "tiffiop.h" +#include + +#include + +static const char *photoNames[] = { + "min-is-white", /* PHOTOMETRIC_MINISWHITE */ + "min-is-black", /* PHOTOMETRIC_MINISBLACK */ + "RGB color", /* PHOTOMETRIC_RGB */ + "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ + "transparency mask", /* PHOTOMETRIC_MASK */ + "separated", /* PHOTOMETRIC_SEPARATED */ + "YCbCr", /* PHOTOMETRIC_YCBCR */ + "7 (0x7)", + "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ +}; +#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0])) + +static const char *orientNames[] = { + "0 (0x0)", + "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ + "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ + "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ + "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ + "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ + "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ + "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ + "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ +}; +#define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0])) + +/* + * Print the contents of the current directory + * to the specified stdio file stream. + */ +void +TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) +{ + register TIFFDirectory *td; + char *sep; + uint16 i; + long l, n; + + fprintf(fd, "TIFF Directory at offset 0x%lx\n", (long) tif->tif_diroff); + td = &tif->tif_dir; + if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) { + fprintf(fd, " Subfile Type:"); + sep = " "; + if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) { + fprintf(fd, "%sreduced-resolution image", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_PAGE) { + fprintf(fd, "%smulti-page document", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_MASK) + fprintf(fd, "%stransparency mask", sep); + fprintf(fd, " (%lu = 0x%lx)\n", + (long) td->td_subfiletype, (long) td->td_subfiletype); + } + if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) { + fprintf(fd, " Image Width: %lu Image Length: %lu", + (u_long) td->td_imagewidth, (u_long) td->td_imagelength); + if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) + fprintf(fd, " Image Depth: %lu", + (u_long) td->td_imagedepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) { + fprintf(fd, " Tile Width: %lu Tile Length: %lu", + (u_long) td->td_tilewidth, (u_long) td->td_tilelength); + if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) + fprintf(fd, " Tile Depth: %lu", + (u_long) td->td_tiledepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_RESOLUTION)) { + fprintf(fd, " Resolution: %g, %g", + td->td_xresolution, td->td_yresolution); + if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) { + switch (td->td_resolutionunit) { + case RESUNIT_NONE: + fprintf(fd, " (unitless)"); + break; + case RESUNIT_INCH: + fprintf(fd, " pixels/inch"); + break; + case RESUNIT_CENTIMETER: + fprintf(fd, " pixels/cm"); + break; + default: + fprintf(fd, " (unit %u = 0x%x)", + td->td_resolutionunit, + td->td_resolutionunit); + break; + } + } + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif,FIELD_POSITION)) + fprintf(fd, " Position: %g, %g\n", + td->td_xposition, td->td_yposition); + if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) + fprintf(fd, " Bits/Sample: %u\n", td->td_bitspersample); + if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) { + fprintf(fd, " Sample Format: "); + switch (td->td_sampleformat) { + case SAMPLEFORMAT_VOID: + fprintf(fd, "void\n"); + break; + case SAMPLEFORMAT_INT: + fprintf(fd, "signed integer\n"); + break; + case SAMPLEFORMAT_UINT: + fprintf(fd, "unsigned integer\n"); + break; + case SAMPLEFORMAT_IEEEFP: + fprintf(fd, "IEEE floating point\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_sampleformat, td->td_sampleformat); + break; + } + } + if (TIFFFieldSet(tif,FIELD_COMPRESSION)) { + const TIFFCodec* c = TIFFFindCODEC(td->td_compression); + fprintf(fd, " Compression Scheme: "); + if (c) + fprintf(fd, "%s\n", c->name); + else + fprintf(fd, "%u (0x%x)\n", + td->td_compression, td->td_compression); + } + if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) { + fprintf(fd, " Photometric Interpretation: "); + if (td->td_photometric < NPHOTONAMES) + fprintf(fd, "%s\n", photoNames[td->td_photometric]); + else { + switch (td->td_photometric) { + case PHOTOMETRIC_LOGL: + fprintf(fd, "CIE Log2(L)\n"); + break; + case PHOTOMETRIC_LOGLUV: + fprintf(fd, "CIE Log2(L) (u',v')\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_photometric, td->td_photometric); + break; + } + } + } + if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) { + fprintf(fd, " Extra Samples: %u<", td->td_extrasamples); + sep = ""; + for (i = 0; i < td->td_extrasamples; i++) { + switch (td->td_sampleinfo[i]) { + case EXTRASAMPLE_UNSPECIFIED: + fprintf(fd, "%sunspecified", sep); + break; + case EXTRASAMPLE_ASSOCALPHA: + fprintf(fd, "%sassoc-alpha", sep); + break; + case EXTRASAMPLE_UNASSALPHA: + fprintf(fd, "%sunassoc-alpha", sep); + break; + default: + fprintf(fd, "%s%u (0x%x)", sep, + td->td_sampleinfo[i], td->td_sampleinfo[i]); + break; + } + sep = ", "; + } + fprintf(fd, ">\n"); + } + if (TIFFFieldSet(tif,FIELD_STONITS)) { + fprintf(fd, " Sample to Nits conversion factor: %.4e\n", + td->td_stonits); + } +#ifdef CMYK_SUPPORT + if (TIFFFieldSet(tif,FIELD_INKSET)) { + fprintf(fd, " Ink Set: "); + switch (td->td_inkset) { + case INKSET_CMYK: + fprintf(fd, "CMYK\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_inkset, td->td_inkset); + break; + } + } + if (TIFFFieldSet(tif,FIELD_INKNAMES)) { + char* cp; + fprintf(fd, " Ink Names: "); + i = td->td_samplesperpixel; + sep = ""; + for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) { + fprintf(fd, "%s", sep); + _TIFFprintAscii(fd, cp); + sep = ", "; + } + } + if (TIFFFieldSet(tif,FIELD_NUMBEROFINKS)) + fprintf(fd, " Number of Inks: %u\n", td->td_ninks); + if (TIFFFieldSet(tif,FIELD_DOTRANGE)) + fprintf(fd, " Dot Range: %u-%u\n", + td->td_dotrange[0], td->td_dotrange[1]); + if (TIFFFieldSet(tif,FIELD_TARGETPRINTER)) + _TIFFprintAsciiTag(fd, "Target Printer", td->td_targetprinter); +#endif + if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) { + fprintf(fd, " Thresholding: "); + switch (td->td_threshholding) { + case THRESHHOLD_BILEVEL: + fprintf(fd, "bilevel art scan\n"); + break; + case THRESHHOLD_HALFTONE: + fprintf(fd, "halftone or dithered scan\n"); + break; + case THRESHHOLD_ERRORDIFFUSE: + fprintf(fd, "error diffused\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_threshholding, td->td_threshholding); + break; + } + } + if (TIFFFieldSet(tif,FIELD_FILLORDER)) { + fprintf(fd, " FillOrder: "); + switch (td->td_fillorder) { + case FILLORDER_MSB2LSB: + fprintf(fd, "msb-to-lsb\n"); + break; + case FILLORDER_LSB2MSB: + fprintf(fd, "lsb-to-msb\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_fillorder, td->td_fillorder); + break; + } + } +#ifdef YCBCR_SUPPORT + if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) + fprintf(fd, " YCbCr Subsampling: %u, %u\n", + td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]); + if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) { + fprintf(fd, " YCbCr Positioning: "); + switch (td->td_ycbcrpositioning) { + case YCBCRPOSITION_CENTERED: + fprintf(fd, "centered\n"); + break; + case YCBCRPOSITION_COSITED: + fprintf(fd, "cosited\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_ycbcrpositioning, td->td_ycbcrpositioning); + break; + } + } + if (TIFFFieldSet(tif,FIELD_YCBCRCOEFFICIENTS)) + fprintf(fd, " YCbCr Coefficients: %g, %g, %g\n", + td->td_ycbcrcoeffs[0], + td->td_ycbcrcoeffs[1], + td->td_ycbcrcoeffs[2]); +#endif + if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) + fprintf(fd, " Halftone Hints: light %u dark %u\n", + td->td_halftonehints[0], td->td_halftonehints[1]); + if (TIFFFieldSet(tif,FIELD_ARTIST)) + _TIFFprintAsciiTag(fd, "Artist", td->td_artist); + if (TIFFFieldSet(tif,FIELD_DATETIME)) + _TIFFprintAsciiTag(fd, "Date & Time", td->td_datetime); + if (TIFFFieldSet(tif,FIELD_HOSTCOMPUTER)) + _TIFFprintAsciiTag(fd, "Host Computer", td->td_hostcomputer); + if (TIFFFieldSet(tif,FIELD_SOFTWARE)) + _TIFFprintAsciiTag(fd, "Software", td->td_software); + if (TIFFFieldSet(tif,FIELD_DOCUMENTNAME)) + _TIFFprintAsciiTag(fd, "Document Name", td->td_documentname); + if (TIFFFieldSet(tif,FIELD_IMAGEDESCRIPTION)) + _TIFFprintAsciiTag(fd, "Image Description", td->td_imagedescription); + if (TIFFFieldSet(tif,FIELD_MAKE)) + _TIFFprintAsciiTag(fd, "Make", td->td_make); + if (TIFFFieldSet(tif,FIELD_MODEL)) + _TIFFprintAsciiTag(fd, "Model", td->td_model); + if (TIFFFieldSet(tif,FIELD_ORIENTATION)) { + fprintf(fd, " Orientation: "); + if (td->td_orientation < NORIENTNAMES) + fprintf(fd, "%s\n", orientNames[td->td_orientation]); + else + fprintf(fd, "%u (0x%x)\n", + td->td_orientation, td->td_orientation); + } + if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) + fprintf(fd, " Samples/Pixel: %u\n", td->td_samplesperpixel); + if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) { + fprintf(fd, " Rows/Strip: "); + if (td->td_rowsperstrip == (uint32) -1) + fprintf(fd, "(infinite)\n"); + else + fprintf(fd, "%lu\n", (u_long) td->td_rowsperstrip); + } + if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) + fprintf(fd, " Min Sample Value: %u\n", td->td_minsamplevalue); + if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) + fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue); + if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) + fprintf(fd, " SMin Sample Value: %g\n", + td->td_sminsamplevalue); + if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) + fprintf(fd, " SMax Sample Value: %g\n", + td->td_smaxsamplevalue); + if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) { + fprintf(fd, " Planar Configuration: "); + switch (td->td_planarconfig) { + case PLANARCONFIG_CONTIG: + fprintf(fd, "single image plane\n"); + break; + case PLANARCONFIG_SEPARATE: + fprintf(fd, "separate image planes\n"); + break; + default: + fprintf(fd, "%u (0x%x)\n", + td->td_planarconfig, td->td_planarconfig); + break; + } + } + if (TIFFFieldSet(tif,FIELD_PAGENAME)) + _TIFFprintAsciiTag(fd, "Page Name", td->td_pagename); + if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) + fprintf(fd, " Page Number: %u-%u\n", + td->td_pagenumber[0], td->td_pagenumber[1]); + if (TIFFFieldSet(tif,FIELD_COLORMAP)) { + fprintf(fd, " Color Map: "); + if (flags & TIFFPRINT_COLORMAP) { + fprintf(fd, "\n"); + n = 1L<td_bitspersample; + for (l = 0; l < n; l++) + fprintf(fd, " %5lu: %5u %5u %5u\n", + l, + td->td_colormap[0][l], + td->td_colormap[1][l], + td->td_colormap[2][l]); + } else + fprintf(fd, "(present)\n"); + } +#ifdef COLORIMETRY_SUPPORT + if (TIFFFieldSet(tif,FIELD_WHITEPOINT)) + fprintf(fd, " White Point: %g-%g\n", + td->td_whitepoint[0], td->td_whitepoint[1]); + if (TIFFFieldSet(tif,FIELD_PRIMARYCHROMAS)) + fprintf(fd, " Primary Chromaticities: %g,%g %g,%g %g,%g\n", + td->td_primarychromas[0], td->td_primarychromas[1], + td->td_primarychromas[2], td->td_primarychromas[3], + td->td_primarychromas[4], td->td_primarychromas[5]); + if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) { + fprintf(fd, " Reference Black/White:\n"); + for (i = 0; i < td->td_samplesperpixel; i++) + fprintf(fd, " %2d: %5g %5g\n", + i, + td->td_refblackwhite[2*i+0], + td->td_refblackwhite[2*i+1]); + } + if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) { + fprintf(fd, " Transfer Function: "); + if (flags & TIFFPRINT_CURVES) { + fprintf(fd, "\n"); + n = 1L<td_bitspersample; + for (l = 0; l < n; l++) { + fprintf(fd, " %2lu: %5u", + l, td->td_transferfunction[0][l]); + for (i = 1; i < td->td_samplesperpixel; i++) + fprintf(fd, " %5u", + td->td_transferfunction[i][l]); + fputc('\n', fd); + } + } else + fprintf(fd, "(present)\n"); + } +#endif +#ifdef ICC_SUPPORT + if (TIFFFieldSet(tif,FIELD_ICCPROFILE)) + fprintf(fd, " ICC Profile: , %lu bytes\n", + (u_long) td->td_profileLength); +#endif +#ifdef PHOTOSHOP_SUPPORT + if (TIFFFieldSet(tif,FIELD_PHOTOSHOP)) + fprintf(fd, " Photoshop Data: , %lu bytes\n", + (u_long) td->td_photoshopLength); +#endif +#ifdef IPTC_SUPPORT + if (TIFFFieldSet(tif,FIELD_RICHTIFFIPTC)) + fprintf(fd, " RichTIFFIPTC Data: , %lu bytes\n", + (u_long) td->td_richtiffiptcLength); +#endif +#if SUBIFD_SUPPORT + if (TIFFFieldSet(tif, FIELD_SUBIFD)) { + fprintf(fd, " SubIFD Offsets:"); + for (i = 0; i < td->td_nsubifd; i++) + fprintf(fd, " %5lu", (long) td->td_subifd[i]); + fputc('\n', fd); + } +#endif + if (tif->tif_printdir) + (*tif->tif_printdir)(tif, fd, flags); + if ((flags & TIFFPRINT_STRIPS) && + TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) { + tstrip_t s; + + fprintf(fd, " %lu %s:\n", + (long) td->td_nstrips, + isTiled(tif) ? "Tiles" : "Strips"); + for (s = 0; s < td->td_nstrips; s++) + fprintf(fd, " %3lu: [%8lu, %8lu]\n", + (u_long) s, + (u_long) td->td_stripoffset[s], + (u_long) td->td_stripbytecount[s]); + } +} + +void +_TIFFprintAscii(FILE* fd, const char* cp) +{ + for (; *cp != '\0'; cp++) { + const char* tp; + + if (isprint(*cp)) { + fputc(*cp, fd); + continue; + } + for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) + if (*tp++ == *cp) + break; + if (*tp) + fprintf(fd, "\\%c", *tp); + else + fprintf(fd, "\\%03o", *cp & 0xff); + } +} + +void +_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value) +{ + fprintf(fd, " %s: \"", name); + _TIFFprintAscii(fd, value); + fprintf(fd, "\"\n"); +} diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c new file mode 100644 index 00000000..389616d2 --- /dev/null +++ b/libtiff/tif_read.c @@ -0,0 +1,622 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_read.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * Scanline-oriented Read Support + */ +#include "tiffiop.h" +#include +#include + +static int TIFFFillStrip(TIFF*, tstrip_t); +static int TIFFFillTile(TIFF*, ttile_t); +static int TIFFStartStrip(TIFF*, tstrip_t); +static int TIFFStartTile(TIFF*, ttile_t); +static int TIFFCheckRead(TIFF*, int); + +#define NOSTRIP ((tstrip_t) -1) /* undefined state */ +#define NOTILE ((ttile_t) -1) /* undefined state */ + +/* + * Seek to a random row+sample in a file. + */ +static int +TIFFSeek(TIFF* tif, uint32 row, tsample_t sample) +{ + register TIFFDirectory *td = &tif->tif_dir; + tstrip_t strip; + + if (row >= td->td_imagelength) { /* out of range */ + TIFFError(tif->tif_name, "%lu: Row out of range, max %lu", + (u_long) row, (u_long) td->td_imagelength); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + if (sample >= td->td_samplesperpixel) { + TIFFError(tif->tif_name, + "%lu: Sample out of range, max %lu", + (u_long) sample, (u_long) td->td_samplesperpixel); + return (0); + } + strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; + } else + strip = row / td->td_rowsperstrip; + if (strip != tif->tif_curstrip) { /* different strip, refill */ + if (!TIFFFillStrip(tif, strip)) + return (0); + } else if (row < tif->tif_row) { + /* + * Moving backwards within the same strip: backup + * to the start and then decode forward (below). + * + * NB: If you're planning on lots of random access within a + * strip, it's better to just read and decode the entire + * strip, and then access the decoded data in a random fashion. + */ + if (!TIFFStartStrip(tif, strip)) + return (0); + } + if (row != tif->tif_row) { + /* + * Seek forward to the desired row. + */ + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (0); + tif->tif_row = row; + } + return (1); +} + +int +TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) +{ + int e; + + if (!TIFFCheckRead(tif, 0)) + return (-1); + if (e = TIFFSeek(tif, row, sample)) { + /* + * Decompress desired row into user buffer. + */ + e = (*tif->tif_decoderow) + (tif, (tidata_t) buf, tif->tif_scanlinesize, sample); + tif->tif_row++; + if (e) + (*tif->tif_postdecode)(tif, (tidata_t) buf, + tif->tif_scanlinesize); + } + return (e > 0 ? 1 : -1); +} + +/* + * Read a strip of data and decompress the specified + * amount into the user-supplied buffer. + */ +tsize_t +TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) +{ + TIFFDirectory *td = &tif->tif_dir; + uint32 nrows; + tsize_t stripsize; + + if (!TIFFCheckRead(tif, 0)) + return (-1); + if (strip >= td->td_nstrips) { + TIFFError(tif->tif_name, "%ld: Strip out of range, max %ld", + (long) strip, (long) td->td_nstrips); + return (-1); + } + /* + * Calculate the strip size according to the number of + * rows in the strip (check for truncated last strip). + */ + if (strip != td->td_nstrips-1 || + (nrows = td->td_imagelength % td->td_rowsperstrip) == 0) + nrows = td->td_rowsperstrip; + stripsize = TIFFVStripSize(tif, nrows); + if (size == (tsize_t) -1) + size = stripsize; + else if (size > stripsize) + size = stripsize; + if (TIFFFillStrip(tif, strip) && (*tif->tif_decodestrip)(tif, + (tidata_t) buf, size, (tsample_t)(strip / td->td_stripsperimage))) { + (*tif->tif_postdecode)(tif, (tidata_t) buf, size); + return (size); + } else + return ((tsize_t) -1); +} + +static tsize_t +TIFFReadRawStrip1(TIFF* tif, + tstrip_t strip, tdata_t buf, tsize_t size, const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (!isMapped(tif)) { + tsize_t cc; + + if (!SeekOK(tif, td->td_stripoffset[strip])) { + TIFFError(module, + "%s: Seek error at scanline %lu, strip %lu", + tif->tif_name, + (u_long) tif->tif_row, (u_long) strip); + return (-1); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) { + TIFFError(module, + "%s: Read error at scanline %lu; got %lu bytes, expected %lu", + tif->tif_name, + (u_long) tif->tif_row, + (u_long) cc, + (u_long) size); + return (-1); + } + } else { + if (td->td_stripoffset[strip] + size > tif->tif_size) { + TIFFError(module, + "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu", + tif->tif_name, + (u_long) tif->tif_row, + (u_long) strip, + (u_long) tif->tif_size - td->td_stripoffset[strip], + (u_long) size); + return (-1); + } + _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[strip], size); + } + return (size); +} + +/* + * Read a strip of data from the file. + */ +tsize_t +TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) +{ + static const char module[] = "TIFFReadRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + tsize_t bytecount; + + if (!TIFFCheckRead(tif, 0)) + return ((tsize_t) -1); + if (strip >= td->td_nstrips) { + TIFFError(tif->tif_name, "%lu: Strip out of range, max %lu", + (u_long) strip, (u_long) td->td_nstrips); + return ((tsize_t) -1); + } + bytecount = td->td_stripbytecount[strip]; + if (bytecount <= 0) { + TIFFError(tif->tif_name, + "%lu: Invalid strip byte count, strip %lu", + (u_long) bytecount, (u_long) strip); + return ((tsize_t) -1); + } + if (size != (tsize_t)-1 && size < bytecount) + bytecount = size; + return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module)); +} + +/* + * Read the specified strip and setup for decoding. + * The data buffer is expanded, as necessary, to + * hold the strip's data. + */ +static int +TIFFFillStrip(TIFF* tif, tstrip_t strip) +{ + static const char module[] = "TIFFFillStrip"; + TIFFDirectory *td = &tif->tif_dir; + tsize_t bytecount; + + bytecount = td->td_stripbytecount[strip]; + if (bytecount <= 0) { + TIFFError(tif->tif_name, + "%lu: Invalid strip byte count, strip %lu", + (u_long) bytecount, (u_long) strip); + return (0); + } + if (isMapped(tif) && + (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is going + * to handle this operation itself. In this case, avoid + * copying the raw data and instead just reference the + * data from the memory mapped file image. This assumes + * that the decompression routines do not modify the + * contents of the raw data buffer (if they try to, + * the application will get a fault since the file is + * mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + _TIFFfree(tif->tif_rawdata); + tif->tif_flags &= ~TIFF_MYBUFFER; + if (td->td_stripoffset[strip] + bytecount > tif->tif_size) { + /* + * This error message might seem strange, but it's + * what would happen if a read were done instead. + */ + TIFFError(module, + "%s: Read error on strip %lu; got %lu bytes, expected %lu", + tif->tif_name, + (u_long) strip, + (u_long) tif->tif_size - td->td_stripoffset[strip], + (u_long) bytecount); + tif->tif_curstrip = NOSTRIP; + return (0); + } + tif->tif_rawdatasize = bytecount; + tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip]; + } else { + /* + * Expand raw data buffer, if needed, to + * hold data strip coming from file + * (perhaps should set upper bound on + * the size of a buffer we'll use?). + */ + if (bytecount > tif->tif_rawdatasize) { + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { + TIFFError(module, + "%s: Data buffer too small to hold strip %lu", + tif->tif_name, (u_long) strip); + return (0); + } + if (!TIFFReadBufferSetup(tif, 0, + TIFFroundup(bytecount, 1024))) + return (0); + } + if (TIFFReadRawStrip1(tif, strip, (u_char *)tif->tif_rawdata, + bytecount, module) != bytecount) + return (0); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, bytecount); + } + return (TIFFStartStrip(tif, strip)); +} + +/* + * Tile-oriented Read Support + * Contributed by Nancy Cam (Silicon Graphics). + */ + +/* + * Read and decompress a tile of data. The + * tile is selected by the (x,y,z,s) coordinates. + */ +tsize_t +TIFFReadTile(TIFF* tif, + tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s) +{ + if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) + return (-1); + return (TIFFReadEncodedTile(tif, + TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1)); +} + +/* + * Read a tile of data and decompress the specified + * amount into the user-supplied buffer. + */ +tsize_t +TIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) +{ + TIFFDirectory *td = &tif->tif_dir; + tsize_t tilesize = tif->tif_tilesize; + + if (!TIFFCheckRead(tif, 1)) + return (-1); + if (tile >= td->td_nstrips) { + TIFFError(tif->tif_name, "%ld: Tile out of range, max %ld", + (long) tile, (u_long) td->td_nstrips); + return (-1); + } + if (size == (tsize_t) -1) + size = tilesize; + else if (size > tilesize) + size = tilesize; + if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, + (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) { + (*tif->tif_postdecode)(tif, (tidata_t) buf, size); + return (size); + } else + return (-1); +} + +static tsize_t +TIFFReadRawTile1(TIFF* tif, + ttile_t tile, tdata_t buf, tsize_t size, const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (!isMapped(tif)) { + tsize_t cc; + + if (!SeekOK(tif, td->td_stripoffset[tile])) { + TIFFError(module, + "%s: Seek error at row %ld, col %ld, tile %ld", + tif->tif_name, + (long) tif->tif_row, + (long) tif->tif_col, + (long) tile); + return ((tsize_t) -1); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) { + TIFFError(module, + "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu", + tif->tif_name, + (long) tif->tif_row, + (long) tif->tif_col, + (u_long) cc, + (u_long) size); + return ((tsize_t) -1); + } + } else { + if (td->td_stripoffset[tile] + size > tif->tif_size) { + TIFFError(module, + "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu", + tif->tif_name, + (long) tif->tif_row, + (long) tif->tif_col, + (long) tile, + (u_long) tif->tif_size - td->td_stripoffset[tile], + (u_long) size); + return ((tsize_t) -1); + } + _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size); + } + return (size); +} + +/* + * Read a tile of data from the file. + */ +tsize_t +TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) +{ + static const char module[] = "TIFFReadRawTile"; + TIFFDirectory *td = &tif->tif_dir; + tsize_t bytecount; + + if (!TIFFCheckRead(tif, 1)) + return ((tsize_t) -1); + if (tile >= td->td_nstrips) { + TIFFError(tif->tif_name, "%lu: Tile out of range, max %lu", + (u_long) tile, (u_long) td->td_nstrips); + return ((tsize_t) -1); + } + bytecount = td->td_stripbytecount[tile]; + if (size != (tsize_t) -1 && size < bytecount) + bytecount = size; + return (TIFFReadRawTile1(tif, tile, buf, bytecount, module)); +} + +/* + * Read the specified tile and setup for decoding. + * The data buffer is expanded, as necessary, to + * hold the tile's data. + */ +static int +TIFFFillTile(TIFF* tif, ttile_t tile) +{ + static const char module[] = "TIFFFillTile"; + TIFFDirectory *td = &tif->tif_dir; + tsize_t bytecount; + + bytecount = td->td_stripbytecount[tile]; + if (bytecount <= 0) { + TIFFError(tif->tif_name, + "%lu: Invalid tile byte count, tile %lu", + (u_long) bytecount, (u_long) tile); + return (0); + } + if (isMapped(tif) && + (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is going + * to handle this operation itself. In this case, avoid + * copying the raw data and instead just reference the + * data from the memory mapped file image. This assumes + * that the decompression routines do not modify the + * contents of the raw data buffer (if they try to, + * the application will get a fault since the file is + * mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + _TIFFfree(tif->tif_rawdata); + tif->tif_flags &= ~TIFF_MYBUFFER; + if (td->td_stripoffset[tile] + bytecount > tif->tif_size) { + tif->tif_curtile = NOTILE; + return (0); + } + tif->tif_rawdatasize = bytecount; + tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile]; + } else { + /* + * Expand raw data buffer, if needed, to + * hold data tile coming from file + * (perhaps should set upper bound on + * the size of a buffer we'll use?). + */ + if (bytecount > tif->tif_rawdatasize) { + tif->tif_curtile = NOTILE; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { + TIFFError(module, + "%s: Data buffer too small to hold tile %ld", + tif->tif_name, (long) tile); + return (0); + } + if (!TIFFReadBufferSetup(tif, 0, + TIFFroundup(bytecount, 1024))) + return (0); + } + if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata, + bytecount, module) != bytecount) + return (0); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, bytecount); + } + return (TIFFStartTile(tif, tile)); +} + +/* + * Setup the raw data buffer in preparation for + * reading a strip of raw data. If the buffer + * is specified as zero, then a buffer of appropriate + * size is allocated by the library. Otherwise, + * the client must guarantee that the buffer is + * large enough to hold any individual strip of + * raw data. + */ +int +TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) +{ + static const char module[] = "TIFFReadBufferSetup"; + + if (tif->tif_rawdata) { + if (tif->tif_flags & TIFF_MYBUFFER) + _TIFFfree(tif->tif_rawdata); + tif->tif_rawdata = NULL; + } + if (bp) { + tif->tif_rawdatasize = size; + tif->tif_rawdata = (tidata_t) bp; + tif->tif_flags &= ~TIFF_MYBUFFER; + } else { + tif->tif_rawdatasize = TIFFroundup(size, 1024); + tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize); + tif->tif_flags |= TIFF_MYBUFFER; + } + if (tif->tif_rawdata == NULL) { + TIFFError(module, + "%s: No space for data buffer at scanline %ld", + tif->tif_name, (long) tif->tif_row); + tif->tif_rawdatasize = 0; + return (0); + } + return (1); +} + +/* + * Set state to appear as if a + * strip has just been read in. + */ +static int +TIFFStartStrip(TIFF* tif, tstrip_t strip) +{ + TIFFDirectory *td = &tif->tif_dir; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_rawcc = td->td_stripbytecount[strip]; + return ((*tif->tif_predecode)(tif, + (tsample_t)(strip / td->td_stripsperimage))); +} + +/* + * Set state to appear as if a + * tile has just been read in. + */ +static int +TIFFStartTile(TIFF* tif, ttile_t tile) +{ + TIFFDirectory *td = &tif->tif_dir; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curtile = tile; + tif->tif_row = + (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) * + td->td_tilelength; + tif->tif_col = + (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) * + td->td_tilewidth; + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_rawcc = td->td_stripbytecount[tile]; + return ((*tif->tif_predecode)(tif, + (tsample_t)(tile/td->td_stripsperimage))); +} + +static int +TIFFCheckRead(TIFF* tif, int tiles) +{ + if (tif->tif_mode == O_WRONLY) { + TIFFError(tif->tif_name, "File not open for reading"); + return (0); + } + if (tiles ^ isTiled(tif)) { + TIFFError(tif->tif_name, tiles ? + "Can not read tiles from a stripped image" : + "Can not read scanlines from a tiled image"); + return (0); + } + return (1); +} + +void +_TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc) +{ + (void) tif; (void) buf; (void) cc; +} + +void +_TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc) +{ + (void) tif; + assert((cc & 1) == 0); + TIFFSwabArrayOfShort((uint16*) buf, cc/2); +} + +void +_TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc) +{ + (void) tif; + assert((cc & 3) == 0); + TIFFSwabArrayOfLong((uint32*) buf, cc/4); +} + +void +_TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc) +{ + (void) tif; + assert((cc & 7) == 0); + TIFFSwabArrayOfDouble((double*) buf, cc/8); +} diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c new file mode 100644 index 00000000..c7c018a7 --- /dev/null +++ b/libtiff/tif_strip.c @@ -0,0 +1,192 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_strip.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Strip-organized Image Support Routines. + */ +#include "tiffiop.h" + +/* + * Compute which strip a (row,sample) value is in. + */ +tstrip_t +TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample) +{ + TIFFDirectory *td = &tif->tif_dir; + tstrip_t strip; + + strip = row / td->td_rowsperstrip; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + if (sample >= td->td_samplesperpixel) { + TIFFError(tif->tif_name, + "%u: Sample out of range, max %u", + sample, td->td_samplesperpixel); + return ((tstrip_t) 0); + } + strip += sample*td->td_stripsperimage; + } + return (strip); +} + +/* + * Compute how many strips are in an image. + */ +tstrip_t +TIFFNumberOfStrips(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + tstrip_t nstrips; + + nstrips = (td->td_rowsperstrip == (uint32) -1 ? + (td->td_imagelength != 0 ? 1 : 0) : + TIFFhowmany(td->td_imagelength, td->td_rowsperstrip)); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + nstrips *= td->td_samplesperpixel; + return (nstrips); +} + +/* + * Compute the # bytes in a variable height, row-aligned strip. + */ +tsize_t +TIFFVStripSize(TIFF* tif, uint32 nrows) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (nrows == (uint32) -1) + nrows = td->td_imagelength; +#ifdef YCBCR_SUPPORT + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + td->td_photometric == PHOTOMETRIC_YCBCR && + !isUpSampled(tif)) { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + tsize_t w = + TIFFroundup(td->td_imagewidth, td->td_ycbcrsubsampling[0]); + tsize_t scanline = TIFFhowmany(w*td->td_bitspersample, 8); + tsize_t samplingarea = + td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; + nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); + /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ + return ((tsize_t) + (nrows*scanline + 2*(nrows*scanline / samplingarea))); + } else +#endif + return ((tsize_t)(nrows * TIFFScanlineSize(tif))); +} + +/* + * Compute the # bytes in a (row-aligned) strip. + * + * Note that if RowsPerStrip is larger than the + * recorded ImageLength, then the strip size is + * truncated to reflect the actual space required + * to hold the strip. + */ +tsize_t +TIFFStripSize(TIFF* tif) +{ + TIFFDirectory* td = &tif->tif_dir; + uint32 rps = td->td_rowsperstrip; + if (rps > td->td_imagelength) + rps = td->td_imagelength; + return (TIFFVStripSize(tif, rps)); +} + +/* + * Compute a default strip size based on the image + * characteristics and a requested value. If the + * request is <1 then we choose a strip size according + * to certain heuristics. + */ +uint32 +TIFFDefaultStripSize(TIFF* tif, uint32 request) +{ + return (*tif->tif_defstripsize)(tif, request); +} + +uint32 +_TIFFDefaultStripSize(TIFF* tif, uint32 s) +{ + if ((int32) s < 1) { + /* + * If RowsPerStrip is unspecified, try to break the + * image up into strips that are approximately 8Kbytes. + */ + tsize_t scanline = TIFFScanlineSize(tif); + s = (uint32)(8*1024) / (scanline == 0 ? 1 : scanline); + if (s == 0) /* very wide images */ + s = 1; + } + return (s); +} + +/* + * Return the number of bytes to read/write in a call to + * one of the scanline-oriented i/o routines. Note that + * this number may be 1/samples-per-pixel if data is + * stored as separate planes. + */ +tsize_t +TIFFScanlineSize(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + tsize_t scanline; + + scanline = td->td_bitspersample * td->td_imagewidth; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + scanline *= td->td_samplesperpixel; + return ((tsize_t) TIFFhowmany(scanline, 8)); +} + +/* + * Return the number of bytes required to store a complete + * decoded and packed raster scanline (as opposed to the + * I/O size returned by TIFFScanlineSize which may be less + * if data is store as separate planes). + */ +tsize_t +TIFFRasterScanlineSize(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + tsize_t scanline; + + scanline = td->td_bitspersample * td->td_imagewidth; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { + scanline *= td->td_samplesperpixel; + return ((tsize_t) TIFFhowmany(scanline, 8)); + } else + return ((tsize_t) + TIFFhowmany(scanline, 8)*td->td_samplesperpixel); +} diff --git a/libtiff/tif_swab.c b/libtiff/tif_swab.c new file mode 100644 index 00000000..0e3de0cb --- /dev/null +++ b/libtiff/tif_swab.c @@ -0,0 +1,217 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_swab.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library Bit & Byte Swapping Support. + * + * XXX We assume short = 16-bits and long = 32-bits XXX + */ +#include "tiffiop.h" + +#ifndef TIFFSwabShort +void +TIFFSwabShort(uint16* wp) +{ + register u_char* cp = (u_char*) wp; + int t; + + t = cp[1]; cp[1] = cp[0]; cp[0] = t; +} +#endif + +#ifndef TIFFSwabLong +void +TIFFSwabLong(uint32* lp) +{ + register u_char* cp = (u_char*) lp; + int t; + + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; +} +#endif + +#ifndef TIFFSwabArrayOfShort +void +TIFFSwabArrayOfShort(uint16* wp, register u_long n) +{ + register u_char* cp; + register int t; + + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (u_char*) wp; + t = cp[1]; cp[1] = cp[0]; cp[0] = t; + wp++; + } +} +#endif + +#ifndef TIFFSwabArrayOfLong +void +TIFFSwabArrayOfLong(register uint32* lp, register u_long n) +{ + register unsigned char *cp; + register int t; + + /* XXX unroll loop some */ + while (n-- > 0) { + cp = (unsigned char *)lp; + t = cp[3]; cp[3] = cp[0]; cp[0] = t; + t = cp[2]; cp[2] = cp[1]; cp[1] = t; + lp++; + } +} +#endif + +#ifndef TIFFSwabDouble +void +TIFFSwabDouble(double *dp) +{ + register uint32* lp = (uint32*) dp; + uint32 t; + + TIFFSwabArrayOfLong(lp, 2); + t = lp[0]; lp[0] = lp[1]; lp[1] = t; +} +#endif + +#ifndef TIFFSwabArrayOfDouble +void +TIFFSwabArrayOfDouble(double* dp, register u_long n) +{ + register uint32* lp = (uint32*) dp; + register uint32 t; + + TIFFSwabArrayOfLong(lp, n + n); + while (n-- > 0) { + t = lp[0]; lp[0] = lp[1]; lp[1] = t; + lp += 2; + } +} +#endif + +/* + * Bit reversal tables. TIFFBitRevTable[] gives + * the bit reversed value of . Used in various + * places in the library when the FillOrder requires + * bit reversal of byte values (e.g. CCITT Fax 3 + * encoding/decoding). TIFFNoBitRevTable is provided + * for algorithms that want an equivalent table that + * do not reverse bit values. + */ +static const unsigned char TIFFBitRevTable[256] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; +static const unsigned char TIFFNoBitRevTable[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +const unsigned char* +TIFFGetBitRevTable(int reversed) +{ + return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); +} + +void +TIFFReverseBits(register u_char* cp, register u_long n) +{ + for (; n > 8; n -= 8) { + cp[0] = TIFFBitRevTable[cp[0]]; + cp[1] = TIFFBitRevTable[cp[1]]; + cp[2] = TIFFBitRevTable[cp[2]]; + cp[3] = TIFFBitRevTable[cp[3]]; + cp[4] = TIFFBitRevTable[cp[4]]; + cp[5] = TIFFBitRevTable[cp[5]]; + cp[6] = TIFFBitRevTable[cp[6]]; + cp[7] = TIFFBitRevTable[cp[7]]; + cp += 8; + } + while (n-- > 0) + *cp = TIFFBitRevTable[*cp], cp++; +} diff --git a/libtiff/tif_thunder.c b/libtiff/tif_thunder.c new file mode 100644 index 00000000..ef8f1067 --- /dev/null +++ b/libtiff/tif_thunder.c @@ -0,0 +1,154 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_thunder.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef THUNDER_SUPPORT +/* + * TIFF Library. + * + * ThunderScan 4-bit Compression Algorithm Support + */ + +/* + * ThunderScan uses an encoding scheme designed for + * 4-bit pixel values. Data is encoded in bytes, with + * each byte split into a 2-bit code word and a 6-bit + * data value. The encoding gives raw data, runs of + * pixels, or pixel values encoded as a delta from the + * previous pixel value. For the latter, either 2-bit + * or 3-bit delta values are used, with the deltas packed + * into a single byte. + */ +#define THUNDER_DATA 0x3f /* mask for 6-bit data */ +#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ +/* code values */ +#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ +#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ +#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ +#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ +#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ +#define THUNDER_RAW 0xc0 /* raw data encoded */ + +static const int twobitdeltas[4] = { 0, 1, 0, -1 }; +static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; + +#define SETPIXEL(op, v) { \ + lastpixel = (v) & 0xf; \ + if (npixels++ & 1) \ + *op++ |= lastpixel; \ + else \ + op[0] = lastpixel << 4; \ +} + +static int +ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels) +{ + register u_char *bp; + register tsize_t cc; + u_int lastpixel; + tsize_t npixels; + + bp = (u_char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + lastpixel = 0; + npixels = 0; + while (cc > 0 && npixels < maxpixels) { + int n, delta; + + n = *bp++, cc--; + switch (n & THUNDER_CODE) { + case THUNDER_RUN: /* pixel run */ + /* + * Replicate the last pixel n times, + * where n is the lower-order 6 bits. + */ + if (npixels & 1) { + op[0] |= lastpixel; + lastpixel = *op++; npixels++; n--; + } else + lastpixel |= lastpixel << 4; + npixels += n; + for (; n > 0; n -= 2) + *op++ = lastpixel; + if (n == -1) + *--op &= 0xf0; + lastpixel &= 0xf; + break; + case THUNDER_2BITDELTAS: /* 2-bit deltas */ + if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) + SETPIXEL(op, lastpixel + twobitdeltas[delta]); + if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) + SETPIXEL(op, lastpixel + twobitdeltas[delta]); + if ((delta = (n & 3)) != DELTA2_SKIP) + SETPIXEL(op, lastpixel + twobitdeltas[delta]); + break; + case THUNDER_3BITDELTAS: /* 3-bit deltas */ + if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) + SETPIXEL(op, lastpixel + threebitdeltas[delta]); + if ((delta = (n & 7)) != DELTA3_SKIP) + SETPIXEL(op, lastpixel + threebitdeltas[delta]); + break; + case THUNDER_RAW: /* raw data */ + SETPIXEL(op, n); + break; + } + } + tif->tif_rawcp = (tidata_t) bp; + tif->tif_rawcc = cc; + if (npixels != maxpixels) { + TIFFError(tif->tif_name, + "ThunderDecode: %s data at scanline %ld (%lu != %lu)", + npixels < maxpixels ? "Not enough" : "Too much", + (long) tif->tif_row, (long) npixels, (long) maxpixels); + return (0); + } + return (1); +} + +static int +ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) +{ + tidata_t row = buf; + + (void) s; + while ((long)occ > 0) { + if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) + return (0); + occ -= tif->tif_scanlinesize; + row += tif->tif_scanlinesize; + } + return (1); +} + +int +TIFFInitThunderScan(TIFF* tif, int scheme) +{ + (void) scheme; + tif->tif_decoderow = ThunderDecodeRow; + tif->tif_decodestrip = ThunderDecodeRow; + return (1); +} +#endif /* THUNDER_SUPPORT */ diff --git a/libtiff/tif_tile.c b/libtiff/tif_tile.c new file mode 100644 index 00000000..418d29f2 --- /dev/null +++ b/libtiff/tif_tile.c @@ -0,0 +1,219 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_tile.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Tiled Image Support Routines. + */ +#include "tiffiop.h" + +/* + * Compute which tile an (x,y,z,s) value is in. + */ +ttile_t +TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) +{ + TIFFDirectory *td = &tif->tif_dir; + uint32 dx = td->td_tilewidth; + uint32 dy = td->td_tilelength; + uint32 dz = td->td_tiledepth; + ttile_t tile = 1; + + if (td->td_imagedepth == 1) + z = 0; + if (dx == (uint32) -1) + dx = td->td_imagewidth; + if (dy == (uint32) -1) + dy = td->td_imagelength; + if (dz == (uint32) -1) + dz = td->td_imagedepth; + if (dx != 0 && dy != 0 && dz != 0) { + uint32 xpt = TIFFhowmany(td->td_imagewidth, dx); + uint32 ypt = TIFFhowmany(td->td_imagelength, dy); + uint32 zpt = TIFFhowmany(td->td_imagedepth, dz); + + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + tile = (xpt*ypt*zpt)*s + + (xpt*ypt)*(z/dz) + + xpt*(y/dy) + + x/dx; + else + tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx + s; + } + return (tile); +} + +/* + * Check an (x,y,z,s) coordinate + * against the image bounds. + */ +int +TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t s) +{ + TIFFDirectory *td = &tif->tif_dir; + + if (x >= td->td_imagewidth) { + TIFFError(tif->tif_name, "Col %ld out of range, max %lu", + (long) x, (u_long) td->td_imagewidth); + return (0); + } + if (y >= td->td_imagelength) { + TIFFError(tif->tif_name, "Row %ld out of range, max %lu", + (long) y, (u_long) td->td_imagelength); + return (0); + } + if (z >= td->td_imagedepth) { + TIFFError(tif->tif_name, "Depth %ld out of range, max %lu", + (long) z, (u_long) td->td_imagedepth); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && + s >= td->td_samplesperpixel) { + TIFFError(tif->tif_name, "Sample %d out of range, max %u", + (int) s, td->td_samplesperpixel); + return (0); + } + return (1); +} + +/* + * Compute how many tiles are in an image. + */ +ttile_t +TIFFNumberOfTiles(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + uint32 dx = td->td_tilewidth; + uint32 dy = td->td_tilelength; + uint32 dz = td->td_tiledepth; + ttile_t ntiles; + + if (dx == (uint32) -1) + dx = td->td_imagewidth; + if (dy == (uint32) -1) + dy = td->td_imagelength; + if (dz == (uint32) -1) + dz = td->td_imagedepth; + ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : + (TIFFhowmany(td->td_imagewidth, dx) * + TIFFhowmany(td->td_imagelength, dy) * + TIFFhowmany(td->td_imagedepth, dz)); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + ntiles *= td->td_samplesperpixel; + return (ntiles); +} + +/* + * Compute the # bytes in each row of a tile. + */ +tsize_t +TIFFTileRowSize(TIFF* tif) +{ + TIFFDirectory *td = &tif->tif_dir; + tsize_t rowsize; + + if (td->td_tilelength == 0 || td->td_tilewidth == 0) + return ((tsize_t) 0); + rowsize = td->td_bitspersample * td->td_tilewidth; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + rowsize *= td->td_samplesperpixel; + return ((tsize_t) TIFFhowmany(rowsize, 8)); +} + +/* + * Compute the # bytes in a variable length, row-aligned tile. + */ +tsize_t +TIFFVTileSize(TIFF* tif, uint32 nrows) +{ + TIFFDirectory *td = &tif->tif_dir; + tsize_t tilesize; + + if (td->td_tilelength == 0 || td->td_tilewidth == 0 || + td->td_tiledepth == 0) + return ((tsize_t) 0); +#ifdef YCBCR_SUPPORT + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + td->td_photometric == PHOTOMETRIC_YCBCR && + !isUpSampled(tif)) { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + tsize_t w = + TIFFroundup(td->td_tilewidth, td->td_ycbcrsubsampling[0]); + tsize_t rowsize = TIFFhowmany(w*td->td_bitspersample, 8); + tsize_t samplingarea = + td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; + nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); + /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ + tilesize = nrows*rowsize + 2*(nrows*rowsize / samplingarea); + } else +#endif + tilesize = nrows * TIFFTileRowSize(tif); + return ((tsize_t)(tilesize * td->td_tiledepth)); +} + +/* + * Compute the # bytes in a row-aligned tile. + */ +tsize_t +TIFFTileSize(TIFF* tif) +{ + return (TIFFVTileSize(tif, tif->tif_dir.td_tilelength)); +} + +/* + * Compute a default tile size based on the image + * characteristics and a requested value. If a + * request is <1 then we choose a size according + * to certain heuristics. + */ +void +TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +{ + (*tif->tif_deftilesize)(tif, tw, th); +} + +void +_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th) +{ + (void) tif; + if (*(int32*) tw < 1) + *tw = 256; + if (*(int32*) th < 1) + *th = 256; + /* roundup to a multiple of 16 per the spec */ + if (*tw & 0xf) + *tw = TIFFroundup(*tw, 16); + if (*th & 0xf) + *th = TIFFroundup(*th, 16); +} diff --git a/libtiff/tif_unix.c b/libtiff/tif_unix.c new file mode 100644 index 00000000..3f49a06f --- /dev/null +++ b/libtiff/tif_unix.c @@ -0,0 +1,209 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_unix.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library UNIX-specific Routines. + */ +#include "tiffiop.h" +#include +#include +#include + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return ((tsize_t) read((int) fd, buf, (size_t) size)); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return ((tsize_t) write((int) fd, buf, (size_t) size)); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + return ((toff_t) lseek((int) fd, (off_t) off, whence)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (close((int) fd)); +} + +#include + +static toff_t +_tiffSizeProc(thandle_t fd) +{ +#ifdef _AM29K + long fsize; + return ((fsize = lseek((int) fd, 0, SEEK_END)) < 0 ? 0 : fsize); +#else + struct stat sb; + return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size); +#endif +} + +#ifdef HAVE_MMAP +#include + +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + toff_t size = _tiffSizeProc(fd); + if (size != (toff_t) -1) { + *pbase = (tdata_t) + mmap(0, size, PROT_READ, MAP_SHARED, (int) fd, 0); + if (*pbase != (tdata_t) -1) { + *psize = size; + return (1); + } + } + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ + (void) fd; + (void) munmap(base, (off_t) size); +} +#else /* !HAVE_MMAP */ +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + (void) fd; (void) pbase; (void) psize; + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ + (void) fd; (void) base; (void) size; +} +#endif /* !HAVE_MMAP */ + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); +#ifdef _AM29K + fd = open(name, m); +#else + fd = open(name, m, 0666); +#endif + if (fd < 0) { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF *)0); + } + return (TIFFFdOpen(fd, name, mode)); +} + +void* +_TIFFmalloc(tsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(tdata_t p) +{ + free(p); +} + +void* +_TIFFrealloc(tdata_t p, tsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(tdata_t p, int v, tsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +static void +unixWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; + +static void +unixErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} +TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; diff --git a/libtiff/tif_version.c b/libtiff/tif_version.c new file mode 100644 index 00000000..a807ad95 --- /dev/null +++ b/libtiff/tif_version.c @@ -0,0 +1,34 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_version.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ +/* + * Copyright (c) 1992-1997 Sam Leffler + * Copyright (c) 1992-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ +#include "tiffiop.h" +#include "version.h" + +static const char TIFFVersion[] = VERSION; + +const char* +TIFFGetVersion(void) +{ + return (TIFFVersion); +} diff --git a/libtiff/tif_vms.c b/libtiff/tif_vms.c new file mode 100644 index 00000000..0b00de31 --- /dev/null +++ b/libtiff/tif_vms.c @@ -0,0 +1,588 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_vms.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library VMS-specific Routines. + */ + +#include +#include +#include "tiffiop.h" +#if !HAVE_IEEEFP +#include +#endif + +#ifdef VAXC +#define NOSHARE noshare +#else +#define NOSHARE +#endif + +#ifdef __alpha +/* Dummy entry point for backwards compatibility */ +void TIFFModeCCITTFax3(void){} +#endif + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (read((int) fd, buf, size)); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (write((int) fd, buf, size)); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + return ((toff_t) lseek((int) fd, (off_t) off, whence)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (close((int) fd)); +} + +#include + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + struct stat sb; + return (toff_t) (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size); +} + +#ifdef HAVE_MMAP +#include +#include +#include + +/* + * Table for storing information on current open sections. + * (Should really be a linked list) + */ +#define MAX_MAPPED 100 +static int no_mapped = 0; +static struct { + char *base; + char *top; + unsigned short channel; +} map_table[MAX_MAPPED]; + +/* + * This routine maps a file into a private section. Note that this + * method of accessing a file is by far the fastest under VMS. + * The routine may fail (i.e. return 0) for several reasons, for + * example: + * - There is no more room for storing the info on sections. + * - The process is out of open file quota, channels, ... + * - fd does not describe an opened file. + * - The file is already opened for write access by this process + * or another process + * - There is no free "hole" in virtual memory that fits the + * size of the file + */ +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + char name[256]; + struct FAB fab; + unsigned short channel; + char *inadr[2], *retadr[2]; + unsigned long status; + long size; + + if (no_mapped >= MAX_MAPPED) + return(0); + /* + * We cannot use a file descriptor, we + * must open the file once more. + */ + if (getname((int)fd, name, 1) == NULL) + return(0); + /* prepare the FAB for a user file open */ + fab = cc$rms_fab; + fab.fab$l_fop |= FAB$V_UFO; + fab.fab$b_fac = FAB$M_GET; + fab.fab$b_shr = FAB$M_SHRGET; + fab.fab$l_fna = name; + fab.fab$b_fns = strlen(name); + status = sys$open(&fab); /* open file & get channel number */ + if ((status&1) == 0) + return(0); + channel = (unsigned short)fab.fab$l_stv; + inadr[0] = inadr[1] = (char *)0; /* just an address in P0 space */ + /* + * Map the blocks of the file up to + * the EOF block into virtual memory. + */ + size = _tiffSizeProc(fd); + status = sys$crmpsc(inadr, retadr, 0, SEC$M_EXPREG, 0,0,0, channel, + TIFFhowmany(size,512), 0,0,0); + if ((status&1) == 0){ + sys$dassgn(channel); + return(0); + } + *pbase = (tdata_t) retadr[0]; /* starting virtual address */ + /* + * Use the size of the file up to the + * EOF mark for UNIX compatibility. + */ + *psize = (toff_t) size; + /* Record the section in the table */ + map_table[no_mapped].base = retadr[0]; + map_table[no_mapped].top = retadr[1]; + map_table[no_mapped].channel = channel; + no_mapped++; + + return(1); +} + +/* + * This routine unmaps a section from the virtual address space of + * the process, but only if the base was the one returned from a + * call to TIFFMapFileContents. + */ +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ + char *inadr[2]; + int i, j; + + /* Find the section in the table */ + for (i = 0;i < no_mapped; i++) { + if (map_table[i].base == (char *) base) { + /* Unmap the section */ + inadr[0] = (char *) base; + inadr[1] = map_table[i].top; + sys$deltva(inadr, 0, 0); + sys$dassgn(map_table[i].channel); + /* Remove this section from the list */ + for (j = i+1; j < no_mapped; j++) + map_table[j-1] = map_table[j]; + no_mapped--; + return; + } + } +} +#else /* !HAVE_MMAP */ +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ +} +#endif /* !HAVE_MMAP */ + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, + _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); + if (m&O_TRUNC){ + /* + * There is a bug in open in VAXC. If you use + * open w/ m=O_RDWR|O_CREAT|O_TRUNC the + * wrong thing happens. On the other hand + * creat does the right thing. + */ + fd = creat((char *) /* bug in stdio.h */ name, 0666, + "alq = 128", "deq = 64", "mbc = 32", + "fop = tef"); + } else if (m&O_RDWR) { + fd = open(name, m, 0666, + "deq = 64", "mbc = 32", "fop = tef", "ctx = stm"); + } else + fd = open(name, m, 0666, "mbc = 32", "ctx = stm"); + if (fd < 0) { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF*)0); + } + return (TIFFFdOpen(fd, name, mode)); +} + +tdata_t +_TIFFmalloc(tsize_t s) +{ + return (malloc((size_t) s)); +} + +void +_TIFFfree(tdata_t p) +{ + free(p); +} + +tdata_t +_TIFFrealloc(tdata_t p, tsize_t s) +{ + return (realloc(p, (size_t) s)); +} + +void +_TIFFmemset(tdata_t p, int v, tsize_t c) +{ + memset(p, v, (size_t) c); +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +{ + memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + return (memcmp(p1, p2, (size_t) c)); +} + +/* + * On the VAX, we need to make those global, writable pointers + * non-shareable, otherwise they would be made shareable by default. + * On the AXP, this brain damage has been corrected. + * + * I (Karsten Spang, krs@kampsax.dk) have dug around in the GCC + * manual and the GAS code and have come up with the following + * construct, but I don't have GCC on my VAX, so it is untested. + * Please tell me if it does not work. + */ + +static void +vmsWarningHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} + +NOSHARE TIFFErrorHandler _TIFFwarningHandler = vmsWarningHandler +#if defined(VAX) && defined(__GNUC__) +asm("_$$PsectAttributes_NOSHR$$_TIFFwarningHandler") +#endif +; + +static void +vmsErrorHandler(const char* module, const char* fmt, va_list ap) +{ + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); +} + +NOSHARE TIFFErrorHandler _TIFFerrorHandler = vmsErrorHandler +#if defined(VAX) && defined(__GNUC__) +asm("_$$PsectAttributes_NOSHR$$_TIFFerrorHandler") +#endif +; + + +#if !HAVE_IEEEFP +/* IEEE floting point handling */ + +typedef struct ieeedouble { + u_long mant2; /* fix NDR: full 8-byte swap */ + u_long mant : 20, + exp : 11, + sign : 1; +} ieeedouble; +typedef struct ieeefloat { + u_long mant : 23, + exp : 8, + sign : 1; +} ieeefloat; + +/* + * NB: These are D_FLOAT's, not G_FLOAT's. A G_FLOAT is + * simply a reverse-IEEE float/double. + */ + +typedef struct { + u_long mant1 : 7, + exp : 8, + sign : 1, + mant2 : 16, + mant3 : 16, + mant4 : 16; +} nativedouble; +typedef struct { + u_long mant1 : 7, + exp : 8, + sign : 1, + mant2 : 16; +} nativefloat; + +typedef union { + ieeedouble ieee; + nativedouble native; + char b[8]; + uint32 l[2]; + double d; +} double_t; + +typedef union { + ieeefloat ieee; + nativefloat native; + char b[4]; + uint32 l; + float f; +} float_t; + +#if defined(VAXC) || defined(DECC) +#pragma inline(ieeetod,dtoieee) +#endif + +/* + * Convert an IEEE double precision number to native double precision. + * The source is contained in two longwords, the second holding the sign, + * exponent and the higher order bits of the mantissa, and the first + * holding the rest of the mantissa as follows: + * (Note: It is assumed that the number has been eight-byte swapped to + * LSB first.) + * + * First longword: + * 32 least significant bits of mantissa + * Second longword: + * 0-19: 20 most significant bits of mantissa + * 20-30: exponent + * 31: sign + * The exponent is stored as excess 1023. + * The most significant bit of the mantissa is implied 1, and not stored. + * If the exponent and mantissa are zero, the number is zero. + * If the exponent is 0 (i.e. -1023) and the mantissa is non-zero, it is an + * unnormalized number with the most significant bit NOT implied. + * If the exponent is 2047, the number is invalid, in case the mantissa is zero, + * this means overflow (+/- depending of the sign bit), otherwise + * it simply means invalid number. + * + * If the number is too large for the machine or was specified as overflow, + * +/-HUGE_VAL is returned. + */ +INLINE static void +ieeetod(double *dp) +{ + double_t source; + long sign,exp,mant; + double dmant; + + source.ieee = ((double_t*)dp)->ieee; + sign = source.ieee.sign; + exp = source.ieee.exp; + mant = source.ieee.mant; + + if (exp == 2047) { + if (mant) /* Not a Number (NAN) */ + *dp = HUGE_VAL; + else /* +/- infinity */ + *dp = (sign ? -HUGE_VAL : HUGE_VAL); + return; + } + if (!exp) { + if (!(mant || source.ieee.mant2)) { /* zero */ + *dp=0; + return; + } else { /* Unnormalized number */ + /* NB: not -1023, the 1 bit is not implied */ + exp= -1022; + } + } else { + mant |= 1<<20; + exp -= 1023; + } + dmant = (((double) mant) + + ((double) source.ieee.mant2) / (((double) (1<<16)) * + ((double) (1<<16)))) / (double) (1<<20); + dmant = ldexp(dmant, exp); + if (sign) + dmant= -dmant; + *dp = dmant; +} + +INLINE static void +dtoieee(double *dp) +{ + double_t num; + double x; + int exp; + + num.d = *dp; + if (!num.d) { /* Zero is just binary all zeros */ + num.l[0] = num.l[1] = 0; + return; + } + + if (num.d < 0) { /* Sign is encoded separately */ + num.d = -num.d; + num.ieee.sign = 1; + } else { + num.ieee.sign = 0; + } + + /* Now separate the absolute value into mantissa and exponent */ + x = frexp(num.d, &exp); + + /* + * Handle cases where the value is outside the + * range for IEEE floating point numbers. + * (Overflow cannot happen on a VAX, but underflow + * can happen for G float.) + */ + if (exp < -1022) { /* Unnormalized number */ + x = ldexp(x, -1023-exp); + exp = 0; + } else if (exp > 1023) { /* +/- infinity */ + x = 0; + exp = 2047; + } else { /* Get rid of most significant bit */ + x *= 2; + x -= 1; + exp += 1022; /* fix NDR: 1.0 -> x=0.5, exp=1 -> ieee.exp = 1023 */ + } + num.ieee.exp = exp; + + x *= (double) (1<<20); + num.ieee.mant = (long) x; + x -= (double) num.ieee.mant; + num.ieee.mant2 = (long) (x*((double) (1<<16)*(double) (1<<16))); + + if (!(num.ieee.mant || num.ieee.exp || num.ieee.mant2)) { + /* Avoid negative zero */ + num.ieee.sign = 0; + } + ((double_t*)dp)->ieee = num.ieee; +} + +/* + * Beware, these do not handle over/under-flow + * during conversion from ieee to native format. + */ +#define NATIVE2IEEEFLOAT(fp) { \ + float_t t; \ + if (t.ieee.exp = (fp)->native.exp) \ + t.ieee.exp += -129 + 127; \ + t.ieee.sign = (fp)->native.sign; \ + t.ieee.mant = ((fp)->native.mant1<<16)|(fp)->native.mant2; \ + *(fp) = t; \ +} +#define IEEEFLOAT2NATIVE(fp) { \ + float_t t; int v = (fp)->ieee.exp; \ + if (v) v += -127 + 129; /* alter bias of exponent */\ + t.native.exp = v; /* implicit truncation of exponent */\ + t.native.sign = (fp)->ieee.sign; \ + v = (fp)->ieee.mant; \ + t.native.mant1 = v >> 16; \ + t.native.mant2 = v;\ + *(fp) = t; \ +} + +#define IEEEDOUBLE2NATIVE(dp) ieeetod(dp) + +#define NATIVE2IEEEDOUBLE(dp) dtoieee(dp) + + +/* + * These unions are used during floating point + * conversions. The above macros define the + * conversion operations. + */ +void +TIFFCvtIEEEFloatToNative(TIFF* tif, u_int n, float* f) +{ + float_t* fp = (float_t*) f; + + while (n-- > 0) { + IEEEFLOAT2NATIVE(fp); + fp++; + } +} + +void +TIFFCvtNativeToIEEEFloat(TIFF* tif, u_int n, float* f) +{ + float_t* fp = (float_t*) f; + + while (n-- > 0) { + NATIVE2IEEEFLOAT(fp); + fp++; + } +} +void +TIFFCvtIEEEDoubleToNative(TIFF* tif, u_int n, double* f) +{ + double_t* fp = (double_t*) f; + + while (n-- > 0) { + IEEEDOUBLE2NATIVE(fp); + fp++; + } +} + +void +TIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, double* f) +{ + double_t* fp = (double_t*) f; + + while (n-- > 0) { + NATIVE2IEEEDOUBLE(fp); + fp++; + } +} +#endif diff --git a/libtiff/tif_warning.c b/libtiff/tif_warning.c new file mode 100644 index 00000000..7f16cbeb --- /dev/null +++ b/libtiff/tif_warning.c @@ -0,0 +1,49 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + */ +#include "tiffiop.h" + +TIFFErrorHandler +TIFFSetWarningHandler(TIFFErrorHandler handler) +{ + TIFFErrorHandler prev = _TIFFwarningHandler; + _TIFFwarningHandler = handler; + return (prev); +} + +void +TIFFWarning(const char* module, const char* fmt, ...) +{ + if (_TIFFwarningHandler) { + va_list ap; + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } +} diff --git a/libtiff/tif_win3.c b/libtiff/tif_win3.c new file mode 100644 index 00000000..0ec9dda2 --- /dev/null +++ b/libtiff/tif_win3.c @@ -0,0 +1,225 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_win3.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library Windows 3.x-specific Routines. + */ +#include "tiffiop.h" +#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER) +#include /* for open, close, etc. function prototypes */ +#endif + +#include +#include +#include + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (_hread(fd, buf, size)); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + return (_hwrite(fd, buf, size)); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + return (_llseek(fd, (off_t) off, whence)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (_lclose(fd)); +} + +#include + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + struct stat sb; + return (fstat((int) fd, &sb) < 0 ? 0 : sb.st_size); +} + +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + return (0); +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ +} + +/* + * Open a TIFF file descriptor for read/writing. + */ +TIFF* +TIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF* tif; + + tif = TIFFClientOpen(name, mode, + (thandle_t) fd, + _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, + _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); + if (tif) + tif->tif_fd = fd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + int m, fd; + OFSTRUCT of; + int mm = 0; + + m = _TIFFgetMode(mode, module); + if (m == -1) + return ((TIFF*)0); + if (m & O_CREAT) { + if ((m & O_TRUNC) || OpenFile(name, &of, OF_EXIST) != HFILE_ERROR) + mm |= OF_CREATE; + } + if (m & O_WRONLY) + mm |= OF_WRITE; + if (m & O_RDWR) + mm |= OF_READWRITE; + fd = OpenFile(name, &of, mm); + if (fd < 0) { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF*)0); + } + return (TIFFFdOpen(fd, name, mode)); +} + +tdata_t +_TIFFmalloc(tsize_t s) +{ + return (tdata_t) GlobalAllocPtr(GHND, (DWORD) s); +} + +void +_TIFFfree(tdata_t p) +{ + GlobalFreePtr(p); +} + +tdata_t +_TIFFrealloc(tdata_t p, tsize_t s) +{ + return (tdata_t) GlobalReAllocPtr(p, (DWORD) s, GHND); +} + +void +_TIFFmemset(tdata_t p, int v, tsize_t c) +{ + char* pp = (char*) p; + + while (c > 0) { + tsize_t chunk = 0x10000 - ((uint32) pp & 0xffff);/* What's left in segment */ + if (chunk > 0xff00) /* No more than 0xff00 */ + chunk = 0xff00; + if (chunk > c) /* No more than needed */ + chunk = c; + memset(pp, v, chunk); + pp = (char*) (chunk + (char huge*) pp); + c -= chunk; + } +} + +void +_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) +{ + if (c > 0xFFFF) + hmemcpy((void _huge*) d, (void _huge*) s, c); + else + (void) memcpy(d, s, (size_t) c); +} + +int +_TIFFmemcmp(const tdata_t d, const tdata_t s, tsize_t c) +{ + char* dd = (char*) d; + char* ss = (char*) s; + tsize_t chunks, chunkd, chunk; + int result; + + while (c > 0) { + chunks = 0x10000 - ((uint32) ss & 0xffff); /* What's left in segment */ + chunkd = 0x10000 - ((uint32) dd & 0xffff); /* What's left in segment */ + chunk = c; /* Get the largest of */ + if (chunk > chunks) /* c, chunks, chunkd, */ + chunk = chunks; /* 0xff00 */ + if (chunk > chunkd) + chunk = chunkd; + if (chunk > 0xff00) + chunk = 0xff00; + result = memcmp(dd, ss, chunk); + if (result != 0) + return (result); + dd = (char*) (chunk + (char huge*) dd); + ss = (char*) (chunk + (char huge*) ss); + c -= chunk; + } + return (0); +} + +static void +win3WarningHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + if (module != NULL) + strcat(strcpy(e, module), ":"); + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + MessageBox(GetActiveWindow(), e, "LibTIFF Warning", + MB_OK|MB_ICONEXCLAMATION); +} +TIFFErrorHandler _TIFFwarningHandler = win3WarningHandler; + +static void +win3ErrorHandler(const char* module, const char* fmt, va_list ap) +{ + char e[512] = { '\0' }; + if (module != NULL) + strcat(strcpy(e, module), ":"); + vsprintf(e+strlen(e), fmt, ap); + strcat(e, "."); + MessageBox(GetActiveWindow(), e, "LibTIFF Error", MB_OK|MB_ICONSTOP); +} +TIFFErrorHandler _TIFFerrorHandler = win3ErrorHandler; diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c new file mode 100644 index 00000000..9476dc36 --- /dev/null +++ b/libtiff/tif_win32.c @@ -0,0 +1,288 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_win32.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by + * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA + */ +#include +#include "tiffiop.h" + +static tsize_t +_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + DWORD dwSizeRead; + if (!ReadFile(fd, buf, size, &dwSizeRead, NULL)) + return(0); + return ((tsize_t) dwSizeRead); +} + +static tsize_t +_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + DWORD dwSizeWritten; + if (!WriteFile(fd, buf, size, &dwSizeWritten, NULL)) + return(0); + return ((tsize_t) dwSizeWritten); +} + +static toff_t +_tiffSeekProc(thandle_t fd, toff_t off, int whence) +{ + DWORD dwMoveMethod; + switch(whence) + { + case 0: + dwMoveMethod = FILE_BEGIN; + break; + case 1: + dwMoveMethod = FILE_CURRENT; + break; + case 2: + dwMoveMethod = FILE_END; + break; + default: + dwMoveMethod = FILE_BEGIN; + break; + } + return ((toff_t)SetFilePointer(fd, off, NULL, dwMoveMethod)); +} + +static int +_tiffCloseProc(thandle_t fd) +{ + return (CloseHandle(fd) ? 0 : -1); +} + +static toff_t +_tiffSizeProc(thandle_t fd) +{ + return ((toff_t)GetFileSize(fd, NULL)); +} + +#pragma argsused +static int +_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + return (0); +} + +/* + * From "Hermann Josef Hill" : + * + * Windows uses both a handle and a pointer for file mapping, + * but according to the SDK documentation and Richter's book + * "Advanced Windows Programming" it is safe to free the handle + * after obtaining the file mapping pointer + * + * This removes a nasty OS dependency and cures a problem + * with Visual C++ 5.0 + */ +static int +_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) +{ + toff_t size; + HANDLE hMapFile; + + if ((size = _tiffSizeProc(fd)) == (toff_t)-1) + return (0); + hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL); + if (hMapFile == NULL) + return (0); + *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); + CloseHandle(hMapFile); + if (*pbase == NULL) + return (0); + *psize = size; + return(1); +} + +#pragma argsused +static void +_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ +} + +static void +_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) +{ + UnmapViewOfFile(base); +} + +/* + * Open a TIFF file descriptor for read/writing. + * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode + * string, which forces the file to be opened unmapped. + */ +TIFF* +TIFFFdOpen(int ifd, const char* name, const char* mode) +{ + TIFF* tif; + BOOL fSuppressMap = (mode[1] == 'u' || mode[2] == 'u'); + + tif = TIFFClientOpen(name, mode, + (thandle_t)ifd, + _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, + fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); + if (tif) + tif->tif_fd = ifd; + return (tif); +} + +/* + * Open a TIFF file for read/writing. + */ +TIFF* +TIFFOpen(const char* name, const char* mode) +{ + static const char module[] = "TIFFOpen"; + thandle_t fd; + int m; + DWORD dwMode; + + m = _TIFFgetMode(mode, module); + + switch(m) + { + case O_RDONLY: + dwMode = OPEN_EXISTING; + break; + case O_RDWR: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR|O_CREAT: + dwMode = CREATE_NEW; + break; + case O_RDWR|O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + case O_RDWR|O_CREAT|O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + default: + return ((TIFF*)0); + } + fd = (thandle_t)CreateFile(name, (m == O_RDONLY) ? GENERIC_READ : + (GENERIC_READ | GENERIC_WRITE), FILE_SHARE_READ, NULL, dwMode, + (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, NULL); + if (fd == INVALID_HANDLE_VALUE) { + TIFFError(module, "%s: Cannot open", name); + return ((TIFF *)0); + } + return (TIFFFdOpen((int)fd, name, mode)); +} + +tdata_t +_TIFFmalloc(tsize_t s) +{ + return ((tdata_t)GlobalAlloc(GMEM_FIXED, s)); +} + +void +_TIFFfree(tdata_t p) +{ + GlobalFree(p); + return; +} + +tdata_t +_TIFFrealloc(tdata_t p, tsize_t s) +{ + void* pvTmp; + if ((pvTmp = GlobalReAlloc(p, s, 0)) == NULL) { + if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) { + CopyMemory(pvTmp, p, GlobalSize(p)); + GlobalFree(p); + } + } + return ((tdata_t)pvTmp); +} + +void +_TIFFmemset(void* p, int v, tsize_t c) +{ + FillMemory(p, c, (BYTE)v); +} + +void +_TIFFmemcpy(void* d, const tdata_t s, tsize_t c) +{ + CopyMemory(d, s, c); +} + +int +_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) +{ + register const BYTE *pb1 = p1; + register const BYTE *pb2 = p2; + register DWORD dwTmp = c; + register int iTmp; + for (iTmp = 0; dwTmp-- && !iTmp; iTmp = (int)*pb1++ - (int)*pb2++) + ; + return (iTmp); +} + +static void +Win32WarningHandler(const char* module, const char* fmt, va_list ap) +{ + LPTSTR szTitle; + LPTSTR szTmp; + LPCTSTR szTitleText = "%s Warning"; + LPCTSTR szDefaultModule = "TIFFLIB"; + szTmp = (module == NULL) ? (LPTSTR)szDefaultModule : (LPTSTR)module; + if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (lstrlen(szTmp) + + lstrlen(szTitleText) + lstrlen(fmt) + 128)*sizeof(TCHAR))) == NULL) + return; + wsprintf(szTitle, szTitleText, szTmp); + szTmp = szTitle + (lstrlen(szTitle)+2)*sizeof(TCHAR); + wvsprintf(szTmp, fmt, ap); + MessageBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION); + LocalFree(szTitle); + return; +} +TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; + +static void +Win32ErrorHandler(const char* module, const char* fmt, va_list ap) +{ + LPTSTR szTitle; + LPTSTR szTmp; + LPCTSTR szTitleText = "%s Error"; + LPCTSTR szDefaultModule = "TIFFLIB"; + szTmp = (module == NULL) ? (LPTSTR)szDefaultModule : (LPTSTR)module; + if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (lstrlen(szTmp) + + lstrlen(szTitleText) + lstrlen(fmt) + 128)*sizeof(TCHAR))) == NULL) + return; + wsprintf(szTitle, szTitleText, szTmp); + szTmp = szTitle + (lstrlen(szTitle)+2)*sizeof(TCHAR); + wvsprintf(szTmp, fmt, ap); + MessageBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION); + LocalFree(szTitle); + return; +} +TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c new file mode 100644 index 00000000..8d725892 --- /dev/null +++ b/libtiff/tif_write.c @@ -0,0 +1,628 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_write.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * TIFF Library. + * + * Scanline-oriented Write Support + */ +#include "tiffiop.h" +#include +#include + +#define STRIPINCR 20 /* expansion factor on strip array */ + +#define WRITECHECKSTRIPS(tif, module) \ + (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) +#define WRITECHECKTILES(tif, module) \ + (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) +#define BUFFERCHECK(tif) \ + (((tif)->tif_flags & TIFF_BUFFERSETUP) || \ + TIFFWriteBufferSetup((tif), NULL, (tsize_t) -1)) + +static int TIFFWriteCheck(TIFF*, int, const char*); +static int TIFFGrowStrips(TIFF*, int, const char*); +static int TIFFAppendToStrip(TIFF*, tstrip_t, tidata_t, tsize_t); +static int TIFFSetupStrips(TIFF*); + +int +TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) +{ + static const char module[] = "TIFFWriteScanline"; + register TIFFDirectory *td; + int status, imagegrew = 0; + tstrip_t strip; + + if (!WRITECHECKSTRIPS(tif, module)) + return (-1); + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return (-1); + td = &tif->tif_dir; + /* + * Extend image length if needed + * (but only for PlanarConfig=1). + */ + if (row >= td->td_imagelength) { /* extend image */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + TIFFError(tif->tif_name, + "Can not change \"ImageLength\" when using separate planes"); + return (-1); + } + td->td_imagelength = row+1; + imagegrew = 1; + } + /* + * Calculate strip and check for crossings. + */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + if (sample >= td->td_samplesperpixel) { + TIFFError(tif->tif_name, + "%d: Sample out of range, max %d", + sample, td->td_samplesperpixel); + return (-1); + } + strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; + } else + strip = row / td->td_rowsperstrip; + if (strip != tif->tif_curstrip) { + /* + * Changing strips -- flush any data present. + */ + if (!TIFFFlushData(tif)) + return (-1); + tif->tif_curstrip = strip; + /* + * Watch out for a growing image. The value of + * strips/image will initially be 1 (since it + * can't be deduced until the imagelength is known). + */ + if (strip >= td->td_stripsperimage && imagegrew) + td->td_stripsperimage = + TIFFhowmany(td->td_imagelength,td->td_rowsperstrip); + tif->tif_row = + (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupencode)(tif)) + return (-1); + tif->tif_flags |= TIFF_CODERSETUP; + } + if (!(*tif->tif_preencode)(tif, sample)) + return (-1); + tif->tif_flags |= TIFF_POSTENCODE; + } + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) + return (-1); + /* + * Ensure the write is either sequential or at the + * beginning of a strip (or that we can randomly + * access the data -- i.e. no encoding). + */ + if (row != tif->tif_row) { + if (row < tif->tif_row) { + /* + * Moving backwards within the same strip: + * backup to the start and then decode + * forward (below). + */ + tif->tif_row = (strip % td->td_stripsperimage) * + td->td_rowsperstrip; + tif->tif_rawcp = tif->tif_rawdata; + } + /* + * Seek forward to the desired row. + */ + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (-1); + tif->tif_row = row; + } + status = (*tif->tif_encoderow)(tif, (tidata_t) buf, + tif->tif_scanlinesize, sample); + tif->tif_row++; + return (status); +} + +/* + * Encode the supplied data and write it to the + * specified strip. There must be space for the + * data; we don't check if strips overlap! + * + * NB: Image length must be setup before writing. + */ +tsize_t +TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) +{ + static const char module[] = "TIFFWriteEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + tsample_t sample; + + if (!WRITECHECKSTRIPS(tif, module)) + return ((tsize_t) -1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + TIFFError(tif->tif_name, + "Can not grow image by strips when using separate planes"); + return ((tsize_t) -1); + } + if (!TIFFGrowStrips(tif, 1, module)) + return ((tsize_t) -1); + td->td_stripsperimage = + TIFFhowmany(td->td_imagelength, td->td_rowsperstrip); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized according to the directory + * info. + */ + if (!BUFFERCHECK(tif)) + return ((tsize_t) -1); + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupencode)(tif)) + return ((tsize_t) -1); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_flags &= ~TIFF_POSTENCODE; + sample = (tsample_t)(strip / td->td_stripsperimage); + if (!(*tif->tif_preencode)(tif, sample)) + return ((tsize_t) -1); + if (!(*tif->tif_encodestrip)(tif, (tidata_t) data, cc, sample)) + return ((tsize_t) 0); + if (!(*tif->tif_postencode)(tif)) + return ((tsize_t) -1); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && + !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) + return ((tsize_t) -1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); +} + +/* + * Write the supplied data to the specified strip. + * There must be space for the data; we don't check + * if strips overlap! + * + * NB: Image length must be setup before writing. + */ +tsize_t +TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc) +{ + static const char module[] = "TIFFWriteRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + + if (!WRITECHECKSTRIPS(tif, module)) + return ((tsize_t) -1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { + TIFFError(tif->tif_name, + "Can not grow image by strips when using separate planes"); + return ((tsize_t) -1); + } + /* + * Watch out for a growing image. The value of + * strips/image will initially be 1 (since it + * can't be deduced until the imagelength is known). + */ + if (strip >= td->td_stripsperimage) + td->td_stripsperimage = + TIFFhowmany(td->td_imagelength,td->td_rowsperstrip); + if (!TIFFGrowStrips(tif, 1, module)) + return ((tsize_t) -1); + } + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + return (TIFFAppendToStrip(tif, strip, (tidata_t) data, cc) ? + cc : (tsize_t) -1); +} + +/* + * Write and compress a tile of data. The + * tile is selected by the (x,y,z,s) coordinates. + */ +tsize_t +TIFFWriteTile(TIFF* tif, + tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s) +{ + if (!TIFFCheckTile(tif, x, y, z, s)) + return (-1); + /* + * NB: A tile size of -1 is used instead of tif_tilesize knowing + * that TIFFWriteEncodedTile will clamp this to the tile size. + * This is done because the tile size may not be defined until + * after the output buffer is setup in TIFFWriteBufferSetup. + */ + return (TIFFWriteEncodedTile(tif, + TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1)); +} + +/* + * Encode the supplied data and write it to the + * specified tile. There must be space for the + * data. The function clamps individual writes + * to a tile to the tile size, but does not (and + * can not) check that multiple writes to the same + * tile do not write more than tile size data. + * + * NB: Image length must be setup before writing; this + * interface does not support automatically growing + * the image on each write (as TIFFWriteScanline does). + */ +tsize_t +TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) +{ + static const char module[] = "TIFFWriteEncodedTile"; + TIFFDirectory *td; + tsample_t sample; + + if (!WRITECHECKTILES(tif, module)) + return ((tsize_t) -1); + td = &tif->tif_dir; + if (tile >= td->td_nstrips) { + TIFFError(module, "%s: Tile %lu out of range, max %lu", + tif->tif_name, (u_long) tile, (u_long) td->td_nstrips); + return ((tsize_t) -1); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return ((tsize_t) -1); + tif->tif_curtile = tile; + /* + * Compute tiles per row & per column to compute + * current row and column + */ + tif->tif_row = (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) + * td->td_tilelength; + tif->tif_col = (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) + * td->td_tilewidth; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { + if (!(*tif->tif_setupencode)(tif)) + return ((tsize_t) -1); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_flags &= ~TIFF_POSTENCODE; + sample = (tsample_t)(tile/td->td_stripsperimage); + if (!(*tif->tif_preencode)(tif, sample)) + return ((tsize_t) -1); + /* + * Clamp write amount to the tile size. This is mostly + * done so that callers can pass in some large number + * (e.g. -1) and have the tile size used instead. + */ + if ((uint32) cc > tif->tif_tilesize) + cc = tif->tif_tilesize; + if (!(*tif->tif_encodetile)(tif, (tidata_t) data, cc, sample)) + return ((tsize_t) 0); + if (!(*tif->tif_postencode)(tif)) + return ((tsize_t) -1); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((u_char *)tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, + tif->tif_rawdata, tif->tif_rawcc)) + return ((tsize_t) -1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); +} + +/* + * Write the supplied data to the specified strip. + * There must be space for the data; we don't check + * if strips overlap! + * + * NB: Image length must be setup before writing; this + * interface does not support automatically growing + * the image on each write (as TIFFWriteScanline does). + */ +tsize_t +TIFFWriteRawTile(TIFF* tif, ttile_t tile, tdata_t data, tsize_t cc) +{ + static const char module[] = "TIFFWriteRawTile"; + + if (!WRITECHECKTILES(tif, module)) + return ((tsize_t) -1); + if (tile >= tif->tif_dir.td_nstrips) { + TIFFError(module, "%s: Tile %lu out of range, max %lu", + tif->tif_name, (u_long) tile, + (u_long) tif->tif_dir.td_nstrips); + return ((tsize_t) -1); + } + return (TIFFAppendToStrip(tif, tile, (tidata_t) data, cc) ? + cc : (tsize_t) -1); +} + +#define isUnspecified(tif, f) \ + (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) + +static int +TIFFSetupStrips(TIFF* tif) +{ + TIFFDirectory* td = &tif->tif_dir; + + if (isTiled(tif)) + td->td_stripsperimage = + isUnspecified(tif, FIELD_TILEDIMENSIONS) ? + td->td_samplesperpixel : TIFFNumberOfTiles(tif); + else + td->td_stripsperimage = + isUnspecified(tif, FIELD_ROWSPERSTRIP) ? + td->td_samplesperpixel : TIFFNumberOfStrips(tif); + td->td_nstrips = td->td_stripsperimage; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + td->td_stripsperimage /= td->td_samplesperpixel; + td->td_stripoffset = (uint32 *) + _TIFFmalloc(td->td_nstrips * sizeof (uint32)); + td->td_stripbytecount = (uint32 *) + _TIFFmalloc(td->td_nstrips * sizeof (uint32)); + if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) + return (0); + /* + * Place data at the end-of-file + * (by setting offsets to zero). + */ + _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint32)); + _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint32)); + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + return (1); +} +#undef isUnspecified + +/* + * Verify file is writable and that the directory + * information is setup properly. In doing the latter + * we also "freeze" the state of the directory so + * that important information is not changed. + */ +static int +TIFFWriteCheck(TIFF* tif, int tiles, const char* module) +{ + if (tif->tif_mode == O_RDONLY) { + TIFFError(module, "%s: File not open for writing", + tif->tif_name); + return (0); + } + if (tiles ^ isTiled(tif)) { + TIFFError(tif->tif_name, tiles ? + "Can not write tiles to a stripped image" : + "Can not write scanlines to a tiled image"); + return (0); + } + /* + * On the first write verify all the required information + * has been setup and initialize any data structures that + * had to wait until directory information was set. + * Note that a lot of our work is assumed to remain valid + * because we disallow any of the important parameters + * from changing after we start writing (i.e. once + * TIFF_BEENWRITING is set, TIFFSetField will only allow + * the image's length to be changed). + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { + TIFFError(module, + "%s: Must set \"ImageWidth\" before writing data", + tif->tif_name); + return (0); + } + if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) { + TIFFError(module, + "%s: Must set \"PlanarConfiguration\" before writing data", + tif->tif_name); + return (0); + } + if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) { + tif->tif_dir.td_nstrips = 0; + TIFFError(module, "%s: No space for %s arrays", + tif->tif_name, isTiled(tif) ? "tile" : "strip"); + return (0); + } + tif->tif_tilesize = TIFFTileSize(tif); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + tif->tif_flags |= TIFF_BEENWRITING; + return (1); +} + +/* + * Setup the raw data buffer used for encoding. + */ +int +TIFFWriteBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) +{ + static const char module[] = "TIFFWriteBufferSetup"; + + if (tif->tif_rawdata) { + if (tif->tif_flags & TIFF_MYBUFFER) { + _TIFFfree(tif->tif_rawdata); + tif->tif_flags &= ~TIFF_MYBUFFER; + } + tif->tif_rawdata = NULL; + } + if (size == (tsize_t) -1) { + size = (isTiled(tif) ? + tif->tif_tilesize : tif->tif_scanlinesize); + /* + * Make raw data buffer at least 8K + */ + if (size < 8*1024) + size = 8*1024; + bp = NULL; /* NB: force malloc */ + } + if (bp == NULL) { + bp = _TIFFmalloc(size); + if (bp == NULL) { + TIFFError(module, "%s: No space for output buffer", + tif->tif_name); + return (0); + } + tif->tif_flags |= TIFF_MYBUFFER; + } else + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdata = (tidata_t) bp; + tif->tif_rawdatasize = size; + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (1); +} + +/* + * Grow the strip data structures by delta strips. + */ +static int +TIFFGrowStrips(TIFF* tif, int delta, const char* module) +{ + TIFFDirectory *td = &tif->tif_dir; + + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + td->td_stripoffset = (uint32*)_TIFFrealloc(td->td_stripoffset, + (td->td_nstrips + delta) * sizeof (uint32)); + td->td_stripbytecount = (uint32*)_TIFFrealloc(td->td_stripbytecount, + (td->td_nstrips + delta) * sizeof (uint32)); + if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL) { + td->td_nstrips = 0; + TIFFError(module, "%s: No space to expand strip arrays", + tif->tif_name); + return (0); + } + _TIFFmemset(td->td_stripoffset+td->td_nstrips, 0, delta*sizeof (uint32)); + _TIFFmemset(td->td_stripbytecount+td->td_nstrips, 0, delta*sizeof (uint32)); + td->td_nstrips += delta; + return (1); +} + +/* + * Append the data to the specified strip. + * + * NB: We don't check that there's space in the + * file (i.e. that strips do not overlap). + */ +static int +TIFFAppendToStrip(TIFF* tif, tstrip_t strip, tidata_t data, tsize_t cc) +{ + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "TIFFAppendToStrip"; + + if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) { + /* + * No current offset, set the current strip. + */ + if (td->td_stripoffset[strip] != 0) { + if (!SeekOK(tif, td->td_stripoffset[strip])) { + TIFFError(module, + "%s: Seek error at scanline %lu", + tif->tif_name, (u_long) tif->tif_row); + return (0); + } + } else + td->td_stripoffset[strip] = + TIFFSeekFile(tif, (toff_t) 0, SEEK_END); + tif->tif_curoff = td->td_stripoffset[strip]; + } + if (!WriteOK(tif, data, cc)) { + TIFFError(module, "%s: Write error at scanline %lu", + tif->tif_name, (u_long) tif->tif_row); + return (0); + } + tif->tif_curoff += cc; + td->td_stripbytecount[strip] += cc; + return (1); +} + +/* + * Internal version of TIFFFlushData that can be + * called by ``encodestrip routines'' w/o concern + * for infinite recursion. + */ +int +TIFFFlushData1(TIFF* tif) +{ + if (tif->tif_rawcc > 0) { + if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((u_char *)tif->tif_rawdata, + tif->tif_rawcc); + if (!TIFFAppendToStrip(tif, + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, + tif->tif_rawdata, tif->tif_rawcc)) + return (0); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + } + return (1); +} + +/* + * Set the current write offset. This should only be + * used to set the offset to a known previous location + * (very carefully), or to 0 so that the next write gets + * appended to the end of the file. + */ +void +TIFFSetWriteOffset(TIFF* tif, toff_t off) +{ + tif->tif_curoff = off; +} diff --git a/libtiff/tif_zip.c b/libtiff/tif_zip.c new file mode 100644 index 00000000..9572b5f9 --- /dev/null +++ b/libtiff/tif_zip.c @@ -0,0 +1,367 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_zip.c,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1995-1997 Sam Leffler + * Copyright (c) 1995-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "tiffiop.h" +#ifdef ZIP_SUPPORT +/* + * TIFF Library. + * + * ZIP (aka Deflate) Compression Support + * + * This file is simply an interface to the zlib library written by + * Jean-loup Gailly and Mark Adler. You must use version 1.0 or later + * of the library: this code assumes the 1.0 API and also depends on + * the ability to write the zlib header multiple times (one per strip) + * which was not possible with versions prior to 0.95. Note also that + * older versions of this codec avoided this bug by supressing the header + * entirely. This means that files written with the old library cannot + * be read; they should be converted to a different compression scheme + * and then reconverted. + * + * The data format used by the zlib library is described in the files + * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the + * directory ftp://ftp.uu.net/pub/archiving/zip/doc. The library was + * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz. + */ +#include "tif_predict.h" +#include "zlib.h" + +#include +#include + +/* + * Sigh, ZLIB_VERSION is defined as a string so there's no + * way to do a proper check here. Instead we guess based + * on the presence of #defines that were added between the + * 0.95 and 1.0 distributions. + */ +#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED) +#error "Antiquated ZLIB software; you must use version 1.0 or later" +#endif + +/* + * State block for each open TIFF + * file using ZIP compression/decompression. + */ +typedef struct { + TIFFPredictorState predict; + z_stream stream; + int zipquality; /* compression level */ + int state; /* state flags */ +#define ZSTATE_INIT 0x1 /* zlib setup successfully */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} ZIPState; + +#define ZState(tif) ((ZIPState*) (tif)->tif_data) +#define DecoderState(tif) ZState(tif) +#define EncoderState(tif) ZState(tif) + +static int ZIPEncode(TIFF*, tidata_t, tsize_t, tsample_t); +static int ZIPDecode(TIFF*, tidata_t, tsize_t, tsample_t); + +static int +ZIPSetupDecode(TIFF* tif) +{ + ZIPState* sp = DecoderState(tif); + static const char module[] = "ZIPSetupDecode"; + + assert(sp != NULL); + if (inflateInit(&sp->stream) != Z_OK) { + TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); + return (0); + } else { + sp->state |= ZSTATE_INIT; + return (1); + } +} + +/* + * Setup state for decoding a strip. + */ +static int +ZIPPreDecode(TIFF* tif, tsample_t s) +{ + ZIPState* sp = DecoderState(tif); + + (void) s; + assert(sp != NULL); + sp->stream.next_in = tif->tif_rawdata; + sp->stream.avail_in = tif->tif_rawcc; + return (inflateReset(&sp->stream) == Z_OK); +} + +static int +ZIPDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s) +{ + ZIPState* sp = DecoderState(tif); + static const char module[] = "ZIPDecode"; + + (void) s; + assert(sp != NULL); + sp->stream.next_out = op; + sp->stream.avail_out = occ; + do { + int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + if (state == Z_STREAM_END) + break; + if (state == Z_DATA_ERROR) { + TIFFError(module, + "%s: Decoding error at scanline %d, %s", + tif->tif_name, tif->tif_row, sp->stream.msg); + if (inflateSync(&sp->stream) != Z_OK) + return (0); + continue; + } + if (state != Z_OK) { + TIFFError(module, "%s: zlib error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + } while (sp->stream.avail_out > 0); + if (sp->stream.avail_out != 0) { + TIFFError(module, + "%s: Not enough data at scanline %d (short %d bytes)", + tif->tif_name, tif->tif_row, sp->stream.avail_out); + return (0); + } + return (1); +} + +static int +ZIPSetupEncode(TIFF* tif) +{ + ZIPState* sp = EncoderState(tif); + static const char module[] = "ZIPSetupEncode"; + + assert(sp != NULL); + if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) { + TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg); + return (0); + } else { + sp->state |= ZSTATE_INIT; + return (1); + } +} + +/* + * Reset encoding state at the start of a strip. + */ +static int +ZIPPreEncode(TIFF* tif, tsample_t s) +{ + ZIPState *sp = EncoderState(tif); + + (void) s; + assert(sp != NULL); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = tif->tif_rawdatasize; + return (deflateReset(&sp->stream) == Z_OK); +} + +/* + * Encode a chunk of pixels. + */ +static int +ZIPEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s) +{ + ZIPState *sp = EncoderState(tif); + static const char module[] = "ZIPEncode"; + + (void) s; + sp->stream.next_in = bp; + sp->stream.avail_in = cc; + do { + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { + TIFFError(module, "%s: Encoder error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + if (sp->stream.avail_out == 0) { + tif->tif_rawcc = tif->tif_rawdatasize; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = tif->tif_rawdatasize; + } + } while (sp->stream.avail_in > 0); + return (1); +} + +/* + * Finish off an encoded strip by flushing the last + * string and tacking on an End Of Information code. + */ +static int +ZIPPostEncode(TIFF* tif) +{ + ZIPState *sp = EncoderState(tif); + static const char module[] = "ZIPPostEncode"; + int state; + + sp->stream.avail_in = 0; + do { + state = deflate(&sp->stream, Z_FINISH); + switch (state) { + case Z_STREAM_END: + case Z_OK: + if (sp->stream.avail_out != tif->tif_rawdatasize) { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + TIFFFlushData1(tif); + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = tif->tif_rawdatasize; + } + break; + default: + TIFFError(module, "%s: zlib error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + } while (state != Z_STREAM_END); + return (1); +} + +static void +ZIPCleanup(TIFF* tif) +{ + ZIPState* sp = ZState(tif); + if (sp) { + if (sp->state&ZSTATE_INIT) { + /* NB: avoid problems in the library */ + if (tif->tif_mode == O_RDONLY) + inflateEnd(&sp->stream); + else + deflateEnd(&sp->stream); + } + _TIFFfree(sp); + tif->tif_data = NULL; + } +} + +static int +ZIPVSetField(TIFF* tif, ttag_t tag, va_list ap) +{ + ZIPState* sp = ZState(tif); + static const char module[] = "ZIPVSetField"; + + switch (tag) { + case TIFFTAG_ZIPQUALITY: + sp->zipquality = va_arg(ap, int); + if (tif->tif_mode != O_RDONLY && (sp->state&ZSTATE_INIT)) { + if (deflateParams(&sp->stream, + sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) { + TIFFError(module, "%s: zlib error: %s", + tif->tif_name, sp->stream.msg); + return (0); + } + } + return (1); + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ +} + +static int +ZIPVGetField(TIFF* tif, ttag_t tag, va_list ap) +{ + ZIPState* sp = ZState(tif); + + switch (tag) { + case TIFFTAG_ZIPQUALITY: + *va_arg(ap, int*) = sp->zipquality; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); +} + +static const TIFFFieldInfo zipFieldInfo[] = { + { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, FIELD_PSEUDO, + TRUE, FALSE, "" }, +}; +#define N(a) (sizeof (a) / sizeof (a[0])) + +int +TIFFInitZIP(TIFF* tif, int scheme) +{ + ZIPState* sp; + + assert(scheme == COMPRESSION_DEFLATE); + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (ZIPState)); + if (tif->tif_data == NULL) + goto bad; + sp = ZState(tif); + sp->stream.zalloc = NULL; + sp->stream.zfree = NULL; + sp->stream.opaque = NULL; + sp->stream.data_type = Z_BINARY; + + /* + * Merge codec-specific tag information and + * override parent get/set field methods. + */ + _TIFFMergeFieldInfo(tif, zipFieldInfo, N(zipFieldInfo)); + sp->vgetparent = tif->tif_vgetfield; + tif->tif_vgetfield = ZIPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_vsetfield; + tif->tif_vsetfield = ZIPVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; + + /* + * Install codec methods. + */ + tif->tif_setupdecode = ZIPSetupDecode; + tif->tif_predecode = ZIPPreDecode; + tif->tif_decoderow = ZIPDecode; + tif->tif_decodestrip = ZIPDecode; + tif->tif_decodetile = ZIPDecode; + tif->tif_setupencode = ZIPSetupEncode; + tif->tif_preencode = ZIPPreEncode; + tif->tif_postencode = ZIPPostEncode; + tif->tif_encoderow = ZIPEncode; + tif->tif_encodestrip = ZIPEncode; + tif->tif_encodetile = ZIPEncode; + tif->tif_cleanup = ZIPCleanup; + /* + * Setup predictor setup. + */ + (void) TIFFPredictorInit(tif); + return (1); +bad: + TIFFError("TIFFInitZIP", "No space for ZIP state block"); + return (0); +} +#endif /* ZIP_SUPORT */ diff --git a/libtiff/tiff.h b/libtiff/tiff.h new file mode 100644 index 00000000..c2419556 --- /dev/null +++ b/libtiff/tiff.h @@ -0,0 +1,422 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiff.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFF_ +#define _TIFF_ +/* + * Tag Image File Format (TIFF) + * + * Based on Rev 6.0 from: + * Developer's Desk + * Aldus Corporation + * 411 First Ave. South + * Suite 200 + * Seattle, WA 98104 + * 206-622-5500 + */ +#define TIFF_VERSION 42 + +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 + +#ifndef _TIFF_DATA_TYPEDEFS_ +#define _TIFF_DATA_TYPEDEFS_ +/* + * Intrinsic data types required by the file format: + * + * 8-bit quantities int8/uint8 + * 16-bit quantities int16/uint16 + * 32-bit quantities int32/uint32 + * strings unsigned char* + */ +#ifdef __STDC__ +typedef signed char int8; /* NB: non-ANSI compilers may not grok */ +#else +typedef char int8; +#endif +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; /* sizeof (uint16) must == 2 */ +#if defined(__alpha) || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) +typedef int int32; +typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ +#else +typedef long int32; +typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ +#endif +#endif /* _TIFF_DATA_TYPEDEFS_ */ + +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint32 tiff_diroff; /* byte offset to first directory */ +} TIFFHeader; + +/* + * TIFF Image File Directories are comprised of + * a table of field descriptors of the form shown + * below. The table is sorted in ascending order + * by tag. The values associated with each entry + * are disjoint and may appear anywhere in the file + * (so long as they are placed on a word boundary). + * + * If the value is 4 bytes or less, then it is placed + * in the offset field to save space. If the value + * is less than 4 bytes, it is left-justified in the + * offset field. + */ +typedef struct { + uint16 tdir_tag; /* see below */ + uint16 tdir_type; /* data type; see below */ + uint32 tdir_count; /* number of items; length in spec */ + uint32 tdir_offset; /* byte offset to field data */ +} TIFFDirEntry; + +/* + * NB: In the comments below, + * - items marked with a + are obsoleted by revision 5.0, + * - items marked with a ! are introduced in revision 6.0. + * - items marked with a % are introduced post revision 6.0. + * - items marked with a $ are obsoleted by revision 6.0. + */ + +/* + * Tag data type information. + * + * Note: RATIONALs are the ratio of two 32-bit integer values. + */ +typedef enum { + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12 /* !64-bit IEEE floating point */ +} TIFFDataType; + +/* + * TIFF Tag Definitions. + */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !rows/data tile */ +#define TIFFTAG_TILELENGTH 323 /* !cols/data tile */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +/* + * Tags 512-521 are obsoleted by Technical Note #2 + * which specifies a revised JPEG-in-TIFF scheme. + */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +/* tags 32952-32956 are private tags registered to Island Graphics */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +/* tags 32995-32999 are private tags registered to SGI */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +/* tags 33300-33309 are private tags registered to Pixar */ +/* + * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH + * are set when an image has been cropped out of a larger image. + * They reflect the size of the original uncropped image. + * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used + * to determine the position of the smaller image in the larger one. + */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ +/* tag 33405 is a private tag registered to Eastman Kodak */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +/* IPTC TAG from RichTIFF specifications */ +#define TIFFTAG_RICHTIFFIPTC 33723 +/* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +/* tag 34929 is a private tag registered to FedEx */ +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +/* tag 65535 is an undefined tag used by Eastman Kodak */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ + +/* + * The following are ``pseudo tags'' that can be + * used to control codec-specific functionality. + * These tags are not written to file. Note that + * these values start at 0xffff+1 so that they'll + * never collide with Aldus-assigned tags. + * + * If you want your private pseudo tags ``registered'' + * (i.e. added to this file), send mail to sam@sgi.com + * with the appropriate C definitions to add. + */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +/* 65550-65556 are allocated to Oceana Matrix */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +/* 65559 is allocated to Oceana Matrix */ +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#endif /* _TIFF_ */ diff --git a/libtiff/tiffcomp.h b/libtiff/tiffcomp.h new file mode 100644 index 00000000..4fd58ffe --- /dev/null +++ b/libtiff/tiffcomp.h @@ -0,0 +1,214 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tiffcomp.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _COMPAT_ +#define _COMPAT_ +/* + * This file contains a hodgepodge of definitions and + * declarations that are needed to provide compatibility + * between the native system and the base implementation + * that the library assumes. + * + * NB: This file is a mess. + */ + +/* + * Setup basic type definitions and function declaratations. + */ + +/* + * Simplify Acorn RISC OS identifier (to avoid confusion with Acorn RISC iX + * and with defunct Unix Risc OS) + * No need to specify __arm - hey, Acorn might port the OS, no problem here! + */ +#ifdef __acornriscos +#undef __acornriscos +#endif +#if defined(__acorn) && defined(__riscos) +#define __acornriscos +#endif + +#if defined(__MWERKS__) || defined(THINK_C) +#include +#include +#endif + +#include + +#if defined(__PPCC__) || defined(__SC__) || defined(__MRC__) +#include +#elif !defined(__MWERKS__) && !defined(THINK_C) && !defined(__acornriscos) && !defined(applec) +#include +#endif + +#if defined(VMS) +#include +#include +#elif !defined(__acornriscos) +#include +#endif + +/* + * This maze of checks controls defines or not the + * target system has BSD-style typdedefs declared in + * an include file and/or whether or not to include + * to get the SEEK_* definitions. Some + * additional includes are also done to pull in the + * appropriate definitions we're looking for. + */ +#if defined(__MWERKS__) || defined(THINK_C) || defined(__PPCC__) || defined(__SC__) || defined(__MRC__) +#include +#define BSDTYPES +#define HAVE_UNISTD_H 0 +#elif defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) +#define BSDTYPES +#elif defined(OS2_16) || defined(OS2_32) +#define BSDTYPES +#elif defined(__acornriscos) +#include +#define BSDTYPES +#define HAVE_UNISTD_H 0 +#elif defined(VMS) +#define HAVE_UNISTD_H 0 +#else +#define HAVE_UNISTD_H 1 +#endif + +/* + * The library uses the ANSI C/POSIX SEEK_* + * definitions that should be defined in unistd.h + * (except on system where they are in stdio.h and + * there is no unistd.h). + */ +#if !defined(SEEK_SET) && HAVE_UNISTD_H +#include +#endif + +/* + * The library uses memset, memcpy, and memcmp. + * ANSI C and System V define these in string.h. + */ +#include + +/* + * The BSD typedefs are used throughout the library. + * If your system doesn't have them in , + * then define BSDTYPES in your Makefile. + */ +#if defined(BSDTYPES) +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +#endif + +/* + * dblparam_t is the type that a double precision + * floating point value will have on the parameter + * stack (when coerced by the compiler). + */ +/* Note: on MacPowerPC "extended" is undefined. So only use it for 68K-Macs */ +#if defined(__SC__) || defined(THINK_C) +typedef extended dblparam_t; +#else +typedef double dblparam_t; +#endif + +/* + * If your compiler supports inline functions, then + * set INLINE appropriately to get the known hotspots + * in the library expanded inline. + */ +#if defined(__GNUC__) +#if defined(__STRICT_ANSI__) +#define INLINE __inline__ +#else +#define INLINE inline +#endif +#else /* !__GNUC__ */ +#define INLINE +#endif + +/* + * GLOBALDATA is a macro that is used to define global variables + * private to the library. We use this indirection to hide + * brain-damage in VAXC (and GCC) under VAX/VMS. In these + * environments the macro places the variable in a non-shareable + * program section, which ought to be done by default (sigh!) + * + * Apparently DEC are aware of the problem as this behaviour is the + * default under VMS on AXP. + * + * The GNU C variant is untested. + */ +#if defined(VAX) && defined(VMS) +#if defined(VAXC) +#define GLOBALDATA(TYPE,NAME) extern noshare TYPE NAME +#endif +#if defined(__GNUC__) +#define GLOBALDATA(TYPE,NAME) extern TYPE NAME \ + asm("_$$PsectAttributes_NOSHR$$" #NAME) +#endif +#else /* !VAX/VMS */ +#define GLOBALDATA(TYPE,NAME) extern TYPE NAME +#endif + +#if defined(__acornriscos) +/* + * osfcn.h is part of C++Lib on Acorn C/C++, and as such can't be used + * on C alone. For that reason, the relevant functions are + * implemented in tif_acorn.c, and the elements from the header + * file are included here. + */ +#if defined(__cplusplus) +#include +#else +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define O_APPEND 8 +#define O_CREAT 0x200 +#define O_TRUNC 0x400 +typedef long off_t; +extern int open(const char *name, int flags, int mode); +extern int close(int fd); +extern int write(int fd, const char *buf, int nbytes); +extern int read(int fd, char *buf, int nbytes); +extern off_t lseek(int fd, off_t offset, int whence); +extern int creat(const char *path, int mode); +#endif /* __cplusplus */ +#endif /* __acornriscos */ + +/* Bit and byte order, the default is MSB to LSB */ +#ifdef VMS +#undef HOST_FILLORDER +#undef HOST_BIGENDIAN +#define HOST_FILLORDER FILLORDER_LSB2MSB +#define HOST_BIGENDIAN 0 +#endif + + +#endif /* _COMPAT_ */ diff --git a/libtiff/tiffconf.h b/libtiff/tiffconf.h new file mode 100644 index 00000000..46a7f3b2 --- /dev/null +++ b/libtiff/tiffconf.h @@ -0,0 +1,137 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tiffconf.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFCONF_ +#define _TIFFCONF_ +/* + * Library Configuration Definitions. + * + * This file defines the default configuration for the library. + * If the target system does not have make or a way to specify + * #defines on the command line, this file can be edited to + * configure the library. Otherwise, one can override portability + * and configuration-related definitions from a Makefile or command + * line by defining FEATURE_SUPPORT and COMPRESSION_SUPPORT (see below). + */ + +/* + * General portability-related defines: + * + * HAVE_IEEEFP define as 0 or 1 according to the floating point + * format suported by the machine + * BSDTYPES define this if your system does NOT define the + * usual 4BSD typedefs u_int et. al. + * HAVE_MMAP enable support for memory mapping read-only files; + * this is typically deduced by the configure script + * HOST_FILLORDER native cpu bit order: one of FILLORDER_MSB2LSB + * or FILLODER_LSB2MSB; this is typically set by the + * configure script + * HOST_BIGENDIAN native cpu byte order: 1 if big-endian (Motorola) + * or 0 if little-endian (Intel); this may be used + * in codecs to optimize code + */ +#ifndef HAVE_IEEEFP +#define HAVE_IEEEFP 1 +#endif +#ifndef HOST_FILLORDER +#define HOST_FILLORDER FILLORDER_MSB2LSB +#endif +#ifndef HOST_BIGENDIAN +#define HOST_BIGENDIAN 1 +#endif + +#ifndef FEATURE_SUPPORT +/* + * Feature support definitions: + * + * COLORIMETRY_SUPPORT enable support for 6.0 colorimetry tags + * YCBCR_SUPPORT enable support for 6.0 YCbCr tags + * CMYK_SUPPORT enable support for 6.0 CMYK tags + * ICC_SUPPORT enable support for ICC profile tag + * PHOTOSHOP_SUPPORT enable support for PHOTOSHOP resource tag + * IPTC_SUPPORT enable support for RichTIFF IPTC tag + */ +#define COLORIMETRY_SUPPORT +#define YCBCR_SUPPORT +#define CMYK_SUPPORT +#define ICC_SUPPORT +#define PHOTOSHOP_SUPPORT +#define IPTC_SUPPORT +#endif /* FEATURE_SUPPORT */ + +#ifndef COMPRESSION_SUPPORT +/* + * Compression support defines: + * + * CCITT_SUPPORT enable support for CCITT Group 3 & 4 algorithms + * PACKBITS_SUPPORT enable support for Macintosh PackBits algorithm + * LZW_SUPPORT enable support for LZW algorithm + * THUNDER_SUPPORT enable support for ThunderScan 4-bit RLE algorithm + * NEXT_SUPPORT enable support for NeXT 2-bit RLE algorithm + * OJPEG_SUPPORT enable support for 6.0-style JPEG DCT algorithms + * (no builtin support, only a codec hook) + * JPEG_SUPPORT enable support for post-6.0-style JPEG DCT algorithms + * (requires freely available IJG software, see tif_jpeg.c) + * ZIP_SUPPORT enable support for Deflate algorithm + * (requires freely available zlib software, see tif_zip.c) + * PIXARLOG_SUPPORT enable support for Pixar log-format algorithm + * LOGLUV_SUPPORT enable support for LogLuv high dynamic range encoding + */ +#define CCITT_SUPPORT +#define PACKBITS_SUPPORT +#define LZW_SUPPORT +#define THUNDER_SUPPORT +#define NEXT_SUPPORT +#define LOGLUV_SUPPORT +#endif /* COMPRESSION_SUPPORT */ + +/* + * If JPEG compression is enabled then we must also include + * support for the colorimetry and YCbCr-related tags. + */ +#ifdef JPEG_SUPPORT +#ifndef YCBCR_SUPPORT +#define YCBCR_SUPPORT +#endif +#ifndef COLORIMETRY_SUPPORT +#define COLORIMETRY_SUPPORT +#endif +#endif /* JPEG_SUPPORT */ + +/* + * ``Orthogonal Features'' + * + * STRIPCHOP_DEFAULT default handling of strip chopping support (whether + * or not to convert single-strip uncompressed images + * to mutiple strips of ~8Kb--to reduce memory use) + * SUBIFD_SUPPORT enable support for SubIFD tag (thumbnails and such) + */ +#ifndef STRIPCHOP_DEFAULT +#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP /* default is to enable */ +#endif +#ifndef SUBIFD_SUPPORT +#define SUBIFD_SUPPORT 1 /* enable SubIFD tag (330) support */ +#endif +#endif /* _TIFFCONF_ */ diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h new file mode 100644 index 00000000..43d1d854 --- /dev/null +++ b/libtiff/tiffio.h @@ -0,0 +1,316 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiffio.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIO_ +#define _TIFFIO_ + +/* + * TIFF I/O Library Definitions. + */ +#include "tiff.h" + +/* + * This define can be used in code that requires + * compilation-related definitions specific to a + * version or versions of the library. Runtime + * version checking should be done based on the + * string returned by TIFFGetVersion. + */ +#define TIFFLIB_VERSION 19970127 /* January 27, 1997 */ + +/* + * TIFF is defined as an incomplete type to hide the + * library's internal data structures from clients. + */ +typedef struct tiff TIFF; + +/* + * The following typedefs define the intrinsic size of + * data types used in the *exported* interfaces. These + * definitions depend on the proper definition of types + * in tiff.h. Note also that the varargs interface used + * to pass tag types and values uses the types defined in + * tiff.h directly. + * + * NB: ttag_t is unsigned int and not unsigned short because + * ANSI C requires that the type before the ellipsis be a + * promoted type (i.e. one of int, unsigned int, pointer, + * or double) and because we defined pseudo-tags that are + * outside the range of legal Aldus-assigned tags. + * NB: tsize_t is int32 and not uint32 because some functions + * return -1. + * NB: toff_t is not off_t for many reasons; TIFFs max out at + * 32-bit file offsets being the most important + */ +typedef uint32 ttag_t; /* directory tag */ +typedef uint16 tdir_t; /* directory index */ +typedef uint16 tsample_t; /* sample number */ +typedef uint32 tstrip_t; /* strip number */ +typedef uint32 ttile_t; /* tile number */ +typedef int32 tsize_t; /* i/o size in bytes */ +typedef void* tdata_t; /* image data ref */ +typedef int32 toff_t; /* file offset */ + +#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) +#define __WIN32__ +#endif +#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) +#include +#ifdef __WIN32__ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +#else +typedef HFILE thandle_t; /* client data handle */ +#endif +#else +typedef void* thandle_t; /* client data handle */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* + * Flags to pass to TIFFPrintDirectory to control + * printing of data structures that are potentially + * very large. Bit-or these flags to enable printing + * multiple items. + */ +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ + +/* + * RGBA-style image support. + */ +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ +typedef struct _TIFFRGBAImage TIFFRGBAImage; +/* + * The image reading and conversion routines invoke + * ``put routines'' to copy/image/whatever tiles of + * raw image data. A default set of routines are + * provided to convert/copy raw image data to 8-bit + * packed ABGR format rasters. Applications can supply + * alternate routines that unpack the data into a + * different format or, for example, unpack the data + * and draw the unpacked raster on the display. + */ +typedef void (*tileContigRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*); +typedef void (*tileSeparateRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*, unsigned char*, unsigned char*, unsigned char*); +/* + * RGBA-reader state. + */ +typedef struct { /* YCbCr->RGB support */ + TIFFRGBValue* clamptab; /* range clamping table */ + int* Cr_r_tab; + int* Cb_b_tab; + int32* Cr_g_tab; + int32* Cb_g_tab; + float coeffs[3]; /* cached for repeated use */ +} TIFFYCbCrToRGB; + +struct _TIFFRGBAImage { + TIFF* tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32 width; /* image width */ + uint32 height; /* image height */ + uint16 bitspersample; /* image bits/sample */ + uint16 samplesperpixel; /* image samples/pixel */ + uint16 orientation; /* image orientation */ + uint16 photometric; /* image photometric interp */ + uint16* redcmap; /* colormap pallete */ + uint16* greencmap; + uint16* bluecmap; + /* get image data routine */ + int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32); + union { + void (*any)(TIFFRGBAImage*); + tileContigRoutine contig; + tileSeparateRoutine separate; + } put; /* put decoded strip/tile */ + TIFFRGBValue* Map; /* sample mapping array */ + uint32** BWmap; /* black&white map */ + uint32** PALmap; /* palette image map */ + TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */ +}; + +/* + * Macros for extracting components from the + * packed ABGR form returned by TIFFReadRGBAImage. + */ +#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) +#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) +#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) + +/* + * A CODEC is a software package that implements decoding, + * encoding, or decoding+encoding of a compression algorithm. + * The library provides a collection of builtin codecs. + * More codecs may be registered through calls to the library + * and/or the builtin implementations may be overridden. + */ +typedef int (*TIFFInitMethod)(TIFF*, int); +typedef struct { + char* name; + uint16 scheme; + TIFFInitMethod init; +} TIFFCodec; + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif +typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); +typedef tsize_t (*TIFFReadWriteProc)(thandle_t, tdata_t, tsize_t); +typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); +typedef int (*TIFFCloseProc)(thandle_t); +typedef toff_t (*TIFFSizeProc)(thandle_t); +typedef int (*TIFFMapFileProc)(thandle_t, tdata_t*, toff_t*); +typedef void (*TIFFUnmapFileProc)(thandle_t, tdata_t, toff_t); +typedef void (*TIFFExtendProc)(TIFF*); + +extern const char* TIFFGetVersion(void); + +extern const TIFFCodec* TIFFFindCODEC(uint16); +extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); +extern void TIFFUnRegisterCODEC(TIFFCodec*); + +extern tdata_t _TIFFmalloc(tsize_t); +extern tdata_t _TIFFrealloc(tdata_t, tsize_t); +extern void _TIFFmemset(tdata_t, int, tsize_t); +extern void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t); +extern int _TIFFmemcmp(const tdata_t, const tdata_t, tsize_t); +extern void _TIFFfree(tdata_t); + +extern void TIFFClose(TIFF*); +extern int TIFFFlush(TIFF*); +extern int TIFFFlushData(TIFF*); +extern int TIFFGetField(TIFF*, ttag_t, ...); +extern int TIFFVGetField(TIFF*, ttag_t, va_list); +extern int TIFFGetFieldDefaulted(TIFF*, ttag_t, ...); +extern int TIFFVGetFieldDefaulted(TIFF*, ttag_t, va_list); +extern int TIFFReadDirectory(TIFF*); +extern tsize_t TIFFScanlineSize(TIFF*); +extern tsize_t TIFFRasterScanlineSize(TIFF*); +extern tsize_t TIFFStripSize(TIFF*); +extern tsize_t TIFFVStripSize(TIFF*, uint32); +extern tsize_t TIFFTileRowSize(TIFF*); +extern tsize_t TIFFTileSize(TIFF*); +extern tsize_t TIFFVTileSize(TIFF*, uint32); +extern uint32 TIFFDefaultStripSize(TIFF*, uint32); +extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); +extern int TIFFFileno(TIFF*); +extern int TIFFGetMode(TIFF*); +extern int TIFFIsTiled(TIFF*); +extern int TIFFIsByteSwapped(TIFF*); +extern int TIFFIsUpSampled(TIFF*); +extern int TIFFIsMSB2LSB(TIFF*); +extern uint32 TIFFCurrentRow(TIFF*); +extern tdir_t TIFFCurrentDirectory(TIFF*); +extern tdir_t TIFFNumberOfDirectories(TIFF*); +extern uint32 TIFFCurrentDirOffset(TIFF*); +extern tstrip_t TIFFCurrentStrip(TIFF*); +extern ttile_t TIFFCurrentTile(TIFF*); +extern int TIFFReadBufferSetup(TIFF*, tdata_t, tsize_t); +extern int TIFFWriteBufferSetup(TIFF*, tdata_t, tsize_t); +extern int TIFFLastDirectory(TIFF*); +extern int TIFFSetDirectory(TIFF*, tdir_t); +extern int TIFFSetSubDirectory(TIFF*, uint32); +extern int TIFFUnlinkDirectory(TIFF*, tdir_t); +extern int TIFFSetField(TIFF*, ttag_t, ...); +extern int TIFFVSetField(TIFF*, ttag_t, va_list); +extern int TIFFWriteDirectory(TIFF *); +#if defined(c_plusplus) || defined(__cplusplus) +extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); +extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t = 0); +extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t = 0); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); +#else +extern void TIFFPrintDirectory(TIFF*, FILE*, long); +extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t); +extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); +#endif +extern int TIFFRGBAImageOK(TIFF*, char [1024]); +extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); +extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); +extern void TIFFRGBAImageEnd(TIFFRGBAImage*); +extern TIFF* TIFFOpen(const char*, const char*); +extern TIFF* TIFFFdOpen(int, const char*, const char*); +extern TIFF* TIFFClientOpen(const char*, const char*, + thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, + TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); +extern const char* TIFFFileName(TIFF*); +extern void TIFFError(const char*, const char*, ...); +extern void TIFFWarning(const char*, const char*, ...); +extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); +extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); +extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); +extern ttile_t TIFFComputeTile(TIFF*, uint32, uint32, uint32, tsample_t); +extern int TIFFCheckTile(TIFF*, uint32, uint32, uint32, tsample_t); +extern ttile_t TIFFNumberOfTiles(TIFF*); +extern tsize_t TIFFReadTile(TIFF*, + tdata_t, uint32, uint32, uint32, tsample_t); +extern tsize_t TIFFWriteTile(TIFF*, + tdata_t, uint32, uint32, uint32, tsample_t); +extern tstrip_t TIFFComputeStrip(TIFF*, uint32, tsample_t); +extern tstrip_t TIFFNumberOfStrips(TIFF*); +extern tsize_t TIFFReadEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFReadRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFReadEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFReadRawTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteRawTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern void TIFFSetWriteOffset(TIFF*, toff_t); +extern void TIFFSwabShort(uint16*); +extern void TIFFSwabLong(uint32*); +extern void TIFFSwabDouble(double*); +extern void TIFFSwabArrayOfShort(uint16*, unsigned long); +extern void TIFFSwabArrayOfLong(uint32*, unsigned long); +extern void TIFFSwabArrayOfDouble(double*, unsigned long); +extern void TIFFReverseBits(unsigned char *, unsigned long); +extern const unsigned char* TIFFGetBitRevTable(int); +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFIO_ */ diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h new file mode 100644 index 00000000..47ae7c9f --- /dev/null +++ b/libtiff/tiffiop.h @@ -0,0 +1,278 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tiffiop.h,v 1.1 1999-07-27 21:50:27 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIOP_ +#define _TIFFIOP_ +/* + * ``Library-private'' definitions. + */ +/* + * UNIX systems should run the configure script to generate + * a port.h file that reflects the system capabilities. + * Doing this obviates all the dreck done in tiffcomp.h. + */ +#if defined(unix) || defined(__unix) +#include "port.h" +#include "tiffconf.h" +#else +#include "tiffconf.h" +#include "tiffcomp.h" +#endif +#include "tiffio.h" +#include "tif_dir.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* + * Typedefs for ``method pointers'' used internally. + */ +typedef unsigned char tidataval_t; /* internal image data value type */ +typedef tidataval_t* tidata_t; /* reference to internal image data */ + +typedef void (*TIFFVoidMethod)(TIFF*); +typedef int (*TIFFBoolMethod)(TIFF*); +typedef int (*TIFFPreMethod)(TIFF*, tsample_t); +typedef int (*TIFFCodeMethod)(TIFF*, tidata_t, tsize_t, tsample_t); +typedef int (*TIFFSeekMethod)(TIFF*, uint32); +typedef void (*TIFFPostMethod)(TIFF*, tidata_t, tsize_t); +typedef int (*TIFFVSetMethod)(TIFF*, ttag_t, va_list); +typedef int (*TIFFVGetMethod)(TIFF*, ttag_t, va_list); +typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); +typedef uint32 (*TIFFStripMethod)(TIFF*, uint32); +typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*); + +struct tiff { + char* tif_name; /* name of open file */ + int tif_fd; /* open file descriptor */ + int tif_mode; /* open mode (O_*) */ + uint32 tif_flags; +#define TIFF_FILLORDER 0x0003 /* natural bit fill order for machine */ +#define TIFF_DIRTYHEADER 0x0004 /* header must be written on close */ +#define TIFF_DIRTYDIRECT 0x0008 /* current directory must be written */ +#define TIFF_BUFFERSETUP 0x0010 /* data buffers setup */ +#define TIFF_CODERSETUP 0x0020 /* encoder/decoder setup done */ +#define TIFF_BEENWRITING 0x0040 /* written 1+ scanlines to file */ +#define TIFF_SWAB 0x0080 /* byte swap file information */ +#define TIFF_NOBITREV 0x0100 /* inhibit bit reversal logic */ +#define TIFF_MYBUFFER 0x0200 /* my raw data buffer; free on close */ +#define TIFF_ISTILED 0x0400 /* file is tile, not strip- based */ +#define TIFF_MAPPED 0x0800 /* file is mapped into memory */ +#define TIFF_POSTENCODE 0x1000 /* need call to postencode routine */ +#define TIFF_INSUBIFD 0x2000 /* currently writing a subifd */ +#define TIFF_UPSAMPLED 0x4000 /* library is doing data up-sampling */ +#define TIFF_STRIPCHOP 0x8000 /* enable strip chopping support */ + toff_t tif_diroff; /* file offset of current directory */ + toff_t tif_nextdiroff; /* file offset of following directory */ + TIFFDirectory tif_dir; /* internal rep of current directory */ + TIFFHeader tif_header; /* file's header block */ + tidata_t tif_clientdir; /* client TIFF directory */ + const int* tif_typeshift; /* data type shift counts */ + const long* tif_typemask; /* data type masks */ + uint32 tif_row; /* current scanline */ + tdir_t tif_curdir; /* current directory (index) */ + tstrip_t tif_curstrip; /* current strip for read/write */ + toff_t tif_curoff; /* current offset for read/write */ + toff_t tif_dataoff; /* current offset for writing dir */ +#if SUBIFD_SUPPORT + uint16 tif_nsubifd; /* remaining subifds to write */ + toff_t tif_subifdoff; /* offset for patching SubIFD link */ +#endif +/* tiling support */ + uint32 tif_col; /* current column (offset by row too) */ + ttile_t tif_curtile; /* current tile for read/write */ + tsize_t tif_tilesize; /* # of bytes in a tile */ +/* compression scheme hooks */ + TIFFBoolMethod tif_setupdecode;/* called once before predecode */ + TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ + TIFFBoolMethod tif_setupencode;/* called once before preencode */ + TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ + TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ + TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ + TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ + TIFFCodeMethod tif_decodestrip;/* strip decoding routine */ + TIFFCodeMethod tif_encodestrip;/* strip encoding routine */ + TIFFCodeMethod tif_decodetile; /* tile decoding routine */ + TIFFCodeMethod tif_encodetile; /* tile encoding routine */ + TIFFVoidMethod tif_close; /* cleanup-on-close routine */ + TIFFSeekMethod tif_seek; /* position within a strip routine */ + TIFFVoidMethod tif_cleanup; /* cleanup state routine */ + TIFFStripMethod tif_defstripsize;/* calculate/constrain strip size */ + TIFFTileMethod tif_deftilesize;/* calculate/constrain tile size */ + tidata_t tif_data; /* compression scheme private data */ +/* input/output buffering */ + tsize_t tif_scanlinesize;/* # of bytes in a scanline */ + tsize_t tif_scanlineskew;/* scanline skew for reading strips */ + tidata_t tif_rawdata; /* raw data buffer */ + tsize_t tif_rawdatasize;/* # of bytes in raw data buffer */ + tidata_t tif_rawcp; /* current spot in raw buffer */ + tsize_t tif_rawcc; /* bytes unread from raw buffer */ +/* memory-mapped file support */ + tidata_t tif_base; /* base of mapped file */ + toff_t tif_size; /* size of mapped file region (bytes) */ + TIFFMapFileProc tif_mapproc; /* map file method */ + TIFFUnmapFileProc tif_unmapproc;/* unmap file method */ +/* input/output callback methods */ + thandle_t tif_clientdata; /* callback parameter */ + TIFFReadWriteProc tif_readproc; /* read method */ + TIFFReadWriteProc tif_writeproc;/* write method */ + TIFFSeekProc tif_seekproc; /* lseek method */ + TIFFCloseProc tif_closeproc; /* close method */ + TIFFSizeProc tif_sizeproc; /* filesize method */ +/* post-decoding support */ + TIFFPostMethod tif_postdecode; /* post decoding routine */ +/* tag support */ + TIFFFieldInfo** tif_fieldinfo; /* sorted table of registered tags */ + int tif_nfields; /* # entries in registered tag table */ + TIFFVSetMethod tif_vsetfield; /* tag set routine */ + TIFFVGetMethod tif_vgetfield; /* tag get routine */ + TIFFPrintMethod tif_printdir; /* directory print routine */ +}; + +#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ + +#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) +#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) +#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) +#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) +#define TIFFReadFile(tif, buf, size) \ + ((*(tif)->tif_readproc)((tif)->tif_clientdata,buf,size)) +#define TIFFWriteFile(tif, buf, size) \ + ((*(tif)->tif_writeproc)((tif)->tif_clientdata,buf,size)) +#define TIFFSeekFile(tif, off, whence) \ + ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(toff_t)(off),whence)) +#define TIFFCloseFile(tif) \ + ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) +#define TIFFGetFileSize(tif) \ + ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) +#define TIFFMapFileContents(tif, paddr, psize) \ + ((*(tif)->tif_mapproc)((tif)->tif_clientdata,paddr,psize)) +#define TIFFUnmapFileContents(tif, addr, size) \ + ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,addr,size)) + +/* + * Default Read/Seek/Write definitions. + */ +#ifndef ReadOK +#define ReadOK(tif, buf, size) \ + (TIFFReadFile(tif, (tdata_t) buf, (tsize_t) size) == (tsize_t) size) +#endif +#ifndef SeekOK +#define SeekOK(tif, off) \ + (TIFFSeekFile(tif, (toff_t) off, SEEK_SET) == (toff_t) off) +#endif +#ifndef WriteOK +#define WriteOK(tif, buf, size) \ + (TIFFWriteFile(tif, (tdata_t) buf, (tsize_t) size) == (tsize_t) size) +#endif + +/* NB: the uint32 casts are to silence certain ANSI-C compilers */ +#define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) +#define TIFFroundup(x, y) (TIFFhowmany(x,y)*((uint32)(y))) + +#if defined(__cplusplus) +extern "C" { +#endif +extern int _TIFFgetMode(const char*, const char*); +extern int _TIFFNoRowEncode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoStripEncode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoTileEncode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoRowDecode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoStripDecode(TIFF*, tidata_t, tsize_t, tsample_t); +extern int _TIFFNoTileDecode(TIFF*, tidata_t, tsize_t, tsample_t); +extern void _TIFFNoPostDecode(TIFF*, tidata_t, tsize_t); +extern int _TIFFNoSeek(TIFF*, uint32); +extern void _TIFFSwab16BitData(TIFF*, tidata_t, tsize_t); +extern void _TIFFSwab32BitData(TIFF*, tidata_t, tsize_t); +extern void _TIFFSwab64BitData(TIFF*, tidata_t, tsize_t); +extern int TIFFFlushData1(TIFF*); +extern void TIFFFreeDirectory(TIFF*); +extern int TIFFDefaultDirectory(TIFF*); +extern int TIFFSetCompressionScheme(TIFF*, int); +extern int TIFFSetDefaultCompressionState(TIFF*); +extern uint32 _TIFFDefaultStripSize(TIFF*, uint32); +extern void _TIFFDefaultTileSize(TIFF*, uint32*, uint32*); + +extern void _TIFFsetByteArray(void**, void*, long); +extern void _TIFFsetString(char**, char*); +extern void _TIFFsetShortArray(uint16**, uint16*, long); +extern void _TIFFsetLongArray(uint32**, uint32*, long); +extern void _TIFFsetFloatArray(float**, float*, long); +extern void _TIFFsetDoubleArray(double**, double*, long); + +extern void _TIFFprintAscii(FILE*, const char*); +extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); + +GLOBALDATA(TIFFErrorHandler,_TIFFwarningHandler); +GLOBALDATA(TIFFErrorHandler,_TIFFerrorHandler); + +extern int TIFFInitDumpMode(TIFF*, int); +#ifdef PACKBITS_SUPPORT +extern int TIFFInitPackBits(TIFF*, int); +#endif +#ifdef CCITT_SUPPORT +extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); +extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); +#endif +#ifdef THUNDER_SUPPORT +extern int TIFFInitThunderScan(TIFF*, int); +#endif +#ifdef NEXT_SUPPORT +extern int TIFFInitNeXT(TIFF*, int); +#endif +#ifdef LZW_SUPPORT +extern int TIFFInitLZW(TIFF*, int); +#endif +#ifdef OJPEG_SUPPORT +extern int TIFFInitOJPEG(TIFF*, int); +#endif +#ifdef JPEG_SUPPORT +extern int TIFFInitJPEG(TIFF*, int); +#endif +#ifdef JBIG_SUPPORT +extern int TIFFInitJBIG(TIFF*, int); +#endif +#ifdef ZIP_SUPPORT +extern int TIFFInitZIP(TIFF*, int); +#endif +#ifdef PIXARLOG_SUPPORT +extern int TIFFInitPixarLog(TIFF*, int); +#endif +#ifdef LOGLUV_SUPPORT +extern int TIFFInitSGILog(TIFF*, int); +#endif +#ifdef VMS +extern const TIFFCodec _TIFFBuiltinCODECS[]; +#else +extern TIFFCodec _TIFFBuiltinCODECS[]; +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFIOP_ */ diff --git a/libtiff/uvcode.h b/libtiff/uvcode.h new file mode 100644 index 00000000..330c60b7 --- /dev/null +++ b/libtiff/uvcode.h @@ -0,0 +1,173 @@ +/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */ +#define UV_SQSIZ 0.003500 +#define UV_NDIVS 16289 +#define UV_VSTART 0.016940 +#define UV_NVS 163 +static struct { + float ustart; + short nus, ncum; +} uv_row[UV_NVS] = { + 0.247663, 4, 0, + 0.243779, 6, 4, + 0.241684, 7, 10, + 0.237874, 9, 17, + 0.235906, 10, 26, + 0.232153, 12, 36, + 0.228352, 14, 48, + 0.226259, 15, 62, + 0.222371, 17, 77, + 0.220410, 18, 94, + 0.214710, 21, 112, + 0.212714, 22, 133, + 0.210721, 23, 155, + 0.204976, 26, 178, + 0.202986, 27, 204, + 0.199245, 29, 231, + 0.195525, 31, 260, + 0.193560, 32, 291, + 0.189878, 34, 323, + 0.186216, 36, 357, + 0.186216, 36, 393, + 0.182592, 38, 429, + 0.179003, 40, 467, + 0.175466, 42, 507, + 0.172001, 44, 549, + 0.172001, 44, 593, + 0.168612, 46, 637, + 0.168612, 46, 683, + 0.163575, 49, 729, + 0.158642, 52, 778, + 0.158642, 52, 830, + 0.158642, 52, 882, + 0.153815, 55, 934, + 0.153815, 55, 989, + 0.149097, 58, 1044, + 0.149097, 58, 1102, + 0.142746, 62, 1160, + 0.142746, 62, 1222, + 0.142746, 62, 1284, + 0.138270, 65, 1346, + 0.138270, 65, 1411, + 0.138270, 65, 1476, + 0.132166, 69, 1541, + 0.132166, 69, 1610, + 0.126204, 73, 1679, + 0.126204, 73, 1752, + 0.126204, 73, 1825, + 0.120381, 77, 1898, + 0.120381, 77, 1975, + 0.120381, 77, 2052, + 0.120381, 77, 2129, + 0.112962, 82, 2206, + 0.112962, 82, 2288, + 0.112962, 82, 2370, + 0.107450, 86, 2452, + 0.107450, 86, 2538, + 0.107450, 86, 2624, + 0.107450, 86, 2710, + 0.100343, 91, 2796, + 0.100343, 91, 2887, + 0.100343, 91, 2978, + 0.095126, 95, 3069, + 0.095126, 95, 3164, + 0.095126, 95, 3259, + 0.095126, 95, 3354, + 0.088276, 100, 3449, + 0.088276, 100, 3549, + 0.088276, 100, 3649, + 0.088276, 100, 3749, + 0.081523, 105, 3849, + 0.081523, 105, 3954, + 0.081523, 105, 4059, + 0.081523, 105, 4164, + 0.074861, 110, 4269, + 0.074861, 110, 4379, + 0.074861, 110, 4489, + 0.074861, 110, 4599, + 0.068290, 115, 4709, + 0.068290, 115, 4824, + 0.068290, 115, 4939, + 0.068290, 115, 5054, + 0.063573, 119, 5169, + 0.063573, 119, 5288, + 0.063573, 119, 5407, + 0.063573, 119, 5526, + 0.057219, 124, 5645, + 0.057219, 124, 5769, + 0.057219, 124, 5893, + 0.057219, 124, 6017, + 0.050985, 129, 6141, + 0.050985, 129, 6270, + 0.050985, 129, 6399, + 0.050985, 129, 6528, + 0.050985, 129, 6657, + 0.044859, 134, 6786, + 0.044859, 134, 6920, + 0.044859, 134, 7054, + 0.044859, 134, 7188, + 0.040571, 138, 7322, + 0.040571, 138, 7460, + 0.040571, 138, 7598, + 0.040571, 138, 7736, + 0.036339, 142, 7874, + 0.036339, 142, 8016, + 0.036339, 142, 8158, + 0.036339, 142, 8300, + 0.032139, 146, 8442, + 0.032139, 146, 8588, + 0.032139, 146, 8734, + 0.032139, 146, 8880, + 0.027947, 150, 9026, + 0.027947, 150, 9176, + 0.027947, 150, 9326, + 0.023739, 154, 9476, + 0.023739, 154, 9630, + 0.023739, 154, 9784, + 0.023739, 154, 9938, + 0.019504, 158, 10092, + 0.019504, 158, 10250, + 0.019504, 158, 10408, + 0.016976, 161, 10566, + 0.016976, 161, 10727, + 0.016976, 161, 10888, + 0.016976, 161, 11049, + 0.012639, 165, 11210, + 0.012639, 165, 11375, + 0.012639, 165, 11540, + 0.009991, 168, 11705, + 0.009991, 168, 11873, + 0.009991, 168, 12041, + 0.009016, 170, 12209, + 0.009016, 170, 12379, + 0.009016, 170, 12549, + 0.006217, 173, 12719, + 0.006217, 173, 12892, + 0.005097, 175, 13065, + 0.005097, 175, 13240, + 0.005097, 175, 13415, + 0.003909, 177, 13590, + 0.003909, 177, 13767, + 0.002340, 177, 13944, + 0.002389, 170, 14121, + 0.001068, 164, 14291, + 0.001653, 157, 14455, + 0.000717, 150, 14612, + 0.001614, 143, 14762, + 0.000270, 136, 14905, + 0.000484, 129, 15041, + 0.001103, 123, 15170, + 0.001242, 115, 15293, + 0.001188, 109, 15408, + 0.001011, 103, 15517, + 0.000709, 97, 15620, + 0.000301, 89, 15717, + 0.002416, 82, 15806, + 0.003251, 76, 15888, + 0.003246, 69, 15964, + 0.004141, 62, 16033, + 0.005963, 55, 16095, + 0.008839, 47, 16150, + 0.010490, 40, 16197, + 0.016994, 31, 16237, + 0.023659, 21, 16268, +}; diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 00000000..69ed5787 --- /dev/null +++ b/man/Makefile @@ -0,0 +1,398 @@ +#! smake +# $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/Makefile,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# Warning, this file was automatically created by the TIFF configure script +# +# Tag Image File Format Library Manual Pages +# +# Copyright (c) 1991-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +SRCDIR = ../man + +# +# VERSION: v3.4beta037 +# DATE: Wed Feb 3 19:53:27 EST 1999 +# TARGET: i586-unknown-linux +# CCOMPILER: /usr/bin/gcc +# +SHELL = /bin/sh +NULL = +ECHO = echo +SED = sed +MV = mv +RM = rm -f +INSTALL = ${SHELL} ../port/install.sh + +# +# Manual-related controls: +# +# MAN head of manual tree +# MANAPPS subdirectory for application programs +# MANLIB subdirectory for library functions +# +MAN = /usr/local/man +MANAPPS = man1 +MANLIB = man3 +# +# MANSEDLOCAL additional sed commands to use during source transformation +# (might want to transform section names here) +# MANCVT command to convert source to installable target (can use +# $? and $@, but not $<) +MANSEDLOCAL = +MANCVT = ${MANSED} $? >$@ +# +# The following macros are used during the install step to generate +# the filenames of the target manual pages. They appear inside a +# shell for loop in a command of the form: +# +# f=${MAN*NAME} +# +# where the variable ``i'' contains the filename of the formatted +# manual page (formatted according to the MANCVT macro). +# +# MANAPPNAME generate installed app man page filename +# MANLIBNAME generate installed library man page filename +# +# +MANAPPNAME = $$i +MANLIBNAME = $$i + +# +# Set this up if your manual system requires a +# pathname prefix in the .so commands when setting +# up alternate files for multi-function manual pages. +# +#MANDIR = man3/ + +MANTOOLS=\ + apps/fax2tiff.1 \ + apps/fax2ps.1 \ + apps/gif2tiff.1 \ + apps/pal2rgb.1 \ + apps/ppm2tiff.1 \ + apps/ras2tiff.1 \ + apps/rgb2ycbcr.1 \ + apps/sgi2tiff.1 \ + apps/thumbnail.1 \ + apps/tiff2bw.1 \ + apps/tiff2ps.1 \ + apps/tiffcmp.1 \ + apps/tiffcp.1 \ + apps/tiffdither.1 \ + apps/tiffdump.1 \ + apps/tiffgt.1 \ + apps/tiffinfo.1 \ + apps/tiffmedian.1 \ + apps/tiffsplit.1 \ + apps/tiffsv.1 \ + ${NULL} +MANDEV=\ + lib/libtiff.3t \ + \ + lib/TIFFClose.3t \ + lib/TIFFError.3t \ + lib/TIFFFlush.3t \ + lib/TIFFGetField.3t \ + lib/TIFFOpen.3t \ + lib/TIFFPrintDirectory.3t \ + lib/TIFFReadDirectory.3t \ + lib/TIFFReadEncodedStrip.3t \ + lib/TIFFReadEncodedTile.3t \ + lib/TIFFReadRGBAImage.3t \ + lib/TIFFReadRawStrip.3t \ + lib/TIFFReadRawTile.3t \ + lib/TIFFReadScanline.3t \ + lib/TIFFReadTile.3t \ + lib/TIFFRGBAImage.3t \ + lib/TIFFSetDirectory.3t \ + lib/TIFFSetField.3t \ + lib/TIFFWarning.3t \ + lib/TIFFWriteDirectory.3t \ + lib/TIFFWriteEncodedStrip.3t \ + lib/TIFFWriteEncodedTile.3t \ + lib/TIFFWriteRawStrip.3t \ + lib/TIFFWriteRawTile.3t \ + lib/TIFFWriteScanline.3t \ + \ + lib/TIFFbuffer.3t \ + lib/TIFFcodec.3t \ + lib/TIFFmemory.3t \ + lib/TIFFquery.3t \ + lib/TIFFsize.3t \ + lib/TIFFstrip.3t \ + lib/TIFFswab.3t \ + lib/TIFFtile.3t \ + ${NULL} +MANDEVLINKS=\ + lib/TIFFmalloc.3t \ + lib/TIFFrealloc.3t \ + lib/TIFFfree.3t \ + lib/TIFFmemset.3t \ + lib/TIFFmemcpy.3t \ + lib/TIFFmemcmp.3t \ + lib/TIFFComputeTile.3t \ + lib/TIFFCheckTile.3t \ + lib/TIFFNumberOfTiles.3t \ + lib/TIFFComputeStrip.3t \ + lib/TIFFNumberOfStrips.3t \ + lib/TIFFCurrentDirectory.3t \ + lib/TIFFCurrentRow.3t \ + lib/TIFFCurrentStrip.3t \ + lib/TIFFCurrentTile.3t \ + lib/TIFFFdOpen.3t \ + lib/TIFFFileName.3t \ + lib/TIFFFileno.3t \ + lib/TIFFFindCODEC.3t \ + lib/TIFFFlushData.3t \ + lib/TIFFGetMode.3t \ + lib/TIFFIsTiled.3t \ + lib/TIFFIsByteSwapped.3t \ + lib/TIFFIsUpSampled.3t \ + lib/TIFFIsMSB2LSB.3t \ + lib/TIFFLastDirectory.3t \ + lib/TIFFRegisterCODEC.3t \ + lib/TIFFReverseBits.3t \ + lib/TIFFRGBAImageOK.3t \ + lib/TIFFRGBAImageBegin.3t \ + lib/TIFFRGBAImageGet.3t \ + lib/TIFFRGBAImageEnd.3t \ + lib/TIFFSetErrorHandler.3t \ + lib/TIFFSetSubDirectory.3t \ + lib/TIFFSetWarningHandler.3t \ + lib/TIFFSwabArrayOfLong.3t \ + lib/TIFFSwabArrayOfShort.3t \ + lib/TIFFSwabLong.3t \ + lib/TIFFSwabShort.3t \ + lib/TIFFScanlineSize.3t \ + lib/TIFFDefaultStripSize.3t \ + lib/TIFFVStripSize.3t \ + lib/TIFFStripSize.3t \ + lib/TIFFDefaultTileSize.3t \ + lib/TIFFVTileSize.3t \ + lib/TIFFTileSize.3t \ + lib/TIFFTileRowSize.3t \ + lib/TIFFUnRegisterCODEC.3t \ + lib/TIFFVGetField.3t \ + lib/TIFFVSetField.3t \ + lib/TIFFReadBufferSetup.3t \ + lib/TIFFWriteBufferSetup.3t \ + ${NULL} +TARGETS=apps/Makefile lib/Makefile + +# +# System-specific manual page formatting commands should +# apply this sed command to the manual page source before +# handing it to the formatter. This sets any pathnames +# in the man pages to reflect local conventions. +# +MANSED=${SED}\ + -e 's;\$${DIR_BIN};/usr/local/bin;g' \ + -e 's;\$${DIR_LIB};/usr/local/lib;g' \ + -e 's;\$${DIR_INC};/usr/local/include;g' \ + ${MANSEDLOCAL} + +all: ${TARGETS} + +apps/fax2tiff.1:: ${SRCDIR}/fax2tiff.1; ${MANCVT} +apps/fax2ps.1:: ${SRCDIR}/fax2ps.1; ${MANCVT} +apps/gif2tiff.1:: ${SRCDIR}/gif2tiff.1; ${MANCVT} +apps/pal2rgb.1:: ${SRCDIR}/pal2rgb.1; ${MANCVT} +apps/ppm2tiff.1:: ${SRCDIR}/ppm2tiff.1; ${MANCVT} +apps/ras2tiff.1:: ${SRCDIR}/ras2tiff.1; ${MANCVT} +apps/rgb2ycbcr.1:: ${SRCDIR}/rgb2ycbcr.1; ${MANCVT} +apps/sgi2tiff.1:: ${SRCDIR}/sgi2tiff.1; ${MANCVT} +apps/thumbnail.1:: ${SRCDIR}/thumbnail.1; ${MANCVT} +apps/tiff2bw.1:: ${SRCDIR}/tiff2bw.1; ${MANCVT} +apps/tiff2ps.1:: ${SRCDIR}/tiff2ps.1; ${MANCVT} +apps/tiffcmp.1:: ${SRCDIR}/tiffcmp.1; ${MANCVT} +apps/tiffcp.1:: ${SRCDIR}/tiffcp.1; ${MANCVT} +apps/tiffdither.1:: ${SRCDIR}/tiffdither.1; ${MANCVT} +apps/tiffdump.1:: ${SRCDIR}/tiffdump.1; ${MANCVT} +apps/tiffgt.1:: ${SRCDIR}/tiffgt.1; ${MANCVT} +apps/tiffinfo.1:: ${SRCDIR}/tiffinfo.1; ${MANCVT} +apps/tiffmedian.1:: ${SRCDIR}/tiffmedian.1; ${MANCVT} +apps/tiffsplit.1:: ${SRCDIR}/tiffsplit.1; ${MANCVT} +apps/tiffsv.1:: ${SRCDIR}/tiffsv.1; ${MANCVT} + +lib/libtiff.3t:: ${SRCDIR}/libtiff.3t; ${MANCVT} +lib/TIFFClose.3t:: ${SRCDIR}/TIFFClose.3t; ${MANCVT} +lib/TIFFError.3t:: ${SRCDIR}/TIFFError.3t; ${MANCVT} +lib/TIFFFlush.3t:: ${SRCDIR}/TIFFFlush.3t; ${MANCVT} +lib/TIFFGetField.3t:: ${SRCDIR}/TIFFGetField.3t; ${MANCVT} +lib/TIFFOpen.3t:: ${SRCDIR}/TIFFOpen.3t; ${MANCVT} +lib/TIFFPrintDirectory.3t:: ${SRCDIR}/TIFFPrintDirectory.3t; ${MANCVT} +lib/TIFFReadDirectory.3t:: ${SRCDIR}/TIFFReadDirectory.3t; ${MANCVT} +lib/TIFFReadEncodedStrip.3t:: ${SRCDIR}/TIFFReadEncodedStrip.3t;${MANCVT} +lib/TIFFReadEncodedTile.3t:: ${SRCDIR}/TIFFReadEncodedTile.3t; ${MANCVT} +lib/TIFFReadRGBAImage.3t:: ${SRCDIR}/TIFFReadRGBAImage.3t; ${MANCVT} +lib/TIFFReadRawStrip.3t:: ${SRCDIR}/TIFFReadRawStrip.3t; ${MANCVT} +lib/TIFFReadRawTile.3t:: ${SRCDIR}/TIFFReadRawTile.3t; ${MANCVT} +lib/TIFFReadScanline.3t:: ${SRCDIR}/TIFFReadScanline.3t; ${MANCVT} +lib/TIFFReadTile.3t:: ${SRCDIR}/TIFFReadTile.3t; ${MANCVT} +lib/TIFFRGBAImage.3t:: ${SRCDIR}/TIFFRGBAImage.3t; ${MANCVT} +lib/TIFFSetDirectory.3t:: ${SRCDIR}/TIFFSetDirectory.3t; ${MANCVT} +lib/TIFFSetField.3t:: ${SRCDIR}/TIFFSetField.3t; ${MANCVT} +lib/TIFFWarning.3t:: ${SRCDIR}/TIFFWarning.3t; ${MANCVT} +lib/TIFFWriteDirectory.3t:: ${SRCDIR}/TIFFWriteDirectory.3t; ${MANCVT} +lib/TIFFWriteEncodedStrip.3t:: ${SRCDIR}/TIFFWriteEncodedStrip.3t; ${MANCVT} +lib/TIFFWriteEncodedTile.3t:: ${SRCDIR}/TIFFWriteEncodedTile.3t; ${MANCVT} +lib/TIFFWriteRawStrip.3t:: ${SRCDIR}/TIFFWriteRawStrip.3t; ${MANCVT} +lib/TIFFWriteRawTile.3t:: ${SRCDIR}/TIFFWriteRawTile.3t; ${MANCVT} +lib/TIFFWriteScanline.3t:: ${SRCDIR}/TIFFWriteScanline.3t; ${MANCVT} +lib/TIFFbuffer.3t:: ${SRCDIR}/TIFFbuffer.3t; ${MANCVT} +lib/TIFFcodec.3t:: ${SRCDIR}/TIFFcodec.3t; ${MANCVT} +lib/TIFFmemory.3t:: ${SRCDIR}/TIFFmemory.3t; ${MANCVT} +lib/TIFFquery.3t:: ${SRCDIR}/TIFFquery.3t; ${MANCVT} +lib/TIFFsize.3t:: ${SRCDIR}/TIFFsize.3t; ${MANCVT} +lib/TIFFstrip.3t:: ${SRCDIR}/TIFFstrip.3t; ${MANCVT} +lib/TIFFswab.3t:: ${SRCDIR}/TIFFswab.3t; ${MANCVT} +lib/TIFFtile.3t:: ${SRCDIR}/TIFFtile.3t; ${MANCVT} + +lib/TIFFComputeTile.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFCheckTile.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFNumberOfTiles.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFComputeStrip.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFNumberOfStrips.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFCurrentDirectory.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFCurrentRow.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFCurrentStrip.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFCurrentTile.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFFdOpen.3t:; ${ECHO} ".so ${MANDIR}TIFFOpen.3t" > $@ +lib/TIFFFileName.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFFileno.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFFlushData.3t:; ${ECHO} ".so ${MANDIR}TIFFFlush.3t" > $@ +lib/TIFFGetMode.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsTiled.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsByteSwapped.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsUpSampled.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsMSB2LSB.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFLastDirectory.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFReverseBits.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFRGBAImageOK.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFRGBAImageBegin.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFRGBAImageGet.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFRGBAImageEnd.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFSetErrorHandler.3t:; ${ECHO} ".so ${MANDIR}TIFFError.3t" > $@ +lib/TIFFSetSubDirectory.3t:; ${ECHO} ".so ${MANDIR}TIFFSetDirectory.3t" > $@ +lib/TIFFSetWarningHandler.3t:; ${ECHO} ".so ${MANDIR}TIFFWarning.3t" > $@ +lib/TIFFSwabArrayOfLong.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFSwabArrayOfShort.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFSwabLong.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFSwabShort.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFScanlineSize.3t:; ${ECHO} ".so ${MANDIR}TIFFsize.3t" > $@ +lib/TIFFRasterScanlineSize.3t:; ${ECHO} ".so ${MANDIR}TIFFsize.3t" > $@ +lib/TIFFDefaultStripSize.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFStripSize.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFVStripSize.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFTileSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFVTileSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFDefaultTileSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFTileRowSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFVGetField.3t:; ${ECHO} ".so ${MANDIR}TIFFGetField.3t" > $@ +lib/TIFFVSetField.3t:; ${ECHO} ".so ${MANDIR}TIFFSetField.3t" > $@ +lib/TIFFFindCODEC.3t:; ${ECHO} ".so ${MANDIR}TIFFcodec.3t" > $@ +lib/TIFFRegisterCODEC.3t:; ${ECHO} ".so ${MANDIR}TIFFcodec.3t" > $@ +lib/TIFFUnRegisterCODEC.3t:; ${ECHO} ".so ${MANDIR}TIFFcodec.3t" > $@ +lib/TIFFmalloc.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFrealloc.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFfree.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFmemset.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFmemcpy.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFmemcmp.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFReadBufferSetup.3t:; ${ECHO} ".so ${MANDIR}TIFFbuffer.3t" > $@ +lib/TIFFWriteBufferSetup.3t:; ${ECHO} ".so ${MANDIR}TIFFbuffer.3t" > $@ + +apps/Makefile: + test -d apps || mkdir apps + ${MAKE} ${MANTOOLS} + ${RM} apps/Makefile + (cd apps; \ + ${ECHO} 'install:'; \ + for i in *.1; do \ + f=${MANAPPNAME}; \ + ${ECHO} ' cd ..; ${INSTALL} -m 444 -F ${MAN}/${MANAPPS} \ + -idb tiff.man.tools -src' apps/"$$i" '-O' "$$f"; \ + done \ + )>apps/Makefile +lib/Makefile: + test -d lib || mkdir lib + ${MAKE} ${MANDEV} ${MANDEVLINKS} + ${RM} lib/Makefile + (cd lib; \ + ${ECHO} 'install:'; \ + for i in *.3t; do \ + f=${MANLIBNAME}; \ + ${ECHO} ' cd ..; ${INSTALL} -m 444 -F ${MAN}/${MANLIB} \ + -idb tiff.man.dev -src' lib/"$$i" '-O' "$$f"; \ + done \ + )>lib/Makefile + +install: all + ${INSTALL} -m 755 -dir -idb tiff.man.tools ${MAN} + ${INSTALL} -m 755 -dir -idb tiff.man.tools ${MAN}/${MANAPPS} + cd apps; ${MAKE} install + ${INSTALL} -m 755 -dir -idb tiff.man.dev ${MAN}/${MANLIB} + cd lib; ${MAKE} install + +clean: + rm -rf apps lib + +# +# Miscellaneous junk left over... +# + +links: ${MANDEVLINKS} + +short: + ${MV} TIFFClose.3t close.3t + ${MV} TIFFError.3t error.3t + ${MV} TIFFFlush.3t flush.3t + ${MV} TIFFGetField.3t getfield.3t + ${MV} TIFFOpen.3t open.3t + ${MV} TIFFPrintDirectory.3t print.3t + ${MV} TIFFReadEncodedStrip.3t rdestrip.3t + ${MV} TIFFReadencodedTile.3t rdetile.3t + ${MV} TIFFReadRawStrip.3t rdrstrip.3t + ${MV} TIFFReadRawTile.3t rdrtile.3t + ${MV} TIFFReadDirectory.3t readdir.3t + ${MV} TIFFReadRGBAImage.3t rdimage.3t + ${MV} TIFFReadScanline.3t readline.3t + ${MV} TIFFReadTile.3t readtile.3t + ${MV} TIFFRGBAImage.3t rgbaimage.3t + ${MV} TIFFSetDirectory.3t setdir.3t + ${MV} TIFFSetField.3t setfield.3t + ${MV} TIFFWarning.3t warning.3t + ${MV} TIFFWriteEncodedStrip.3t wrestrip.3t + ${MV} TIFFWriteEncodedTile.3t wretile.3t + ${MV} TIFFWriteDirectory.3t writedir.3t + ${MV} TIFFWriteRawStrip.3t wrrstrip.3t + ${MV} TIFFWriteRawTile.3t wrrtile.3t + ${MV} TIFFWriteScanline.3t writeline.3t + ${MV} TIFFtile.3t tile.3t + ${MV} TIFFstrip.3t strip.3t + ${MV} TIFFquery.3t query.3t + ${MV} TIFFswab.3t swab.3t + ${MV} TIFFsize.3t size.3t + ${MV} TIFFcodec.3t codec.3t + ${MV} TIFFmemory.3t memory.3t + ${MV} TIFFbuffer.3t buffer.3t diff --git a/man/Makefile.in b/man/Makefile.in new file mode 100644 index 00000000..198d109f --- /dev/null +++ b/man/Makefile.in @@ -0,0 +1,398 @@ +#! smake +# $Header: /cvs/maptools/cvsroot/libtiff/man/Makefile.in,v 1.1 1999-07-27 21:50:27 mike Exp $ +# +# @WARNING@ +# +# Tag Image File Format Library Manual Pages +# +# Copyright (c) 1991-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +SRCDIR = @RELSRCDIR@/man + +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# CCOMPILER: @CCOMPILER@ +# +SHELL = @SCRIPT_SH@ +NULL = +ECHO = echo +SED = sed +MV = mv +RM = rm -f +INSTALL = @INSTALL@ + +# +# Manual-related controls: +# +# MAN head of manual tree +# MANAPPS subdirectory for application programs +# MANLIB subdirectory for library functions +# +MAN = @DIR_MAN@ +MANAPPS = @MANAPPS@ +MANLIB = @MANLIB@ +# +# MANSEDLOCAL additional sed commands to use during source transformation +# (might want to transform section names here) +# MANCVT command to convert source to installable target (can use +# $? and $@, but not $<) +MANSEDLOCAL = @MANSEDLOCAL@ +MANCVT = @MANCVT@ +# +# The following macros are used during the install step to generate +# the filenames of the target manual pages. They appear inside a +# shell for loop in a command of the form: +# +# f=${MAN*NAME} +# +# where the variable ``i'' contains the filename of the formatted +# manual page (formatted according to the MANCVT macro). +# +# MANAPPNAME generate installed app man page filename +# MANLIBNAME generate installed library man page filename +# +# +MANAPPNAME = @MANAPPNAME@ +MANLIBNAME = @MANLIBNAME@ + +# +# Set this up if your manual system requires a +# pathname prefix in the .so commands when setting +# up alternate files for multi-function manual pages. +# +#MANDIR = man3/ + +MANTOOLS=\ + apps/fax2tiff.1 \ + apps/fax2ps.1 \ + apps/gif2tiff.1 \ + apps/pal2rgb.1 \ + apps/ppm2tiff.1 \ + apps/ras2tiff.1 \ + apps/rgb2ycbcr.1 \ + apps/sgi2tiff.1 \ + apps/thumbnail.1 \ + apps/tiff2bw.1 \ + apps/tiff2ps.1 \ + apps/tiffcmp.1 \ + apps/tiffcp.1 \ + apps/tiffdither.1 \ + apps/tiffdump.1 \ + apps/tiffgt.1 \ + apps/tiffinfo.1 \ + apps/tiffmedian.1 \ + apps/tiffsplit.1 \ + apps/tiffsv.1 \ + ${NULL} +MANDEV=\ + lib/libtiff.3t \ + \ + lib/TIFFClose.3t \ + lib/TIFFError.3t \ + lib/TIFFFlush.3t \ + lib/TIFFGetField.3t \ + lib/TIFFOpen.3t \ + lib/TIFFPrintDirectory.3t \ + lib/TIFFReadDirectory.3t \ + lib/TIFFReadEncodedStrip.3t \ + lib/TIFFReadEncodedTile.3t \ + lib/TIFFReadRGBAImage.3t \ + lib/TIFFReadRawStrip.3t \ + lib/TIFFReadRawTile.3t \ + lib/TIFFReadScanline.3t \ + lib/TIFFReadTile.3t \ + lib/TIFFRGBAImage.3t \ + lib/TIFFSetDirectory.3t \ + lib/TIFFSetField.3t \ + lib/TIFFWarning.3t \ + lib/TIFFWriteDirectory.3t \ + lib/TIFFWriteEncodedStrip.3t \ + lib/TIFFWriteEncodedTile.3t \ + lib/TIFFWriteRawStrip.3t \ + lib/TIFFWriteRawTile.3t \ + lib/TIFFWriteScanline.3t \ + \ + lib/TIFFbuffer.3t \ + lib/TIFFcodec.3t \ + lib/TIFFmemory.3t \ + lib/TIFFquery.3t \ + lib/TIFFsize.3t \ + lib/TIFFstrip.3t \ + lib/TIFFswab.3t \ + lib/TIFFtile.3t \ + ${NULL} +MANDEVLINKS=\ + lib/TIFFmalloc.3t \ + lib/TIFFrealloc.3t \ + lib/TIFFfree.3t \ + lib/TIFFmemset.3t \ + lib/TIFFmemcpy.3t \ + lib/TIFFmemcmp.3t \ + lib/TIFFComputeTile.3t \ + lib/TIFFCheckTile.3t \ + lib/TIFFNumberOfTiles.3t \ + lib/TIFFComputeStrip.3t \ + lib/TIFFNumberOfStrips.3t \ + lib/TIFFCurrentDirectory.3t \ + lib/TIFFCurrentRow.3t \ + lib/TIFFCurrentStrip.3t \ + lib/TIFFCurrentTile.3t \ + lib/TIFFFdOpen.3t \ + lib/TIFFFileName.3t \ + lib/TIFFFileno.3t \ + lib/TIFFFindCODEC.3t \ + lib/TIFFFlushData.3t \ + lib/TIFFGetMode.3t \ + lib/TIFFIsTiled.3t \ + lib/TIFFIsByteSwapped.3t \ + lib/TIFFIsUpSampled.3t \ + lib/TIFFIsMSB2LSB.3t \ + lib/TIFFLastDirectory.3t \ + lib/TIFFRegisterCODEC.3t \ + lib/TIFFReverseBits.3t \ + lib/TIFFRGBAImageOK.3t \ + lib/TIFFRGBAImageBegin.3t \ + lib/TIFFRGBAImageGet.3t \ + lib/TIFFRGBAImageEnd.3t \ + lib/TIFFSetErrorHandler.3t \ + lib/TIFFSetSubDirectory.3t \ + lib/TIFFSetWarningHandler.3t \ + lib/TIFFSwabArrayOfLong.3t \ + lib/TIFFSwabArrayOfShort.3t \ + lib/TIFFSwabLong.3t \ + lib/TIFFSwabShort.3t \ + lib/TIFFScanlineSize.3t \ + lib/TIFFDefaultStripSize.3t \ + lib/TIFFVStripSize.3t \ + lib/TIFFStripSize.3t \ + lib/TIFFDefaultTileSize.3t \ + lib/TIFFVTileSize.3t \ + lib/TIFFTileSize.3t \ + lib/TIFFTileRowSize.3t \ + lib/TIFFUnRegisterCODEC.3t \ + lib/TIFFVGetField.3t \ + lib/TIFFVSetField.3t \ + lib/TIFFReadBufferSetup.3t \ + lib/TIFFWriteBufferSetup.3t \ + ${NULL} +TARGETS=apps/Makefile lib/Makefile + +# +# System-specific manual page formatting commands should +# apply this sed command to the manual page source before +# handing it to the formatter. This sets any pathnames +# in the man pages to reflect local conventions. +# +MANSED=${SED}\ + -e 's;\$${DIR_BIN};@DIR_BIN@;g' \ + -e 's;\$${DIR_LIB};@DIR_LIB@;g' \ + -e 's;\$${DIR_INC};@DIR_INC@;g' \ + ${MANSEDLOCAL} + +all: ${TARGETS} + +apps/fax2tiff.1:: ${SRCDIR}/fax2tiff.1; ${MANCVT} +apps/fax2ps.1:: ${SRCDIR}/fax2ps.1; ${MANCVT} +apps/gif2tiff.1:: ${SRCDIR}/gif2tiff.1; ${MANCVT} +apps/pal2rgb.1:: ${SRCDIR}/pal2rgb.1; ${MANCVT} +apps/ppm2tiff.1:: ${SRCDIR}/ppm2tiff.1; ${MANCVT} +apps/ras2tiff.1:: ${SRCDIR}/ras2tiff.1; ${MANCVT} +apps/rgb2ycbcr.1:: ${SRCDIR}/rgb2ycbcr.1; ${MANCVT} +apps/sgi2tiff.1:: ${SRCDIR}/sgi2tiff.1; ${MANCVT} +apps/thumbnail.1:: ${SRCDIR}/thumbnail.1; ${MANCVT} +apps/tiff2bw.1:: ${SRCDIR}/tiff2bw.1; ${MANCVT} +apps/tiff2ps.1:: ${SRCDIR}/tiff2ps.1; ${MANCVT} +apps/tiffcmp.1:: ${SRCDIR}/tiffcmp.1; ${MANCVT} +apps/tiffcp.1:: ${SRCDIR}/tiffcp.1; ${MANCVT} +apps/tiffdither.1:: ${SRCDIR}/tiffdither.1; ${MANCVT} +apps/tiffdump.1:: ${SRCDIR}/tiffdump.1; ${MANCVT} +apps/tiffgt.1:: ${SRCDIR}/tiffgt.1; ${MANCVT} +apps/tiffinfo.1:: ${SRCDIR}/tiffinfo.1; ${MANCVT} +apps/tiffmedian.1:: ${SRCDIR}/tiffmedian.1; ${MANCVT} +apps/tiffsplit.1:: ${SRCDIR}/tiffsplit.1; ${MANCVT} +apps/tiffsv.1:: ${SRCDIR}/tiffsv.1; ${MANCVT} + +lib/libtiff.3t:: ${SRCDIR}/libtiff.3t; ${MANCVT} +lib/TIFFClose.3t:: ${SRCDIR}/TIFFClose.3t; ${MANCVT} +lib/TIFFError.3t:: ${SRCDIR}/TIFFError.3t; ${MANCVT} +lib/TIFFFlush.3t:: ${SRCDIR}/TIFFFlush.3t; ${MANCVT} +lib/TIFFGetField.3t:: ${SRCDIR}/TIFFGetField.3t; ${MANCVT} +lib/TIFFOpen.3t:: ${SRCDIR}/TIFFOpen.3t; ${MANCVT} +lib/TIFFPrintDirectory.3t:: ${SRCDIR}/TIFFPrintDirectory.3t; ${MANCVT} +lib/TIFFReadDirectory.3t:: ${SRCDIR}/TIFFReadDirectory.3t; ${MANCVT} +lib/TIFFReadEncodedStrip.3t:: ${SRCDIR}/TIFFReadEncodedStrip.3t;${MANCVT} +lib/TIFFReadEncodedTile.3t:: ${SRCDIR}/TIFFReadEncodedTile.3t; ${MANCVT} +lib/TIFFReadRGBAImage.3t:: ${SRCDIR}/TIFFReadRGBAImage.3t; ${MANCVT} +lib/TIFFReadRawStrip.3t:: ${SRCDIR}/TIFFReadRawStrip.3t; ${MANCVT} +lib/TIFFReadRawTile.3t:: ${SRCDIR}/TIFFReadRawTile.3t; ${MANCVT} +lib/TIFFReadScanline.3t:: ${SRCDIR}/TIFFReadScanline.3t; ${MANCVT} +lib/TIFFReadTile.3t:: ${SRCDIR}/TIFFReadTile.3t; ${MANCVT} +lib/TIFFRGBAImage.3t:: ${SRCDIR}/TIFFRGBAImage.3t; ${MANCVT} +lib/TIFFSetDirectory.3t:: ${SRCDIR}/TIFFSetDirectory.3t; ${MANCVT} +lib/TIFFSetField.3t:: ${SRCDIR}/TIFFSetField.3t; ${MANCVT} +lib/TIFFWarning.3t:: ${SRCDIR}/TIFFWarning.3t; ${MANCVT} +lib/TIFFWriteDirectory.3t:: ${SRCDIR}/TIFFWriteDirectory.3t; ${MANCVT} +lib/TIFFWriteEncodedStrip.3t:: ${SRCDIR}/TIFFWriteEncodedStrip.3t; ${MANCVT} +lib/TIFFWriteEncodedTile.3t:: ${SRCDIR}/TIFFWriteEncodedTile.3t; ${MANCVT} +lib/TIFFWriteRawStrip.3t:: ${SRCDIR}/TIFFWriteRawStrip.3t; ${MANCVT} +lib/TIFFWriteRawTile.3t:: ${SRCDIR}/TIFFWriteRawTile.3t; ${MANCVT} +lib/TIFFWriteScanline.3t:: ${SRCDIR}/TIFFWriteScanline.3t; ${MANCVT} +lib/TIFFbuffer.3t:: ${SRCDIR}/TIFFbuffer.3t; ${MANCVT} +lib/TIFFcodec.3t:: ${SRCDIR}/TIFFcodec.3t; ${MANCVT} +lib/TIFFmemory.3t:: ${SRCDIR}/TIFFmemory.3t; ${MANCVT} +lib/TIFFquery.3t:: ${SRCDIR}/TIFFquery.3t; ${MANCVT} +lib/TIFFsize.3t:: ${SRCDIR}/TIFFsize.3t; ${MANCVT} +lib/TIFFstrip.3t:: ${SRCDIR}/TIFFstrip.3t; ${MANCVT} +lib/TIFFswab.3t:: ${SRCDIR}/TIFFswab.3t; ${MANCVT} +lib/TIFFtile.3t:: ${SRCDIR}/TIFFtile.3t; ${MANCVT} + +lib/TIFFComputeTile.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFCheckTile.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFNumberOfTiles.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFComputeStrip.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFNumberOfStrips.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFCurrentDirectory.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFCurrentRow.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFCurrentStrip.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFCurrentTile.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFFdOpen.3t:; ${ECHO} ".so ${MANDIR}TIFFOpen.3t" > $@ +lib/TIFFFileName.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFFileno.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFFlushData.3t:; ${ECHO} ".so ${MANDIR}TIFFFlush.3t" > $@ +lib/TIFFGetMode.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsTiled.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsByteSwapped.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsUpSampled.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFIsMSB2LSB.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFLastDirectory.3t:; ${ECHO} ".so ${MANDIR}TIFFquery.3t" > $@ +lib/TIFFReverseBits.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFRGBAImageOK.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFRGBAImageBegin.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFRGBAImageGet.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFRGBAImageEnd.3t:; ${ECHO} ".so ${MANDIR}TIFFRGBAImage.3t" > $@ +lib/TIFFSetErrorHandler.3t:; ${ECHO} ".so ${MANDIR}TIFFError.3t" > $@ +lib/TIFFSetSubDirectory.3t:; ${ECHO} ".so ${MANDIR}TIFFSetDirectory.3t" > $@ +lib/TIFFSetWarningHandler.3t:; ${ECHO} ".so ${MANDIR}TIFFWarning.3t" > $@ +lib/TIFFSwabArrayOfLong.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFSwabArrayOfShort.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFSwabLong.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFSwabShort.3t:; ${ECHO} ".so ${MANDIR}TIFFswab.3t" > $@ +lib/TIFFScanlineSize.3t:; ${ECHO} ".so ${MANDIR}TIFFsize.3t" > $@ +lib/TIFFRasterScanlineSize.3t:; ${ECHO} ".so ${MANDIR}TIFFsize.3t" > $@ +lib/TIFFDefaultStripSize.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFStripSize.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFVStripSize.3t:; ${ECHO} ".so ${MANDIR}TIFFstrip.3t" > $@ +lib/TIFFTileSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFVTileSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFDefaultTileSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFTileRowSize.3t:; ${ECHO} ".so ${MANDIR}TIFFtile.3t" > $@ +lib/TIFFVGetField.3t:; ${ECHO} ".so ${MANDIR}TIFFGetField.3t" > $@ +lib/TIFFVSetField.3t:; ${ECHO} ".so ${MANDIR}TIFFSetField.3t" > $@ +lib/TIFFFindCODEC.3t:; ${ECHO} ".so ${MANDIR}TIFFcodec.3t" > $@ +lib/TIFFRegisterCODEC.3t:; ${ECHO} ".so ${MANDIR}TIFFcodec.3t" > $@ +lib/TIFFUnRegisterCODEC.3t:; ${ECHO} ".so ${MANDIR}TIFFcodec.3t" > $@ +lib/TIFFmalloc.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFrealloc.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFfree.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFmemset.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFmemcpy.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFmemcmp.3t:; ${ECHO} ".so ${MANDIR}TIFFmemory.3t" > $@ +lib/TIFFReadBufferSetup.3t:; ${ECHO} ".so ${MANDIR}TIFFbuffer.3t" > $@ +lib/TIFFWriteBufferSetup.3t:; ${ECHO} ".so ${MANDIR}TIFFbuffer.3t" > $@ + +apps/Makefile: + test -d apps || mkdir apps + ${MAKE} ${MANTOOLS} + ${RM} apps/Makefile + (cd apps; \ + ${ECHO} 'install:'; \ + for i in *.1; do \ + f=${MANAPPNAME}; \ + ${ECHO} ' cd ..; ${INSTALL} -m 444 -F ${MAN}/${MANAPPS} \ + -idb tiff.man.tools -src' apps/"$$i" '-O' "$$f"; \ + done \ + )>apps/Makefile +lib/Makefile: + test -d lib || mkdir lib + ${MAKE} ${MANDEV} ${MANDEVLINKS} + ${RM} lib/Makefile + (cd lib; \ + ${ECHO} 'install:'; \ + for i in *.3t; do \ + f=${MANLIBNAME}; \ + ${ECHO} ' cd ..; ${INSTALL} -m 444 -F ${MAN}/${MANLIB} \ + -idb tiff.man.dev -src' lib/"$$i" '-O' "$$f"; \ + done \ + )>lib/Makefile + +install: all + ${INSTALL} -m 755 -dir -idb tiff.man.tools ${MAN} + ${INSTALL} -m 755 -dir -idb tiff.man.tools ${MAN}/${MANAPPS} + cd apps; ${MAKE} install + ${INSTALL} -m 755 -dir -idb tiff.man.dev ${MAN}/${MANLIB} + cd lib; ${MAKE} install + +clean: + rm -rf apps lib + +# +# Miscellaneous junk left over... +# + +links: ${MANDEVLINKS} + +short: + ${MV} TIFFClose.3t close.3t + ${MV} TIFFError.3t error.3t + ${MV} TIFFFlush.3t flush.3t + ${MV} TIFFGetField.3t getfield.3t + ${MV} TIFFOpen.3t open.3t + ${MV} TIFFPrintDirectory.3t print.3t + ${MV} TIFFReadEncodedStrip.3t rdestrip.3t + ${MV} TIFFReadencodedTile.3t rdetile.3t + ${MV} TIFFReadRawStrip.3t rdrstrip.3t + ${MV} TIFFReadRawTile.3t rdrtile.3t + ${MV} TIFFReadDirectory.3t readdir.3t + ${MV} TIFFReadRGBAImage.3t rdimage.3t + ${MV} TIFFReadScanline.3t readline.3t + ${MV} TIFFReadTile.3t readtile.3t + ${MV} TIFFRGBAImage.3t rgbaimage.3t + ${MV} TIFFSetDirectory.3t setdir.3t + ${MV} TIFFSetField.3t setfield.3t + ${MV} TIFFWarning.3t warning.3t + ${MV} TIFFWriteEncodedStrip.3t wrestrip.3t + ${MV} TIFFWriteEncodedTile.3t wretile.3t + ${MV} TIFFWriteDirectory.3t writedir.3t + ${MV} TIFFWriteRawStrip.3t wrrstrip.3t + ${MV} TIFFWriteRawTile.3t wrrtile.3t + ${MV} TIFFWriteScanline.3t writeline.3t + ${MV} TIFFtile.3t tile.3t + ${MV} TIFFstrip.3t strip.3t + ${MV} TIFFquery.3t query.3t + ${MV} TIFFswab.3t swab.3t + ${MV} TIFFsize.3t size.3t + ${MV} TIFFcodec.3t codec.3t + ${MV} TIFFmemory.3t memory.3t + ${MV} TIFFbuffer.3t buffer.3t diff --git a/man/TIFFClose.3t b/man/TIFFClose.3t new file mode 100644 index 00000000..9b9072cb --- /dev/null +++ b/man/TIFFClose.3t @@ -0,0 +1,51 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFClose.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFClose 3T "May 2, 1990" +.SH NAME +TIFFClose \- close a previously opened +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "void TIFFClose(TIFF* tif)" +.SH DESCRIPTION +.IR TIFFClose +closes a file that was previously opened with +.IR TIFFOpen (3T). +Any buffered data are flushed to the file, including the contents of +the current directory (if modified); and all resources +are reclaimed. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +Likewise, warning messages are directed to the +.IR TIFFWarning (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T) diff --git a/man/TIFFError.3t b/man/TIFFError.3t new file mode 100644 index 00000000..5d91f761 --- /dev/null +++ b/man/TIFFError.3t @@ -0,0 +1,69 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFError.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFError 3T "October 15, 1995" +.SH NAME +TIFFError, TIFFSetErrorHandler \- library error handling interface +.SH SYNOPSIS +.B "#include " +.br +.B "void TIFFError(const char* module, const char* fmt, ...)" +.sp .5 +.B "#include " +.br +.B "typedef void (*TIFFErrorHandler)(const char* module, const char* fmt, va_list ap);" +.br +.B "TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler);" +.SH DESCRIPTION +.I TIFFError +invokes the library-wide error handling function +to (normally) write an error message to the +.BR stderr . +The +.I fmt +parameter is a +.IR printf (3S) +format string, and any number arguments can be supplied. +The +.I module +parameter, if non-zero, is printed before the message; it typically +is used to identify the software module in which an error +is detected. +.PP +Applications that desire to capture control in the event of an error +should use +.IR TIFFSetErrorHandler +to override the default error handler. +A +.SM NULL +(0) error handling function may be installed to +suppress error messages. +.SH "RETURN VALUES" +.IR TIFFSetErrorHandler +returns a reference to the previous error handling function. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFWarning (3T), +.IR printf (3S) diff --git a/man/TIFFFlush.3t b/man/TIFFFlush.3t new file mode 100644 index 00000000..01873426 --- /dev/null +++ b/man/TIFFFlush.3t @@ -0,0 +1,64 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFFlush.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFFlush 3T "December 16, 1991" +.SH NAME +TIFFFlush, TIFFFlushData \- flush pending writes to an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFFlush(TIFF* tif)" +.br +.B "int TIFFFlushData(TIFF* tif)" +.SH DESCRIPTION +.IR TIFFFlush +causes any pending writes for the specified file (including writes +for the current directory) +to be done. +In normal operation this call is never needed\- the library +automatically does any flushing required. +.PP +.IR TIFFFlushData +flushes any pending image data for the specified file to be written out; +directory-related data are not flushed. +In normal operation this call is never needed\- the library +automatically does any flushing required. +.SH "RETURN VALUES" +0 is returned if an error is encountered, otherwise 1 is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteEncodedStrip (3T), +.IR TIFFWriteEncodedTile (3T), +.IR TIFFWriteRawStrip (3T), +.IR TIFFWriteRawTile (3T), +.IR TIFFWriteScanline (3T), +.IR TIFFWriteTile (3T) diff --git a/man/TIFFGetField.3t b/man/TIFFGetField.3t new file mode 100644 index 00000000..df12f4af --- /dev/null +++ b/man/TIFFGetField.3t @@ -0,0 +1,210 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFGetField.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFGetField 3T "August 22, 1997" +.SH NAME +TIFFGetField, TIFFVGetField \- get the value(s) of a tag in an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFGetField(TIFF* tif, ttag_t tag, ...)" +.sp 5p +.B "#include " +.br +.B "int TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)" +.sp 5p +.B "int TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...)" +.br +.B "int TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)" +.SH DESCRIPTION +.IR TIFFGetField +returns the value of a tag or pseudo-tag associated with the +the current directory of the open +.SM TIFF +file +.IR tif . +(A +.I pseudo-tag +is a parameter that is used to control the operation of the +.SM TIFF +library but whose value is not read or written to the underlying file.) +The file must have been previously opened with +.IR TIFFOpen (3T). +The tag is identified by +.IR tag , +one of the values defined in the include file +.B tiff.h +(see also the table below). +The type and number of values returned is dependent +on the tag being requested. +The programming interface uses a variable argument list +as prescribed by the +.IR stdarg (3) +interface. +The returned values should only be interpreted if +.IR TIFFGetField +returns 1. +.PP +.IR TIFFVGetField +is functionally equivalent to +.IR TIFFGetField +except that it takes a pointer to a variable +argument list. +.I TIFFVGetField +is useful for layering interfaces on top of +the functionality provided by +.IR TIFFGetField . +.PP +.IR TIFFGetFieldDefaulted +and +.IR TIFFVGetFieldDefaulted +are identical to +.IR TIFFGetField +and +.IR TIFFVGetField , +except that if a tag is not defined in the current directory +and it has a default value, then the default value is returned. +.PP +The tags understood by +.IR libtiff , +the number of parameter values, and the +types for the returned values are shown below. +The data types are specified as in C and correspond +to the types used to specify tag values to +.IR TIFFSetField (3T). +Remember that +.IR TIFFGetField +returns parameter values, so all the listed +data types are pointers to storage where values +should be returned. +Consult the +.SM TIFF +specification for information on the meaning of +each tag and their possible values. +.PP +.nf +.ta \w'TIFFTAG_CONSECUTIVEBADFAXLINES'u+2n +\w'Count'u+2n +\w'TIFFFaxFillFunc*'u+2n +\fITag Name\fP \fICount\fP \fITypes\fP \fINotes\fP +.sp 5p +TIFFTAG_ARTIST 1 char** +TIFFTAG_BADFAXLINES 1 uint32* +TIFFTAG_BITSPERSAMPLE 1 uint16* +TIFFTAG_CLEANFAXDATA 1 uint16* +TIFFTAG_COLORMAP 3 uint16** 1<" +.B "TIFF* TIFFOpen(const char* filename, const char* mode)" +.sp 5p +.B "TIFF* TIFFFdOpen(const int fd, const char* filename, const char* mode)" +.sp 5p +.B "typedef tsize_t (*TIFFReadWriteProc)(thandle_t, tdata_t, tsize_t);" +.B "typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);" +.B "typedef int (*TIFFCloseProc)(thandle_t);" +.B "typedef toff_t (*TIFFSizeProc)(thandle_t);" +.B "typedef int (*TIFFMapFileProc)(thandle_t, tdata_t*, toff_t*);" +.B "typedef void (*TIFFUnmapFileProc)(thandle_t, tdata_t, toff_t);" +.sp 5p +.B "TIFF* TIFFClientOpen(const char* filename, const char* mode, thandle_t clientdata," +.B " TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc," +.B " TIFFCloseProc closeproc, TIFFSizeProc sizeproc, TIFFMapFileProc mapproc," +.B " TIFFUnmapFileProc unmapproc)" +.fi +.SH DESCRIPTION +.IR TIFFOpen +opens a +.SM TIFF +file whose name is +.I filename +and returns a handle to be used in subsequent calls to routines in +.IR libtiff . +If the open operation fails, then zero is returned. +The +.I mode +parameter specifies if the file is to be opened for reading (``r''), +writing (``w''), or appending (``a'') and, optionally, whether +to override certain default aspects of library operation (see below). +When a file is opened for appending, existing data will not +be touched; instead new data will be written as additional subfiles. +If an existing file is opened for writing, all previous data is +overwritten. +.PP +If a file is opened for reading, the first +.SM TIFF +directory in the file is automatically read +(also see +.IR TIFFSetDirectory (3T) +for reading directories other than the first). +If a file is opened for writing or appending, a default directory +is automatically created for writing subsequent data. +This directory has all the default values specified in +.SM TIFF +Revision 6.0: +.IR BitsPerSample =1, +.IR ThreshHolding "=bilevel art scan," +.IR FillOrder =1 +(most significant bit of each data byte is filled first), +.IR Orientation =1 +(the 0th row represents the visual top of the image, and the 0th +column represents the visual left hand side), +.IR SamplesPerPixel =1, +.IR RowsPerStrip =infinity, +.IR ResolutionUnit =2 +(inches), and +.IR Compression =1 +(no compression). +To alter these values, or to define values for additional fields, +.IR TIFFSetField (3T) +must be used. +.PP +.IR TIFFFdOpen +is like +.IR TIFFOpen +except that it opens a +.SM TIFF +file given an open file descriptor +.IR fd . +The file's name and mode must reflect that of the open descriptor. +The object associated with the file descriptor +.BR "must support random access" . +.PP +.IR TIFFClientOpen +is like +.IR TIFFOpen +except that the caller supplies a collection of functions that the +library will use to do \s-1UNIX\s+1-like I/O operations. +The +.I readproc +and +.I writeproc +are called to read and write data at the current file position. +.I seekproc +is called to change the current file position a la +.IR lseek (2). +.I closeproc +is invoked to release any resources associated with an open file. +.I sizeproc +is invoked to obtain the size in bytes of a file. +.I mapproc +and +.I unmapproc +are called to map and unmap a file's contents in memory; c.f. +.IR mmap (2) +and +.IR munmap (2). +The +.I clientdata +parameter is an opaque ``handle'' passed to the client-specified +routines passed as parameters to +.IR TIFFClientOpen . +.SH OPTIONS +The open mode parameter can include the following flags in +addition to the ``r'', ``w'', and ``a'' flags. +Note however that option flags must follow the read-write-append +specification. +.TP +.B l +When creating a new file force information be written with +Little-Endian byte order (but see below). +By default the library will create new files using the native +.SM CPU +byte order. +.TP +.B b +When creating a new file force information be written with +Big-Endian byte order (but see below). +By default the library will create new files using the native +.SM CPU +byte order. +.TP +.B L +Force image data that is read or written to be treated with +bits filled from Least Significant Bit (\s-1LSB\s+1) to +Most Significant Bit (\s-1MSB\s+1). +Note that this is the opposite to the way the library has +worked from its inception. +.TP +.B B +Force image data that is read or written to be treated with +bits filled from Most Significant Bit (\s-1MSB\s+1) to +Least Significant Bit (\s-1LSB\s+1); this is the default. +.TP +.B H +Force image data that is read or written to be treated with +bits filled in the same order as the native +.SM CPU. +.TP +.B M +Enable the use of memory-mapped files for images opened read-only. +If the underlying system does not support memory-mapped files +or if the specific image being opened cannot be memory-mapped +then the library will fallback to using the normal system interface +for reading information. +By default the library will attempt to use memory-mapped files. +.TP +.B m +Disable the use of memory-mapped files. +.TP +.B C +Enable the use of ``strip chopping'' when reading images +that are comprised of a single strip or tile of uncompressed data. +Strip chopping is a mechanism by which the library will automatically +convert the single-strip image to multiple strips, +each of which has about 8 Kilobytes of data. +This facility can be useful in reducing the amount of memory used +to read an image because the library normally reads each strip +in its entirety. +Strip chopping does however alter the apparent contents of the +image because when an image is divided into multiple strips it +looks as though the underlying file contains multiple separate +strips. +Finally, note that default handling of strip chopping is a compile-time +configuration parameter. +The default behaviour, for backwards compatibility, is to enable +strip chopping. +.TP +.B c +Disable the use of strip chopping when reading images. +.SH "BYTE ORDER" +The +.SM TIFF +specification (\fBall versions\fP) states that compliant readers +.IR "must be capable of reading images written in either byte order" . +Nonetheless some software that claims to support the reading of +.SM TIFF +images is incapable of reading images in anything but the native +.SM CPU +byte order on which the software was written. +(Especially notorious +are applications written to run on Intel-based machines.) +By default the library will create new files with the native +byte-order of the +.SM CPU +on which the application is run. +This ensures optimal performance and is portable to any application +that conforms to the TIFF specification. +To force the library to use a specific byte-order when creating +a new file the ``b'' and ``l'' option flags may be included in +the call to open a file; for example, ``wb'' or ``wl''. +.SH "RETURN VALUES" +Upon successful completion +.IR TIFFOpen , +.IR TIFFFdOpen , +and +.IR TIFFClientOpen +return a +.SM TIFF +pointer. +Otherwise, NULL is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +Likewise, warning messages are directed to the +.IR TIFFWarning (3T) +routine. +.PP +\fB"%s": Bad mode\fP. +The specified +.I mode +parameter was not one of ``r'' (read), ``w'' (write), or ``a'' (append). +.PP +.BR "%s: Cannot open" . +.IR TIFFOpen () +was unable to open the specified filename for read/writing. +.PP +.BR "Cannot read TIFF header" . +An error occurred while attempting to read the header information. +.PP +.BR "Error writing TIFF header" . +An error occurred while writing the default header information +for a new file. +.PP +.BR "Not a TIFF file, bad magic number %d (0x%x)" . +The magic number in the header was not (hex) +0x4d4d or (hex) 0x4949. +.PP +.BR "Not a TIFF file, bad version number %d (0x%x)" . +The version field in the header was not 42 (decimal). +.PP +.BR "Cannot append to file that has opposite byte ordering" . +A file with a byte ordering opposite to the native byte +ordering of the current machine was opened for appending (``a''). +This is a limitation of the library. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFClose (3T) diff --git a/man/TIFFPrintDirectory.3t b/man/TIFFPrintDirectory.3t new file mode 100644 index 00000000..b03866dc --- /dev/null +++ b/man/TIFFPrintDirectory.3t @@ -0,0 +1,71 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFPrintDirectory.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFPrintDirectory 3T "December 12, 1991" +.SH NAME +TIFFPrintDirectory \- print a description of a +.SM TIFF +directory +.SH SYNOPSIS +.B "#include " +.br +.B "void TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)" +.SH DESCRIPTION +.I TIFFPrintDirectory +prints a description of the current directory in the specified +.SM TIFF +file to the standard I/O output stream +.IR fd . +The +.I flags +parameter is used to control the +.I "level of detail" +of the printed information; it is a bit-or of the flags +defined in +.BR tiffio.h : +.sp .5 +.nf +.ta \w'#define 'u +\w'TIFFPRINT_JPEGDCTABLES 'u +\w'0x200 'u +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ +.fi +.SH NOTES +In C++ the +.I flags +parameter defaults to 0. +.SH "RETURN VALUES" +None. +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadDirectory (3T), +.IR TIFFSetDirectory (3T) diff --git a/man/TIFFRGBAImage.3t b/man/TIFFRGBAImage.3t new file mode 100644 index 00000000..bd47d6ab --- /dev/null +++ b/man/TIFFRGBAImage.3t @@ -0,0 +1,275 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFRGBAImage.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFRGBAImage 3T "October 15, 1995" +.SH NAME +TIFFRGBAImage \- read and decode an image into a raster +.SH SYNOPSIS +.nf +.B "#include " +.B "typedef unsigned char TIFFRGBValue;" +.B "typedef struct _TIFFRGBAImage TIFFRGBAImage;" +.B "int TIFFRGBAImageOK(TIFF* tif, char emsg[1024]);" +.B "int TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stopOnError, char emsg[1024]);" +.B "int TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 width, uint32 height);" +.B "void TIFFRGBAImageEnd(TIFFRGBAImage* img);" +.SH DESCRIPTION +The routines described here provide a high-level interface +through which +.SM TIFF +images may be read into memory. +Images may be strip- or tile-based and have a variety of different +characteristics: bits/sample, samples/pixel, photometric, etc. +Decoding state is encapsulated in a +.I TIFFRGBAImage +structure making it possible to capture state for multiple images +and quickly switch between them. +The target raster format can be customized to a particular application's +needs by installing custom routines that manipulate image data +according to application requirements. +.PP +The default usage for these routines is: check if an image can +be processed using +.IR TIFFRGBAImageOK , +construct a decoder state block using +.IR TIFFRGBAImageBegin , +read and decode an image into a target raster using +.IR TIFFRGBAImageGet , +and then +release resources using +.IR TIFFRGBAImageEnd . +.I TIFFRGBAImageGet +can be called multiple times to decode an image using different +state parameters. +If multiple images are to be displayed and there is not enough +space for each of the decoded rasters, multiple state blocks can +be managed and then calls can be made to +.I TIFFRGBAImageGet +as needed to display an image. +.PP +The generated raster is assumed to be an array of +.I width +times +.I height +32-bit entries, where +.I width +must be less than or equal to the width of the image (\c +.I height +may be any non-zero size). +If the raster dimensions are smaller than the image, the image data +is cropped to the raster bounds. +If the raster height is greater than that of the image, then the +image data are placed in the lower part of the raster. +(Note that the raster is assume to be organized such that the pixel +at location (\fIx\fP,\fIy\fP) is \fIraster\fP[\fIy\fP*\fIwidth\fP+\fIx\fP]; +with the raster origin in the lower-left hand corner.) +.PP +Raster pixels are 8-bit packed red, green, blue, alpha samples. +The macros +.IR TIFFGetR , +.IR TIFFGetG , +.IR TIFFGetB , +and +.I TIFFGetA +should be used to access individual samples. +Images without Associated Alpha matting information have a constant +Alpha of 1.0 (255). +.PP +.I TIFFRGBAImageGet +converts non-8-bit images by scaling sample values. +Palette, grayscale, bilevel, +.SM CMYK\c +, and YCbCr images are converted to +.SM RGB +transparently. +Raster pixels are returned uncorrected by any colorimetry information +present in the directory. +.PP +The paramater +.I stopOnError +specifies how to act if an error is encountered while reading +the image. +If +.I stopOnError +is non-zero, then an error will terminate the operation; otherwise +.I TIFFRGBAImageGet +will continue processing data until all the possible data in the +image have been requested. +.SH "ALTERNATE RASTER FORMATS" +To use the core support for reading and processing +.SM TIFF +images, but write the resulting raster data in a different format +one need only override the ``\fIput methods\fP'' used to store raster data. +These methods are are defined in the +.I TIFFRGBAImage +structure and initially setup by +.I TIFFRGBAImageBegin +to point to routines that pack raster data in the default +.SM ABGR +pixel format. +Two different routines are used according to the physical organization +of the image data in the file: +.IR PlanarConfiguration =1 +(packed samples), +and +.IR PlanarConfiguration =2 +(separated samples). +Note that this mechanism can be used to transform the data before +storing it in the raster. +For example one can convert data +to colormap indices for display on a colormap display. +.SH "SIMULTANEOUS RASTER STORE AND DISPLAY" +It is simple to display an image as it is being read into memory +by overriding the put methods as described above for supporting +alternate raster formats. +Simply keep a reference to the default put methods setup by +.I TIFFRGBAImageBegin +and then invoke them before or after each display operation. +For example, the +.IR tiffgt (1) +utility uses the following put method to update the display as +the raster is being filled: +.sp +.nf +.ft C +static void +putContigAndDraw(TIFFRGBAImage* img, uint32* raster, + uint32 x, uint32 y, uint32 w, uint32 h, + int32 fromskew, int32 toskew, + unsigned char* cp) +{ + (*putContig)(img, raster, x, y, w, h, fromskew, toskew, cp); + if (x+w == width) { + w = width; + if (img->orientation == ORIENTATION_TOPLEFT) + lrectwrite(0, y-(h-1), w-1, y, raster-x-(h-1)*w); + else + lrectwrite(0, y, w-1, y+h-1, raster); + } +} +.ft R +.fi +.sp +(the original routine provided by the library is saved in the +variable +.IR putContig .) +.SH "SUPPORTING ADDITIONAL TIFF FORMATS" +The +.I TIFFRGBAImage +routines support the most commonly encountered flavors of +.SM TIFF. +It is possible to extend this support by overriding the ``\fIget method\fP'' +invoked by +.I TIFFRGBAImageGet +to read +.SM TIFF +image data. +Details of doing this are a bit involved, it is best to make a copy +of an existing get method and modify it to suit the needs of an +application. +.SH NOTES +Samples must be either 1, 2, 4, 8, or 16 bits. +Colorimetric samples/pixel must be either 1, 3, or 4 (i.e. +.I SamplesPerPixel +minus +.IR ExtraSamples ). +.PP +Palettte image colormaps that appear to be incorrectly written +as 8-bit values are automatically scaled to 16-bits. +.SH "RETURN VALUES" +All routines return +1 if the operation was successful. +Otherwise, 0 is returned if an error was encountered and +.I stopOnError +is zero. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +.BR "Sorry, can not handle %d-bit pictures" . +The image had +.I BitsPerSample +other than 1, 2, 4, 8, or 16. +.PP +.BR "Sorry, can not handle %d-channel images" . +The image had +.I SamplesPerPixel +other than 1, 3, or 4. +.PP +\fBMissing needed "PhotometricInterpretation" tag\fP. +The image did not have a tag that describes how to display +the data. +.PP +\fBNo "PhotometricInterpretation" tag, assuming RGB\fP. +The image was missing a tag that describes how to display it, +but because it has 3 or 4 samples/pixel, it is assumed to be +.SM RGB. +.PP +\fBNo "PhotometricInterpretation" tag, assuming min-is-black\fP. +The image was missing a tag that describes how to display it, +but because it has 1 sample/pixel, it is assumed to be a grayscale +or bilevel image. +.PP +.BR "No space for photometric conversion table" . +There was insufficient memory for a table used to convert +image samples to 8-bit +.SM RGB. +.PP +\fBMissing required "Colormap" tag\fP. +A Palette image did not have a required +.I Colormap +tag. +.PP +.BR "No space for tile buffer" . +There was insufficient memory to allocate an i/o buffer. +.PP +.BR "No space for strip buffer" . +There was insufficient memory to allocate an i/o buffer. +.PP +.BR "Can not handle format" . +The image has a format (combination of +.IR BitsPerSample , +.IR SamplesPerPixel , +and +.IR PhotometricInterpretation ) +that can not be handled. +.PP +.BR "No space for B&W mapping table" . +There was insufficient memory to allocate a table used to map +grayscale data to +.SM RGB. +.PP +.BR "No space for Palette mapping table" . +There was insufficient memory to allocate a table used to map +data to 8-bit +.SM RGB. +.SH BUGS +Orientations other than bottom-left, or top-left are +not handled correctly. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadRGBAImage (3T) diff --git a/man/TIFFReadDirectory.3t b/man/TIFFReadDirectory.3t new file mode 100644 index 00000000..7d079a41 --- /dev/null +++ b/man/TIFFReadDirectory.3t @@ -0,0 +1,164 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadDirectory.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadDirectory 3T "October 15, 1995" +.SH NAME +TIFFReadDirectory \- get the contents of the next directory in an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFReadDirectory(TIFF* tif)" +.SH DESCRIPTION +Read the next directory in the specified file and make it the +current directory. +Applications only need to call +.I TIFFReadDirectory +to read multiple subfiles in a single +.SM TIFF +file\(em +the first directory in a file is automatically read when +.IR TIFFOpen +is called. +.SH NOTES +If the library is compiled with +.SM STRIPCHOP_SUPPORT +enabled, then images that have a single uncompressed strip or +tile of data are automatically treated as if they were made +up of multiple strips or tiles of approximately 8 kilobytes each. +This operation is done only in-memory; it does not alter the +contents of the file. +However, the construction of the ``chopped strips'' is visible +to the application through the number of strips [tiles] +returned by +.I TIFFNumberOfStrips +[\c +.IR TIFFNumberOfTiles ]. +.SH "RETURN VALUES" +If the next directory was successfully read, 1 is returned. +Otherwise, 0 is returned if an error was encountered, +or if there are no more directories to be read. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +All warning messages are directed to the +.IR TIFFWarning (3T) +routine. +.PP +\fBSeek error accessing TIFF directory\fP. +An error occurred while positioning to the location of the +directory. +.PP +\fBWrong data type %d for field "%s"\fP. +The tag entry in the directory had an incorrect data type. +For example, an +.I ImageDescription +tag with a +.SM SHORT +data type. +.PP +\fBTIFF directory is missing required "%s" field\fP. +The specified tag is required to be present by the +.SM TIFF +5.0 specification, but is missing. +The directory is (usually) unusable. +.PP +\fB%s: Rational with zero denominator\fP. +A directory tag has a +.SM RATIONAL +value whose denominator is zero. +.PP +\fBIncorrect count %d for field "%s" (%lu, expecting %lu); tag ignored\fP. +The specified tag's count field is bad. +For example, a count other than 1 for a +.I SubFileType +tag. +.PP +\fBCannot handle different per-sample values for field "%s"\fP. +The tag has +.I SamplesPerPixel +values and they are not all the same; e.g. +.IR BitsPerSample . +The library is unable to handle images of this sort. +.PP +\fBCount mismatch for field "%s"; expecting %d, got %d\fP. +The count field in a +tag does not agree with the number expected by the library. +This should never happen, so if it does, the library refuses to +read the directory. +.PP +\fBInvalid TIFF directory; tags are not sorted in ascending order\fP. +The directory tags are not properly sorted as specified +in the +.SM TIFF +5.0 specification. +This error is not fatal. +.PP +\fBIgnoring unknown field with tag %d (0x%x)\fP. +An unknown tag was encountered in the directory; +the library ignores all such tags. +.PP +\fBTIFF directory is missing requred "ImageLength" field\fP. +The image violates the specification by not having a necessary field. +There is no way for the library to recover from this error. +.PP +\fBTIFF directory is missing requred "PlanarConfig" field\fP. +The image violates the specification by not having a necessary field. +There is no way for the library to recover from this error. +.PP +\fBTIFF directory is missing requred "StripOffsets" field\fP. +The image has multiple strips, but is missing the tag that +specifies the file offset to each strip of data. +There is no way for the library to recover from this error. +.PP +\fBTIFF directory is missing requred "TileOffsets" field\fP. +The image has multiple tiles, but is missing the tag that +specifies the file offset to each tile of data. +There is no way for the library to recover from this error. +.PP +\fBTIFF directory is missing required "StripByteCounts" field\fP. +The image has multiple strips, but is missing the tag that +specifies the size of each strip of data. +There is no way for the library to recover from this error. +.PP +\fBTIFF directory is missing required "StripByteCounts" field, calculating from imagelength\fP. +The image violates the specification by not having a necessary field. +However, when the image is comprised of only one strip or tile, the +library will estimate the missing value based on the file size. +.PP +\fBBogus "StripByteCounts" field, ignoring and calculating from imagelength\fP. +Certain vendors violate the specification by writing zero for +the StripByteCounts tag when they want to leave the value +unspecified. +If the image has a single strip, the library will estimate +the missing value based on the file size. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteDirectory (3T), +.IR TIFFSetDirectory (3T), +.IR TIFFSetSubDirectory (3T) diff --git a/man/TIFFReadEncodedStrip.3t b/man/TIFFReadEncodedStrip.3t new file mode 100644 index 00000000..17eb325f --- /dev/null +++ b/man/TIFFReadEncodedStrip.3t @@ -0,0 +1,73 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadEncodedStrip.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadEncodedStrip 3T "October 15, 1995" +.SH NAME +TIFFReadEncodedStrip \- read and decode a strip of data from an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Read the specified strip of data and place up to +.I size +bytes of decompressed information in the (user supplied) data buffer. +.SH NOTES +The value of +.I strip +is a ``raw strip number.'' +That is, the caller must take into account whether or not the +data are organized in separate planes (\c +.IR PlanarConfiguration =2). +To read a full strip of data the data buffer should typically be +at least as large as the number returned by +.IR TIFFStripSize (3T). +.PP +The library attempts to hide bit- and byte-ordering differences +between the image and the native machine by converting data +to the native machine order. +Bit reversal is done if the +.I FillOrder +tag is opposite to the native machine bit order. +16- and 32-bit samples are automatically byte-swapped if the +file was written with a byte order opposite to the native +machine byte order, +.SH "RETURN VALUES" +The actual number of bytes of data that were placed in +.I buf +is returned; +.IR TIFFReadEncodedStrip +returns \-1 if an error was encountered. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadRawStrip (3T), +.IR TIFFReadScanline (3T) diff --git a/man/TIFFReadEncodedTile.3t b/man/TIFFReadEncodedTile.3t new file mode 100644 index 00000000..bfcdd9bb --- /dev/null +++ b/man/TIFFReadEncodedTile.3t @@ -0,0 +1,76 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadEncodedTile.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadEncodedTile 3T "October 15, 1995" +.SH NAME +TIFFReadEncodedTile \- read and decode a tile of data from an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFReadEncodedTile(TIFF* tif, u_long tile, u_char* buf, u_long size)" +.SH DESCRIPTION +Read the specified tile of data and place up to +.I size +bytes of decompressed information in the (user supplied) data buffer. +.SH NOTES +The value of +.I tile +is a ``raw tile number.'' +That is, the caller must take into account whether or not the +data are organized in separate planes (\c +.IR PlanarConfiguration =2). +.IR TIFFComputeTile +automatically does this when converting an (x,y,z,sample) +coordinate quadruple to a tile number. +To read a full tile of data the data buffer should be +at least as large as the value returned by +.IR TIFFTileSize . +.PP +The library attempts to hide bit- and byte-ordering differences +between the image and the native machine by converting data +to the native machine order. +Bit reversal is done if the +.I FillOrder +tag is opposite to the native machine bit order. +16- and 32-bit samples are automatically byte-swapped if the +file was written with a byte order opposite to the native +machine byte order, +.SH "RETURN VALUES" +The actual number of bytes of data that were placed in +.I buf +is returned; +.IR TIFFReadEncodedTile +returns \-1 if an error was encountered. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadRawTile (3T), +.IR TIFFReadTile (3T) diff --git a/man/TIFFReadRGBAImage.3t b/man/TIFFReadRGBAImage.3t new file mode 100644 index 00000000..2710cca0 --- /dev/null +++ b/man/TIFFReadRGBAImage.3t @@ -0,0 +1,185 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadRGBAImage.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadRGBAImage 3T "February 14, 1992" +.SH NAME +TIFFReadRGBAImage \- read and decode an image into a fixed-format raster +.SH SYNOPSIS +.nf +.B "#include " +.ta \w'\fB#define \fP'u +\w'\fBTIFFGetR(abgr) \fP'u +.B "#define TIFFGetR(abgr) ((abgr) & 0xff)" +.B "#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)" +.B "#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)" +.B "#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)" +.sp 5p +.B "int TIFFReadRGBAImage(TIFF* tif, u_long width, u_long height, u_long* raster, int stopOnError)" +.SH DESCRIPTION +.IR TIFFReadRGBAImage +reads a strip- or tile-based image into memory, storing the +result in the user supplied +.IR raster . +The raster is assumed to be an array of +.I width +times +.I height +32-bit entries, where +.I width +must be less than or equal to the width of the image (\c +.I height +may be any non-zero size). +If the raster dimensions are smaller than the image, the image data +is cropped to the raster bounds. +If the raster height is greater than that of the image, then the +image data are placed in the lower part of the raster. +(Note that the raster is assume to be organized such that the pixel +at location (\fIx\fP,\fIy\fP) is \fIraster\fP[\fIy\fP*\fIwidth\fP+\fIx\fP]; +with the raster origin in the lower-left hand corner.) +.PP +Raster pixels are 8-bit packed red, green, blue, alpha samples. +The macros +.IR TIFFGetR , +.IR TIFFGetG , +.IR TIFFGetB , +and +.I TIFFGetA +should be used to access individual samples. +Images without Associated Alpha matting information have a constant +Alpha of 1.0 (255). +.PP +.I TIFFReadRGBAImage +converts non-8-bit images by scaling sample values. +Palette, grayscale, bilevel, +.SM CMYK\c +, and YCbCr images are converted to +.SM RGB +transparently. +Raster pixels are returned uncorrected by any colorimetry information +present in the directory. +.PP +The paramater +.I stopOnError +specifies how to act if an error is encountered while reading +the image. +If +.I stopOnError +is non-zero, then an error will terminate the operation; otherwise +.I TIFFReadRGBAImage +will continue processing data until all the possible data in the +image have been requested. +.SH NOTES +In C++ the +.I stopOnError +parameter defaults to 0. +.PP +Samples must be either 1, 2, 4, 8, or 16 bits. +Colorimetric samples/pixel must be either 1, 3, or 4 (i.e. +.I SamplesPerPixel +minus +.IR ExtraSamples ). +.PP +Palettte image colormaps that appear to be incorrectly written +as 8-bit values are automatically scaled to 16-bits. +.PP +.I TIFFReadRGBAImage +is just a wrapper around the more general +.IR TIFFRGBAImage (3T) +facilities. +.SH "RETURN VALUES" +1 is returned if the image was successfully read and converted. +Otherwise, 0 is returned if an error was encountered and +.I stopOnError +is zero. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +.BR "Sorry, can not handle %d-bit pictures" . +The image had +.I BitsPerSample +other than 1, 2, 4, 8, or 16. +.PP +.BR "Sorry, can not handle %d-channel images" . +The image had +.I SamplesPerPixel +other than 1, 3, or 4. +.PP +\fBMissing needed "PhotometricInterpretation" tag\fP. +The image did not have a tag that describes how to display +the data. +.PP +\fBNo "PhotometricInterpretation" tag, assuming RGB\fP. +The image was missing a tag that describes how to display it, +but because it has 3 or 4 samples/pixel, it is assumed to be +.SM RGB. +.PP +\fBNo "PhotometricInterpretation" tag, assuming min-is-black\fP. +The image was missing a tag that describes how to display it, +but because it has 1 sample/pixel, it is assumed to be a grayscale +or bilevel image. +.PP +.BR "No space for photometric conversion table" . +There was insufficient memory for a table used to convert +image samples to 8-bit +.SM RGB. +.PP +\fBMissing required "Colormap" tag\fP. +A Palette image did not have a required +.I Colormap +tag. +.PP +.BR "No space for tile buffer" . +There was insufficient memory to allocate an i/o buffer. +.PP +.BR "No space for strip buffer" . +There was insufficient memory to allocate an i/o buffer. +.PP +.BR "Can not handle format" . +The image has a format (combination of +.IR BitsPerSample , +.IR SamplesPerPixel , +and +.IR PhotometricInterpretation ) +that +.I TIFFReadRGBAImage +can not handle. +.PP +.BR "No space for B&W mapping table" . +There was insufficient memory to allocate a table used to map +grayscale data to +.SM RGB. +.PP +.BR "No space for Palette mapping table" . +There was insufficient memory to allocate a table used to map +data to 8-bit +.SM RGB. +.SH BUGS +Orientations other than bottom-left, or top-left are +not handled correctly. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFRGBAImage (3T) diff --git a/man/TIFFReadRawStrip.3t b/man/TIFFReadRawStrip.3t new file mode 100644 index 00000000..dbe67abe --- /dev/null +++ b/man/TIFFReadRawStrip.3t @@ -0,0 +1,63 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadRawStrip.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadRawStrip 3T "October 15, 1995" +.SH NAME +TIFFReadRawStrip \- return the undecoded contents +of a strip of data from an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Read the contents of the specified strip into the +(user supplied) data buffer. +Note that the value of +.I strip +is a ``raw strip number.'' +That is, the caller must take into account whether or not the +data is organized in separate planes (\c +.IR PlanarConfiguration =2). +To read a full strip of data the data buffer should typically be +at least as large as the number returned by +.IR TIFFStripSize . +.SH "RETURN VALUES" +The actual number of bytes of data that were placed in +.I buf +is returned; +.IR TIFFReadEncodedStrip +returns \-1 if an error was encountered. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadEncodedStrip (3T), +.IR TIFFReadScanline (3T), +.IR TIFFStripSize (3T) diff --git a/man/TIFFReadRawTile.3t b/man/TIFFReadRawTile.3t new file mode 100644 index 00000000..1309381d --- /dev/null +++ b/man/TIFFReadRawTile.3t @@ -0,0 +1,65 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadRawTile.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadRawTile 3T "October 15, 1995" +.SH NAME +TIFFReadRawTile \- return an undecoded tile of data from an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Read the contents of the specified tile into the +(user supplied) data buffer. +Note that the value of +.I tile +is a ``raw tile number.'' +That is, the caller must take into account whether or not the +data is organized in separate planes (\c +.IR PlanarConfiguration =2). +.I TIFFComputeTile +automatically does this when converting an (x,y,z,sample) +coordinate quadruple to a tile number. +To read a full tile of data the data buffer should typically be +at least as large as the value returned by +.IR TIFFTileSize . +.SH "RETURN VALUES" +The actual number of bytes of data that were placed in +.I buf +is returned; +.IR TIFFReadEncodedTile +returns \-1 if an error was encountered. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadEncodedTile (3T), +.IR TIFFReadTile (3T), +.IR TIFFTileSize (3T) diff --git a/man/TIFFReadScanline.3t b/man/TIFFReadScanline.3t new file mode 100644 index 00000000..7986be75 --- /dev/null +++ b/man/TIFFReadScanline.3t @@ -0,0 +1,99 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadScanline.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadScanline 3T "October 15, 1995" +.SH NAME +TIFFReadScanline \- read and decode a scanline of data from an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)" +.SH DESCRIPTION +Read the data for the specified row into the (user supplied) +data buffer +.IR buf . +The data are returned decompressed and, in the native byte- +and bit-ordering, but are otherwise packed (see further below). +The buffer must be large enough to hold an entire scanline of data. +Applications should call the routine +.IR TIFFScanlineSize +to find out the size (in bytes) of a scanline buffer. +The +.I row +parameter is always used by +.IR TIFFReadScanline ; +the +.I sample +parameter is used only if data are organized in separate planes (\c +.IR PlanarConfiguration =2). +.SH NOTES +The library attempts to hide bit- and byte-ordering differences +between the image and the native machine by converting data +to the native machine order. +Bit reversal is done if the +.I FillOrder +tag is opposite to the native machine bit order. +16- and 32-bit samples are automatically byte-swapped if the +file was written with a byte order opposite to the native +machine byte order, +.PP +In C++ the +.I sample +parameter defaults to 0. +.SH "RETURN VALUES" +.IR TIFFReadScanline +returns \-1 if it detects an error; otherwise 1 is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +.BR "Compression algorithm does not support random access" . +Data was requested in a non-sequential order from a file that +uses a compression algorithm and that has +.I RowsPerStrip +greater than one. +That is, data in the image is stored in a compressed form, +and with multiple rows packed into a strip. +In this case, the library does not support random access to the data. +The data should either be accessed sequentially, or the file +should be converted so that each strip is made up of one row +of data. +.SH BUGS +Reading subsampled YCbCR data does not work correctly +because, for +.IR PlanarConfiguration =2 +the size of a scanline is not calculated on a per-sample basis, +and for +.IR PlanarConfiguration =1 +the library does not unpack the block-interleaved samples; use +the strip- and tile-based interfaces to read these formats. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadEncodedStrip (3T), +.IR TIFFReadRawStrip (3T) diff --git a/man/TIFFReadTile.3t b/man/TIFFReadTile.3t new file mode 100644 index 00000000..d354c956 --- /dev/null +++ b/man/TIFFReadTile.3t @@ -0,0 +1,85 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFReadTile.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFReadTile 3T "December 16, 1991" +.SH NAME +TIFFReadTile \- read and decode a tile of data from an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFReadTile(TIFF* tif, tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t sample)" +.SH DESCRIPTION +Return the data for the tile +.I containing +the specified coordinates. +The data placed in +.I buf +are returned decompressed and, typically, in the native byte- +and bit-ordering, but are otherwise packed (see further below). +The buffer must be large enough to hold an entire tile of data. +Applications should call the routine +.IR TIFFTileSize +to find out the size (in bytes) of a tile buffer. +The +.I x +and +.I y +parameters are always used by +.IR TIFFReadTile . +The +.I z +parameter is used if the image is deeper than 1 slice (\c +.IR ImageDepth >1). +The +.I sample +parameter is used only if data are organized in separate planes (\c +.IR PlanarConfiguration =2). +.SH NOTES +The library attempts to hide bit- and byte-ordering differences +between the image and the native machine by converting data +to the native machine order. +Bit reversal is done if the +.I FillOrder +tag is opposite to the native machine bit order. +16- and 32-bit samples are automatically byte-swapped if the +file was written with a byte order opposite to the native +machine byte order, +.SH "RETURN VALUES" +.IR TIFFReadTile +returns \-1 if it detects an error; otherwise the number of +bytes in the decoded tile is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFCheckTile (3T), +.IR TIFFComputeTile (3T), +.IR TIFFOpen (3T), +.IR TIFFReadEncodedTile (3T), +.IR TIFFReadRawTile (3T) diff --git a/man/TIFFSetDirectory.3t b/man/TIFFSetDirectory.3t new file mode 100644 index 00000000..1329eb41 --- /dev/null +++ b/man/TIFFSetDirectory.3t @@ -0,0 +1,78 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFSetDirectory.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFSetDirectory 3T "October 15, 1995" +.SH NAME +TIFFSetDirectory, TIFFSetSubDirectory \- set the current directory for an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFSetDirectory(TIFF* tif, tdir_t dirnum)" +.br +.B "int TIFFSetSubDirectory(TIFF* tif, uint32 diroff)" +.SH DESCRIPTION +.I TIFFSetDirectory +changes the current directory and reads its contents with +.IR TIFFReadDirectory . +The parameter +.I dirnum +specifies the subfile/directory as an integer number, with +the first directory numbered zero. +.PP +.I TIFFSetSubDirectory +acts like +.IR TIFFSetDirectory , +except the directory is specified as a +file offset instead of an index; this is required for accessing +subdirectories linked through a +.I SubIFD +tag. +.SH "RETURN VALUES" +On successful return 1 is returned. +Otherwise, 0 is returned if +.I dirnum +or +.I diroff +specifies a non-existent directory, or if an error was +encountered while reading the directory's contents. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +.BR "%s: Error fetching directory count" . +An error was encountered while reading the ``directory count'' field. +.PP +.BR "%s: Error fetching directory link" . +An error was encountered while reading the ``link value'' that +points to the next directory in a file. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFCurrentDirectory (3T), +.IR TIFFOpen (3T), +.IR TIFFReadDirectory (3T), +.IR TIFFWriteDirectory (3T) diff --git a/man/TIFFSetField.3t b/man/TIFFSetField.3t new file mode 100644 index 00000000..b154b7ea --- /dev/null +++ b/man/TIFFSetField.3t @@ -0,0 +1,213 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFSetField.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFSetField 3T "August 28, 1997" +.SH NAME +TIFFSetField \- set the value(s) of a tag in a +.SM TIFF +file open for writing +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFSetField(TIFF* tif, ttag_t tag, ...)" +.br +.B "#include " +.br +.B "int TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)" +.SH DESCRIPTION +.IR TIFFSetField +sets the value of a field +or pseudo-tag in the current directory associated with +the open +.SM TIFF +file +.IR tif . +(A +.I pseudo-tag +is a parameter that is used to control the operation of the +.SM TIFF +library but whose value is not read or written to the underlying file.) +To set the value of a field +the file must have been previously opened for writing with +.IR TIFFOpen (3T); +pseudo-tags can be set whether the file was opened for reading +or writing. +The field is identified by +.IR tag , +one of the values defined in the include file +.B tiff.h +(see also the table below). +The actual value is specified using a variable argument list, +as prescribed by the +.IR stdarg (3) +interface (\c +or, on some machines, the +.IR varargs (3) +interface.) +.PP +.IR TIFFVSetField +is functionally equivalent to +.IR TIFFSetField +except that it takes a pointer to a variable +argument list. +.I TIFFVSetField +is useful for writing routines that are layered +on top of the functionality provided by +.IR TIFFSetField . +.PP +The tags understood by +.IR libtiff , +the number of parameter values, and the +expected types for the parameter values are shown below. +The data types are: +.I char* +is null-terminated string and corresponds to the +.SM ASCII +data type; +.I uint16 +is an unsigned 16-bit value; +.I uint32 +is an unsigned 32-bit value; +.I uint16* +is an array of unsigned 16-bit values. +.I void* +is an array of data values of unspecified type. + +Consult the +.SM TIFF +specification for information on the meaning of each tag. +.PP +.nf +.ta \w'TIFFTAG_CONSECUTIVEBADFAXLINES'u+2n +\w'Count'u+2n +\w'TIFFFaxFillFunc \(dg'u+2n +\fITag Name\fP \fICount\fP \fITypes\fP \fINotes\fP +.sp 5p +TIFFTAG_ARTIST 1 char* +TIFFTAG_BADFAXLINES 1 uint32 +TIFFTAG_BITSPERSAMPLE 1 uint16 \(dg +TIFFTAG_CLEANFAXDATA 1 uint16 +TIFFTAG_COLORMAP 3 uint16* 1< 0 +TIFFTAG_SAMPLEFORMAT 1 uint16 \(dg +TIFFTAG_SAMPLESPERPIXEL 1 uint16 \(dg value must be <= 4 +TIFFTAG_SMAXSAMPLEVALUE 1 double +TIFFTAG_SMINSAMPLEVALUE 1 double +TIFFTAG_SOFTWARE 1 char* +TIFFTAG_STONITS 1 double \(dg +TIFFTAG_SUBFILETYPE 1 uint32 +TIFFTAG_SUBIFD 2 uint16,uint32* count & offsets array +TIFFTAG_TARGETPRINTER 1 char* +TIFFTAG_THRESHHOLDING 1 uint16 +TIFFTAG_TILEDEPTH 1 uint32 \(dg +TIFFTAG_TILELENGTH 1 uint32 \(dg must be a multiple of 8 +TIFFTAG_TILEWIDTH 1 uint32 \(dg must be a multiple of 8 +TIFFTAG_TRANSFERFUNCTION 1 or 3 \(dd uint16* 1<" +.br +.B "void TIFFWarning(const char* module, const char* fmt, ...)" +.sp .5 +.B "#include " +.br +.B "typedef void (*TIFFWarningHandler)(const char* module, const char* fmt, va_list ap);" +.br +.B "TIFFWarningHandler TIFFSetWarningHandler(TIFFWarningHandler handler);" +.SH DESCRIPTION +.I TIFFWarning +invokes the library-wide warning handler function +to (normally) write a warning message to the +.BR stderr . +The +.I fmt +parameter is a +.IR printf (3S) +format string, and any number arguments can be supplied. +The +.I module +parameter is interpreted as a string that, if non-zero, +should be printed before the message; it typically +is used to identify the software module in which a warning +is detected. +.PP +Applications that desire to capture control in the event of a warning +should use +.IR TIFFSetWarningHandler +to override the default warning handler. +A +.SM NULL +(0) warning handler function may be installed to +suppress error messages. +.SH "RETURN VALUES" +.IR TIFFSetWarningHandler +returns a reference to the previous error handling function. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFError (3T), +.IR printf (3S) diff --git a/man/TIFFWriteDirectory.3t b/man/TIFFWriteDirectory.3t new file mode 100644 index 00000000..127a5aef --- /dev/null +++ b/man/TIFFWriteDirectory.3t @@ -0,0 +1,104 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFWriteDirectory.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFWriteDirectory 3T "December 16, 1991" +.SH NAME +TIFFWriteDirectory \- write the current directory in an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFWriteDirectory(TIFF* tif)" +.SH DESCRIPTION +Write the contents of the current directory to the file and setup +to create a new subfile in the same file. +Applications only need to call +.IR TIFFWriteDirectory +when writing multiple subfiles to a single +.SM TIFF +file. +.IR TIFFWriteDirectory +is automatically called by +.IR TIFFClose +and +.IR TIFFFlush +to write a modified directory if the file is open for writing. +.SH "RETURN VALUES" +1 is returned when the contents are successfully +written to the file. +Otherwise, 0 is returned if an error was encountered when writing +the directory contents. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +.BR "Error post-encoding before directory write" . +Before writing the contents of the current directory, any pending +data are flushed. +This message indicates that an error occurred while doing this. +.PP +.BR "Error flushing data before directory write" . +Before writing the contents of the current directory, any pending +data are flushed. +This message indicates that an error occurred while doing this. +.PP +.BR "Cannot write directory, out of space" . +There was not enough space to allocate a temporary area for +the directory that was to be written. +.PP +.BR "Error writing directory count" . +A write error occurred when writing the count of fields in the directory. +.PP +.BR "Error writing directory contents" . +A write error occurred when writing the directory fields. +.PP +.BR "Error writing directory link" . +A write error occurred when writing the link to the next directory. +.PP +\fBError writing data for field "%s"\fP. +A write error occurred when writing indirect data for the specified field. +.PP +.BR "Error writing TIFF header" . +A write error occurred when re-writing header at the front of the file. +.PP +.BR "Error fetching directory count" . +A read error occurred when fetching the directory count field for +a previous directory. +This can occur when setting up a link to the directory that is being +written. +.PP +.BR "Error fetching directory link" . +A read error occurred when fetching the directory link field for +a previous directory. +This can occur when setting up a link to the directory that is being +written. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFError (3T), +.IR TIFFReadDirectory (3T), +.IR TIFFSetDirectory (3T) diff --git a/man/TIFFWriteEncodedStrip.3t b/man/TIFFWriteEncodedStrip.3t new file mode 100644 index 00000000..ea9ae100 --- /dev/null +++ b/man/TIFFWriteEncodedStrip.3t @@ -0,0 +1,105 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFWriteEncodedStrip.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFWriteEncodedStrip 3T "October 15, 1995" +.SH NAME +TIFFWritedEncodedStrip \- compress and write a strip of data to an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFWriteEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Compress +.I size +bytes of raw data from +.I buf +and write the result to the specified strip; replacing +any previously written data. +Note that the value of +.I strip +is a ``raw strip number.'' +That is, the caller must take into account whether or not the +data are organized in separate places (\c +.IR PlanarConfiguration =2). +.SH NOTES +The library writes encoded data using the native machine byte order. +Correctly implemented +.SM TIFF +readers are expected to do any necessary byte-swapping to +correctly process image data with BitsPerSample greater than 8. +.PP +The strip number must be valid according to the current settings +of the +.I ImageLength +and +.I RowsPerStrip +tags. +An image may be dynamically grown by increasing the value of +.I ImageLength +prior to each call to +.IR TIFFWriteEncodedStrip . +.SH "RETURN VALUES" +\-1 is returned if an error was encountered. +Otherwise, the value of +.IR size +is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +\fB%s: File not open for writing\fP. +The file was opened for reading, not writing. +.PP +\fBCan not write scanlines to a tiled image\fP. +The image is assumed to be organized in tiles because the +.I TileWidth +and +.I TileLength +tags have been set with +.IR TIFFSetField (3T). +.PP +\fB%s: Must set "ImageWidth" before writing data\fP. +The image's width has not be set before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: Must set "PlanarConfiguration" before writing data\fP. +The organization of data has not be defined before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: No space for strip arrays"\fP. +There was not enough space for the arrays that hold strip +offsets and byte counts. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteScanline (3T), +.IR TIFFWriteRawStrip (3T) diff --git a/man/TIFFWriteEncodedTile.3t b/man/TIFFWriteEncodedTile.3t new file mode 100644 index 00000000..68492476 --- /dev/null +++ b/man/TIFFWriteEncodedTile.3t @@ -0,0 +1,98 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFWriteEncodedTile.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFWriteEncodedTile 3T "December 16, 1991" +.SH NAME +TIFFWritedEncodedTile \- compress and write a tile of data to an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFWriteEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Compress +.I size +bytes of raw data from +.I buf +and +.B append +the result to the end of the specified tile. +Note that the value of +.I tile +is a ``raw tile number.'' +That is, the caller must take into account whether or not the +data are organized in separate places (\c +.IR PlanarConfiguration =2). +.IR TIFFComputeTile +automatically does this when converting an (x,y,z,sample) +coordinate quadruple to a tile number. +.SH NOTES +The library writes encoded data using the native machine byte order. +Correctly implemented +.SM TIFF +readers are expected to do any necessary byte-swapping to +correctly process image data with BitsPerSample greater than 8. +.SH "RETURN VALUES" +\-1 is returned if an error was encountered. +Otherwise, the value of +.IR size +is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +\fB%s: File not open for writing\fP. +The file was opened for reading, not writing. +.PP +\fBCan not write tiles to a stripped image\fP. +The image is assumed to be organized in strips because neither of the +.I TileWidth +or +.I TileLength +tags have been set with +.IR TIFFSetField (3T). +.PP +\fB%s: Must set "ImageWidth" before writing data\fP. +The image's width has not be set before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: Must set "PlanarConfiguration" before writing data\fP. +The organization of data has not be defined before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: No space for tile arrays"\fP. +There was not enough space for the arrays that hold tile +offsets and byte counts. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteTile (3T), +.IR TIFFWriteRawTile (3T) diff --git a/man/TIFFWriteRawStrip.3t b/man/TIFFWriteRawStrip.3t new file mode 100644 index 00000000..b4723db9 --- /dev/null +++ b/man/TIFFWriteRawStrip.3t @@ -0,0 +1,94 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFWriteRawStrip.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFWriteRawstrip 3T "October 15, 1995" +.SH NAME +TIFFWriteRawStrip \- write a strip of raw data to an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Append +.I size +bytes of raw data to the specified strip. +.SH NOTES +The strip number must be valid according to the current settings +of the +.I ImageLength +and +.I RowsPerStrip +tags. +An image may be dynamically grown by increasing the value of +.I ImageLength +prior to each call to +.IR TIFFWriteRawStrip . +.SH "RETURN VALUES" +\-1 is returned if an error occurred. +Otherwise, the value of +.IR size +is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +\fB%s: File not open for writing\fP. +The file was opened for reading, not writing. +.PP +\fBCan not write scanlines to a tiled image\fP. +The image is assumed to be organized in tiles because the +.I TileWidth +and +.I TileLength +tags have been set with +.IR TIFFSetField (3T). +.PP +\fB%s: Must set "ImageWidth" before writing data\fP. +The image's width has not be set before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: Must set "PlanarConfiguration" before writing data\fP. +The organization of data has not be defined before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: No space for strip arrays"\fP. +There was not enough space for the arrays that hold strip +offsets and byte counts. +.PP +\fB%s: Strip %d out of range, max %d\fP. +The specified strip is not a valid strip according to the +currently specified image dimensions. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteEncodedStrip (3T), +.IR TIFFWriteScanline (3T) diff --git a/man/TIFFWriteRawTile.3t b/man/TIFFWriteRawTile.3t new file mode 100644 index 00000000..b99243c9 --- /dev/null +++ b/man/TIFFWriteRawTile.3t @@ -0,0 +1,83 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFWriteRawTile.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFWriteRawtile 3T "December 16, 1991" +.SH NAME +TIFFWriteRawTile \- write a tile of raw data to an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "tsize_t TIFFWriteRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)" +.SH DESCRIPTION +Append +.I size +bytes of raw data to the specified tile. +.SH "RETURN VALUES" +\-1 is returned if an error occurred. +Otherwise, the value of +.IR size +is returned. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +\fB%s: File not open for writing\fP. +The file was opened for reading, not writing. +.PP +\fBCan not write tiles to a stripped image\fP. +The image is assumed to be organized in strips because neither of the +.I TileWidth +or +.I TileLength +tags have been set with +.IR TIFFSetField (3T). +.PP +\fB%s: Must set "ImageWidth" before writing data\fP. +The image's width has not be set before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: Must set "PlanarConfiguration" before writing data\fP. +The organization of data has not be defined before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: No space for tile arrays"\fP. +There was not enough space for the arrays that hold tile +offsets and byte counts. +.PP +\fB%s: Specified tile %d out of range, max %d\fP. +The specified tile is not valid according to the currently +specified image dimensions. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteEncodedTile (3T), +.IR TIFFWriteScanline (3T) diff --git a/man/TIFFWriteScanline.3t b/man/TIFFWriteScanline.3t new file mode 100644 index 00000000..ffe32cf6 --- /dev/null +++ b/man/TIFFWriteScanline.3t @@ -0,0 +1,162 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFWriteScanline.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFWriteScanline 3T "December 16, 1991" +.SH NAME +TIFFWriteScanline \- write a scanline to an open +.SM TIFF +file +.SH SYNOPSIS +.B "#include " +.br +.B "int TIFFWriteScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)" +.SH DESCRIPTION +Write data to a file at the specified row. +The +.I sample +parameter is used only if data are organized in separate planes (\c +.IR PlanarConfiguration =2). +The data are assumed to be uncompressed and in the native +bit- and byte-order of the host machine. +The data written to the file is +compressed according to the compression scheme +of the current +.SM TIFF +directory (see further below). +If the current scanline is past the end of the current subfile, the +.I ImageLength +field is automatically increased to include the scanline (except +for +.IR PlanarConfiguration =2, +where the +.I ImageLength +cannot be changed once the first data are written). +If the +.I ImageLength +is increased, the +.I StripOffsets +and +.I StripByteCounts +fields are similarly enlarged to reflect data written past the +previous end of image. +.SH NOTES +The library writes encoded data using the native machine byte order. +Correctly implemented +.SM TIFF +readers are expected to do any necessary byte-swapping to +correctly process image data with BitsPerSample greater than 8. +The library attempts to hide bit-ordering differences +between the image and the native machine by converting data +from the native machine order. +.PP +In C++ the +.I sample +parameter defaults to 0. +.PP +Once data are written to a file for the current directory, +the values of certain tags may not be altered; see +.IR TIFFSetField (3T) +for more information. +.PP +It is not possible to write scanlines to a file that +uses a tiled organization. The routine +.IR TIFFIsTiled +can be used to determine if the file is organized +as tiles or strips. +.SH "RETURN VALUES" +.IR TIFFWriteScanline +returns \-1 if it immediately detects an error +and 1 for a successful write. +.SH DIAGNOSTICS +All error messages are directed to the +.IR TIFFError (3T) +routine. +.PP +.BR "%s: File not open for writing . +The file was opened for reading, not writing. +.PP +.BR "Can not write scanlines to a tiled image" . +An attempt was made to write a scanline to a tiled image. +The image is assumed to be organized in tiles because the +.I TileWidth +and +.I TileLength +tags have been set with +.IR TIFFSetField (3T). +.PP +.BR "Compression algorithm does not support random access" . +Data was written in a non-sequential order to a file that +uses a compression algorithm and that has +.I RowsPerStrip +greater than one. +That is, data in the image is to be stored in a compressed form, +and with multiple rows packed into a strip. +In this case, the library does not support random access to the data. +The data should either be written as entire strips, +sequentially by rows, or the value of +.I RowsPerStrip +should be set to one. +.PP +\fB%s: Must set "ImageWidth" before writing data\fP. +The image's width has not be set before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fB%s: Must set "PlanarConfiguration" before writing data\fP. +The organization of data has not be defined before the first write. +See +.IR TIFFSetField (3T) +for information on how to do this. +.PP +\fBCan not change "ImageLength" when using separate planes\fP. +Separate image planes are being used (\c +.IR PlanarConfiguration =2), +but the number of rows has not been specified before the first write. +The library supports the dynamic growth of an image only when data +are organized in a contiguous manner (\c +.IR PlanarConfiguration =1). +.PP +.BR "%d: Sample out of range, max %d" . +The +.I sample +parameter was greater than the value of the SamplesPerPixel tag. +.PP +.BR "%s: No space for strip arrays . +There was not enough space for the arrays that hold strip +offsets and byte counts. +.SH BUGS +Writing subsampled YCbCR data does not work correctly +because, for +.IR PlanarConfiguration =2 +the size of a scanline is not calculated on a per-sample basis, +and for +.IR PlanarConfiguration =1 +the library does not pack the block-interleaved samples. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFWriteEncodedStrip (3T), +.IR TIFFWriteRawStrip (3T) diff --git a/man/TIFFbuffer.3t b/man/TIFFbuffer.3t new file mode 100644 index 00000000..a981e958 --- /dev/null +++ b/man/TIFFbuffer.3t @@ -0,0 +1,77 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFbuffer.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1995 Sam Leffler +.\" Copyright (c) 1995 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFBUFFER 3T "October 15, 1995" +.SH NAME +TIFFReadBufferSetup, +TIFFWriteBufferSetup +\- I/O buffering control routines +.SH SYNOPSIS +.nf +.B "#include " +.B "int TIFFReadBufferSetup(TIFF*, tdata_t buffer, tsize_t size);" +.B "int TIFFWriteBufferSetup(TIFF*, tdata_t buffer, tsize_t size);" +.fi +.SH DESCRIPTION +The following routines are provided for client-control of the +I/O buffers used by the library. +Applications need never use these routines; they are provided only +for ``intelligent clients'' that wish to optimize memory usage and/or +eliminate potential copy operations that can occur when working with +images that have data stored without compression. +.PP +.I TIFFReadBufferSetup +sets up the data buffer used to read raw (encoded) data from a file. +If the specified pointer is +.SM NULL +(zero), then a buffer of the appropriate size is allocated. +Otherwise the caller must guarantee that the buffer is large +enough to hold any individual strip of raw data. +.I TIFFReadBufferSetup +returns a non-zero value if the setup was successful and zero otherwise. +.PP +.I TIFFWriteBufferSetup +sets up the data buffer used to write raw (encoded) data to a file. +If the specified +.I size +is \-1 then the buffer size is selected to hold a complete +tile or strip, or at least 8 kilobytes, whichever is greater. +If the specified +.I buffer +is +.SM NULL +(zero), then a buffer of the appropriate size is dynamically allocated. +.I TIFFWriteBufferSetup +returns a non-zero value if the setup was successful and zero otherwise. +.SH DIAGNOSTICS +.BR "%s: No space for data buffer at scanline %ld" . +.I TIFFReadBufferSetup +was unable to dynamically allocate space for a data buffer. +.PP +.BR "%s: No space for output buffer" . +.I TIFFWriteBufferSetup +was unable to dynamically allocate space for a data buffer. +.SH "SEE ALSO" +.IR libtiff (3T) diff --git a/man/TIFFcodec.3t b/man/TIFFcodec.3t new file mode 100644 index 00000000..c46917d4 --- /dev/null +++ b/man/TIFFcodec.3t @@ -0,0 +1,73 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFcodec.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1995 Sam Leffler +.\" Copyright (c) 1995 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH CODEC 3T "October 15, 1995" +.SH NAME +TIFFFindCODEC, TIFFRegisterCODEC, TIFFUnRegisterCODEC \- codec-related utility routines +.SH SYNOPSIS +.B "#include " +.br +.B "const TIFFCodec* TIFFFindCODEC(uint16 scheme);" +.br +.B "TIFFCodec* TIFFRegisterCODEC(uint16 scheme, const char* method, TIFFInitMethod init);" +.br +.B "void TIFFUnRegisterCODEC(TIFFCodec* codec);" +.SH DESCRIPTION +.I libtiff +supports a variety of compression schemes implemented by software +.IR codecs . +Each codec adheres to a modular interface that provides for +the decoding and encoding of image data; as well as some other +methods for initialization, setup, cleanup, and the control +of default strip and tile sizes. +Codecs are identified by the associated value of the +.SM TIFF +.I Compression +tag; e.g. 5 for +.SM LZW +compression. +.PP +The +.I TIFFRegisterCODEC +routine can be used to +augment or override the set of codecs available to an application. +If the specified +.I scheme +already has a registered codec then it is +.I overridden +and any images with data encoded with this +compression scheme will be decoded using the supplied coded. +.SH DIAGNOSTICS +.BR "No space to register compression scheme %s" . +.I TIFFRegisterCODEC +was unable to allocate memory for the data structures needed +to register a codec. +.PP +.BR "Cannot remove compression scheme %s; not registered" . +.I TIFFUnRegisterCODEC +did not locate the specified codec in the table of registered +compression schemes. +.SH "SEE ALSO" +.IR libtiff (3T) diff --git a/man/TIFFmemory.3t b/man/TIFFmemory.3t new file mode 100644 index 00000000..368d2169 --- /dev/null +++ b/man/TIFFmemory.3t @@ -0,0 +1,84 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFmemory.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1995 Sam Leffler +.\" Copyright (c) 1995 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH MEMORY 3T "October 15, 1995" +.SH NAME +_TIFFmalloc, \c +_TIFFrealloc, \c +_TIFFfree, \c +_TIFFmemset, \c +_TIFFmemcpy, \c +_TIFFmemcmp, \c +\- memory management-related functions for use with +.SM TIFF +files +.SH SYNOPSIS +.nf +.B "#include " +.B "tdata_t _TIFFmalloc(tsize_t);" +.B "tdata_t _TIFFrealloc(tdata_t, tsize_t);" +.B "void _TIFFfree(tdata_t);" +.B "void _TIFFmemset(tdata_t, int, tsize_t);" +.B "void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t);" +.B "int _TIFFmemcmp(const tdata_t, const tdata_t, tsize_t);" +.fi +.SH DESCRIPTION +These routines are provided for writing portable software that uses +.IR libtiff ; +they hide any memory-management related issues, such as dealing with +segmented architectures found on 16-bit machines. +.PP +.I _TIFFmalloc +and +.I _TIFFrealloc +are used to dynamically allocate and reallocate memory used by +.IR libtiff ; +such as memory passed into the I/O routines. +Memory allocated through these interfaces is released back to the +system using the +.I _TIFFfree +routine. +.PP +Memory allocated through one of the above interfaces can be set to +a known value using +.IR _TIFFmemset , +copied to another memory location using +.IR _TIFFmemcpy , +or compared for equality using +.IR _TIFFmemcmp . +These routines conform to the equivalent +.SM ANSI +C routines: +.IR memset , +.IR memcpy , +and +.IR memcmp , +repsectively. +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR malloc (3C), +.IR memory (3C) diff --git a/man/TIFFquery.3t b/man/TIFFquery.3t new file mode 100644 index 00000000..f0b0c8e7 --- /dev/null +++ b/man/TIFFquery.3t @@ -0,0 +1,137 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFquery.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH QUERY 3T "October 15, 1995" +.SH NAME +TIFFCurrentRow, +TIFFCurrentStrip, +TIFFCurrentTile, +TIFFCurrentDirectory, +TIFFLastDirectory, +TIFFFileno, +TIFFFileName, +TIFFGetMode, +TIFFIsTiled, +TIFFIsByteSwapped, +TIFFIsUpSampled, +TIFFIsMSB2LSB +\- query routines +.SH SYNOPSIS +.nf +.B "#include " +.B "uint32 TIFFCurrentRow(TIFF* tif)" +.B "tstrip_t TIFFCurrentStrip(TIFF* tif)" +.B "ttile_t TIFFCurrentTile(TIFF* tif)" +.B "tdir_t TIFFCurrentDirectory(TIFF* tif)" +.B "int TIFFLastDirectory(TIFF* tif)" +.B "int TIFFFileno(TIFF* tif)" +.B "char* TIFFFileName(TIFF* tif)" +.B "int TIFFGetMode(TIFF* tif)" +.B "int TIFFIsTiled(TIFF* tif)" +.B "int TIFFIsByteSwapped(TIFF* tif)" +.B "int TIFFIsUpSampled(TIFF* tif)" +.B "int TIFFIsMSB2LSB(TIFF* tif)" +.B "const char* TIFFGetVersion(void)" +.fi +.SH DESCRIPTION +The following routines return status information about an open +.SM TIFF +file. +.PP +.IR TIFFCurrentDirectory +returns the index of the current directory (directories +are numbered starting at 0). +This number is suitable for use with the +.IR TIFFSetDirectory +routine. +.PP +.IR TIFFLastDirectory +returns a non-zero value if the current directory is the +last directory in the file; +otherwise zero is returned. +.PP +.IR TIFFCurrentRow , +.IR TIFFCurrentStrip , +and +.IR TIFFCurrentTile , +return the current row, strip, and tile, respectively, +that is being read or written. +These values are updated each time a read or write is done. +.PP +.IR TIFFFileno +returns the underlying file descriptor used to access the +.SM TIFF +image in the filesystem. +.PP +.IR TIFFFileName +returns the pathname argument passed to +.IR TIFFOpen +or +.IR TIFFFdOpen . +.PP +.IR TIFFGetMode +returns the mode with which the underlying file was opened. +On +.SM UNIX +systems, this is the value passed to the +.IR open (2) +system call. +.PP +.IR TIFFIsTiled +returns a non-zero value if the image data has +a tiled organization. +Zero is returned if the image data is organized in strips. +.PP +.IR TIFFIsByteSwapped +returns a non-zero value if the image data was in a different +byte-order than the host machine. +Zero is returned if the image data and local host byte-orders +are the same. +Data samples that are more than 8 bits wide must be byte-swapped +by the application. +.PP +.I TIFFIsUpSampled +returns a non-zero value if image data returned through the +read interface routines is being up-sampled. +This can be useful to applications that want to calculate +I/O buffer sizes to reflect this usage (though the usual +strip and tile size routines already do this). +.PP +.I TIFFIsMSB2LSB +returns a non-zero value if the image data is being returned with +bit 0 as the most significant bit. +.PP +.IR TIFFGetVersion +returns an +.SM ASCII +string that has a version stamp for the +.SM TIFF +library software. +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFFdOpen (3T) diff --git a/man/TIFFsize.3t b/man/TIFFsize.3t new file mode 100644 index 00000000..c03289f3 --- /dev/null +++ b/man/TIFFsize.3t @@ -0,0 +1,57 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFsize.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFSIZE 3T "October 15, 1995" +.SH NAME +TIFFScanlineSize, +TIFFRasterScanlineSize, +\- return the size of various items associated with an open +.SM TIFF +file +.SH SYNOPSIS +.nf +.B "#include " +.B "tsize_t TIFFRasterScanlineSize(TIFF* tif)" +.B "tsize_t TIFFScanlineSize(TIFF* tif)" +.SH DESCRIPTION +.I TIFFScanlineSize +returns the size in bytes of a row of data as it would be +returned in a call to +.IR TIFFReadScanline , +or as it would be expected in a call to +.IR TIFFWriteScanline . +.PP +.I TIFFRasterScanlineSize +returns the size in bytes of a complete decoded and packed +raster scanline. +Note that this value may be different from the value returned by +.I TIFFScanlineSize +if data is stored as separate planes. +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFOpen (3T), +.IR TIFFReadScanline (3T) diff --git a/man/TIFFstrip.3t b/man/TIFFstrip.3t new file mode 100644 index 00000000..28273cb4 --- /dev/null +++ b/man/TIFFstrip.3t @@ -0,0 +1,96 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFstrip.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1992-1997 Sam Leffler +.\" Copyright (c) 1992-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFSTRIP 3T "October 15, 1995" +.SH NAME +TIFFDefaultStripSize, +TIFFStripSize, +TIFFVStripSize, +TIFFComputeStrip, +TIFFNumberOfStrips +\- strip-related utility routines +.SH SYNOPSIS +.nf +.B "#include " +.B "uint32 TIFFDefaultStripSize(TIFF* tif, uint32 estimate)" +.B "tsize_t TIFFStripSize(TIFF* tif)" +.B "tsize_t TIFFVStripSize(TIFF* tif, uint32 nrows)" +.B "tstrip_t TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample)" +.B "tstrip_t TIFFNumberOfStrips(TIFF* tif)" +.fi +.SH DESCRIPTION +.I TIFFDefaultStripSize +returns the number of rows for a reasonable-sized strip according +to the current settings of the +.IR ImageWidth , +.IR BitsPerSample , +.IR SamplesPerPixel , +tags and any compression-specific requirements. +If the +.I estimate +parameter, if non-zero, then it is taken as an estimate of the desired +strip size and adjusted according to any compression-specific requirements. +The value returned by this function is typically used to define the +.I RowsPerStrip +tag. +In lieu of any unusual requirements +.I TIFFDefaultStripSize +tries to create strips that have approximately +8 kilobytes of uncompressed data. +.PP +.IR TIFFStripSize +returns the equivalent size for a strip of data as it would +be returned in a call to +.IR TIFFReadEncodedStrip +or as it would be expected in a call to +.IR TIFFWriteEncodedStrip . +.PP +.I TIFFVStripSize +returns the number of bytes in a strip with +.I nrows +rows of data. +.PP +.IR TIFFComputeStrip +returns the strip that contains the specified coordinates. +A valid strip is always returned; +out-of-range coordinate values are clamped to the bounds of the image. +The +.I row +parameter is always used in calculating a strip. +The +.I sample +parameter is used only if data are organized in separate planes (\c +.IR PlanarConfiguration =2). +.PP +.IR TIFFNumberOfStrips +returns the number of strips in the image. +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFReadEncodedStrip (3T), +.IR TIFFReadRawStrip (3T), +.IR TIFFWriteEncodedStrip (3T), +.IR TIFFWriteRawStrip (3T) diff --git a/man/TIFFswab.3t b/man/TIFFswab.3t new file mode 100644 index 00000000..355cccb2 --- /dev/null +++ b/man/TIFFswab.3t @@ -0,0 +1,73 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFswab.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH SWAB 3T "December 16, 1991" +.SH NAME +TIFFReverseBits, TIFFSwabShort, TIFFSwabLong, TIFFSwabArrayOfShort, TIFFSwabArrayOfLong \- byte- and bit-swapping routines +.SH SYNOPSIS +.B "#include " +.br +.B "const unsigned char* TIFFGetBitRevTable(int reversed);" +.br +.B "void TIFFReverseBits(u_char* data, unsigned long nbytes)" +.br +.B "void TIFFSwabShort(uint16* data)" +.br +.B "void TIFFSwabLong(uint32* data)" +.br +.B "void TIFFSwabArrayOfShort(uint16* data, unsigned long nshorts)" +.br +.B "void TIFFSwabArrayOfLong(uint32* data, unsigned long nlongs)" +.SH DESCRIPTION +The following routines are used by the library to swap +16- and 32-bit data and to reverse the order of bits in bytes. +.PP +.IR TIFFSwabShort +and +.IR TIFFSwabLong +swap the bytes in a single 16-bit and 32-bit item, respectively. +.IR TIFFSwabArrayOfShort +and +.IR TIFFSwabArrayOfLong +swap the bytes in an array of 16-bit and 32-bit items, respectively. +.PP +.IR TIFFReverseBits +replaces each byte in +.I data +with the equivalent bit-reversed value. +This operation is done with a lookup table, +.I TIFFBitRevTable +which is declared public. +A second table, +.I TIFFNoBitRevTable +is also declared public; it is a lookup table that +can be used as an +.IR "identity function" ; +i.e. +.IR "TIFFNoBitRevTable[n] == n" . +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), diff --git a/man/TIFFtile.3t b/man/TIFFtile.3t new file mode 100644 index 00000000..83e359f9 --- /dev/null +++ b/man/TIFFtile.3t @@ -0,0 +1,134 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/TIFFtile.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFTILE 3T "February 14, 1992" +.SH NAME +TIFFTileSize, +TIFFTileRowSize, +TIFFVTileSize, +TIFFDefaultTileSize, +TIFFComputeTile, +TIFFCheckTile, +TIFFNumberOfTiles +\- tile-related utility routines +.SH SYNOPSIS +.nf +.B "#include " +.B "void TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)" +.B "tsize_t TIFFTileSize(TIFF* tif)" +.B "tsize_t TIFFTileRowSize(TIFF* tif)" +.B "tsize_t TIFFVTileSize(TIFF* tif, uint32 nrows)" +.B "ttile_t TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t sample)" +.B "int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t sample)" +.B "ttile_t TIFFNumberOfTiles(TIFF* tif)" +.fi +.SH DESCRIPTION +.I TIFFDefaultTileSize +returns the pixel width and height of a reasonable-sized tile; +suitable for setting up the +.I TileWidth +and +.I TileLength +tags. +If the +.I tw +and +.I th +values passed in are non-zero, then they are adjusted to reflect +any compression-specific requirements. +The returned width and height are constrained to be a multiple +of 16 pixels to conform with the +.SM TIFF +specification. +.PP +.I TIFFTileSize +returns the equivalent size for a tile of data as it would +be returned in a call to +.I TIFFReadTile +or as it would be expected in a call to +.IR TIFFWriteTile . +.PP +.I TIFFVTileSize +returns the number of bytes in a row-aligned tile with +.I nrows +of data. +.PP +.I TIFFTileRowSize +returns the number of bytes of a row of data in a tile. +.PP +.IR TIFFComputeTile +returns the tile that contains the specified coordinates. +A valid tile is always returned; +out-of-range coordinate values are clamped to the bounds of the image. +The +.I x +and +.I y +parameters are always used in calculating a tile. +The +.I z +parameter is used if the image is deeper than 1 slice (\c +.IR ImageDepth >1). +The +.I sample +parameter is used only if data are organized in separate planes (\c +.IR PlanarConfiguration =2). +.PP +.IR TIFFCheckTile +returns a non-zero value if the supplied coordinates are +within the bounds of the image and zero otherwise. +The +.I x +parameter is checked against the value of the +.I ImageWidth +tag. +The +.I y +parameter is checked against the value of the +.I ImageLength +tag. +The +.I z +parameter is checked against the value of the +.I ImageDepth +tag (if defined). +The +.I sample +parameter is checked against the value of the +.I SamplesPerPixel +parameter if the data are organized in separate planes. +.PP +.IR TIFFNumberOfTiles +returns the number of tiles in the image. +.SH DIAGNOSTICS +None. +.SH "SEE ALSO" +.IR libtiff (3T), +.IR TIFFReadEncodedTile (3T), +.IR TIFFReadRawTile (3T), +.IR TIFFReadTile (3T), +.IR TIFFWriteEncodedTile (3T), +.IR TIFFWriteRawTile (3T), +.IR TIFFWriteTile (3T) diff --git a/man/fax2ps.1 b/man/fax2ps.1 new file mode 100644 index 00000000..ec199d36 --- /dev/null +++ b/man/fax2ps.1 @@ -0,0 +1,158 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/fax2ps.1,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.ds Ps P\s-2OST\s+2S\s-2CRIPT\s+2 +.TH FAX2PS 1 "March 16, 1995" +.SH NAME +fax2ps \- convert a +.SM TIFF +facsimile to compressed \*(Ps\(tm +.SH SYNOPSIS +.B fax2ps +[ +.I options +] [ +.IR file ... +] +.SH DESCRIPTION +.I fax2ps +reads one or more +.SM TIFF +facsimile image files and prints a compressed form of +\*(Ps on the standard output that is suitable for printing. +.PP +By default, each page is scaled to reflect the +image dimensions and resolutions stored in the file. +The +.B \-x +and +.B \-y +options can be used to specify the horizontal and vertical +image resolutions (lines/inch), respectively. +If the +.B \-S +option is specified, each page is scaled to fill an output page. +The default output page is 8.5 by 11 inches. +Alternate page dimensions can be specified in inches with the +.B \-W +and +.B \-H +options. +.PP +By default +.I fax2ps +generates \*(Ps for all pages in the file. +The +.B \-p +option can be used to select one or more pages from +a multi-page document. +.PP +.I fax2ps +generates a compressed form of \*(Ps that is +optimized for sending pages of text to a \*(Ps +printer attached to a host through a low-speed link (such +as a serial line). +Each output page is filled with white and then only +the black areas are drawn. +The \*(Ps specification of the black drawing operations +is optimized by using a special font that encodes the +move-draw operations required to fill +the black regions on the page. +This compression scheme typically results in a substantially +reduced \*(Ps description, relative to the straightforward +imaging of the page with a \*(Ps +.I image +operator. +This algorithm can, however, be ineffective +for continuous-tone and white-on-black images. +For these images, it sometimes is more efficient to send +the raster bitmap image directly; see +.IR tiff2ps (1). +.SH OPTIONS +.TP 10 +.BI \-p " number" +Print only the indicated page. +Multiple pages may be printed by specifying +this option more than once. +.TP 10 +.BI \-x " resolution" +Use +.I resolution +as the horizontal resolution, in dots/inch, of the image data. +By default this value is taken from the file. +.TP 10 +.BI \-y " resolution" +Use +.I resolution +as the vertical resolution, in lines/inch, of the image data. +By default this value is taken from the file. +.TP 10 +.B \-S +Scale each page of image data to fill the output page dimensions. +By default images are presented according to the dimension +information recorded in the +.SM TIFF +file. +.TP 10 +.BI \-W " width" +Use +.I width +as the width, in inches, of the output page. +The default page width is 8.5 inches. +.TP 10 +.BI \-H " height" +Use +.I height +as the height, in inches, of the output page. +The default page height is 11 inches. +.SH DIAGNOSTICS +Some messages about malformed +.SM TIFF +images come from the +.SM TIFF +library. +.PP +Various messages about badly formatted facsimile images +may be generated due to transmission errors in received +facsimile. +.I fax2ps +attempts to recover from such data errors by resynchronizing +decoding at the end of the current scanline. +This can result in long horizontal black lines in the resultant +\*(Ps image. +.SH NOTES +If the destination printer supports \*(Ps Level II then +it is always faster to just send the encoded bitmap generated +by the +.IR tiff2ps (1) +program. +.SH BUGS +.I fax2ps +should probably figure out when it is doing a poor +job of compressing the output and just generate +\*(Ps to image the bitmap raster instead. +.SH "SEE ALSO" +.IR tiff2ps (1), +.IR libtiff (3) diff --git a/man/fax2tiff.1 b/man/fax2tiff.1 new file mode 100644 index 00000000..dcf2eee8 --- /dev/null +++ b/man/fax2tiff.1 @@ -0,0 +1,205 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/fax2tiff.1,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1990-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH FAX2TIFF 1 "September 24, 1994" +.SH NAME +fax2tiff \- create a +.SM TIFF +Class F fax file from raw fax data +.SH SYNOPSIS +.B fax2tiff +[ +.I options +] [ +.B \-o +.I output.tif +] +.I input.g3 +.SH DESCRIPTION +.I Fax2tiff +creates a +.SM TIFF +file containing +.SM CCITT +Group 3 or Group 4 encoded data from one or more files containing ``raw'' +Group 3 encoded data (typically obtained directly from a fax modem). +By default, each row of data in the resultant +.SM TIFF +file is 2-dimensionally encoded and +padded or truncated to 1728 pixels, as needed. +The resultant image is a set of low resolution (98 lines/inch) +or medium resolution (196 lines/inch) +pages, each of which is a single strip of data. +The generated file conforms to the +.SM TIFF +Class F (\c +.SM FAX\c +) specification for storing facsimile data. +This means, in particular, that each page of the data does +.B not +include the trailing +.I "return to control" +(\c +.SM RTC\c +) code; as required +for transmission by the +.SM CCITT +Group 3 specifications. +The old, ``classic'', format is created if the +.B \-c +option is used. +(The Class F format can also be requested with the +.B \-f +option.) +.PP +The default name of the output image is +.IR fax.tif ; +this can be changed with the +.B \-o +option. +Each input file is assumed to be a separate page of facsimile data +from the same document. +The order in which input files are specified on the command +line is the order in which the resultant pages appear in the +output file. +.SH OPTIONS +Options that affect the interpretation of input data are: +.TP +.B \-2 +Assume input data is 2-d Huffman encoded. +.TP +.B \-B +Assume input data was encoded with +black as 0 and white as 1. +.TP +.B \-L +Treat input data as having bits filled from least +significant bit (\c +.SM LSB\c +) to most significant bit (\c +.SM MSB\c +). +(This is the default.) +.TP +.B \-M +Treat input data as having bits filled from most +significant bit (\c +.SM MSB\c +) to most least bit (\c +.SM LSB\c +). +.TP +.B \-R +Specify the vertical resolution, in lines/inch, of the +input images. +By default input are assumed to have a vertical +resolution of 196 lines/inch. +If images are low resolution facsimile, a value of +98 lines/inch should be specified. +.TP +.B \-W +Assume input data was encoded with +black as 1 and white as 0. +(This is the default.) +.PP +Options that affect the output file format are: +.TP +.B \-1 +Force output to be compressed with the 1-dimensional +version of the +.SM CCITT +Group 3 Huffman encoding algorithm. +.TP +.B \-4 +Force output to be compressed with the +.SM CCITT +Group 4 Huffman encoding. +.TP +.B \-o +Specify the name of the output file. +.TP +.B \-p +Force the last bit of each +.I "End Of Line" +(\c +.SM EOL\c +) code to land on a byte boundary. +This ``zero padding'' will be reflected in the contents of the +.I Group3Options +tag of the resultant +.SM TIFF +file. +.TP +.B \-s +Stretch the input image vertically by writing each input row of +data twice to the output file. +.TP +.B \-v +Force +.I fax2tiff +to print the number of rows of data it retrieved from the input file. +.SH DIAGNOSTICS +The following warnings and errors come from the decoding +routines in the library. +.PP +.BR "Warning, %s: Premature EOL at scanline %d (x %d).\en" . +The input data had a row that was shorter than the expected value of 1728. +The row is padded with white. +.PP +.BR "%s: Premature EOF at scanline %d (x %d).\en" . +The decoder ran out of data in the middle of a scanline. +The resultant row is padded with white. +.PP +.BR "%s: Bad code word at row %d, x %d\en" . +An invalid Group 3 +.I code +was encountered while decoding the input file. +The row number and horizontal position is given. +The remainder of the input row is discarded, while +the corresponding output row is padded with white. +.PP +.BR "%s: Bad 2D code word at scanline %d.\en" . +An invalid Group 4 or 2D Group 3 +.I code +was encountered while decoding the input file. +The row number and horizontal position is given. +The remainder of the input row is discarded, while +the corresponding output row is padded with white. +.SH BUGS +Should not have the constant width 1728 built into it. +Input data are assumed to have a a ``top left'' orientation; +it should be possible to override this assumption +from the command line. +.SH "SEE ALSO" +.I "\s-1CCITT\s+1 Recommendation T.4" +(Standardization of Group 3 Facsimile Apparatus for Document Transmission). +.PP +.IR "The Spirit of TIFF Class F" , +an appendix to the TIFF 5.0 specification prepared by Cygnet Technologies. +.PP +.IR tiffinfo (1), +.IR tiffdither (1), +.IR tiffgt (1), +.IR libtiff (3). diff --git a/man/gif2tiff.1 b/man/gif2tiff.1 new file mode 100644 index 00000000..2bebff9e --- /dev/null +++ b/man/gif2tiff.1 @@ -0,0 +1,78 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/gif2tiff.1,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH GIF2TIFF 1 "October 15, 1995" +.SH NAME +gif2tiff \- create a +.SM TIFF +file from a GIF87 format image file +.SH SYNOPSIS +.B gif2tiff +[ +.I options +] +.I input.gif +.I output.tif +.SH DESCRIPTION +.I Gif2tiff +converts a file in the GIF87 format to +.SM TIFF. +The +.SM TIFF +image is created as a palette image, with samples +compressed with the Lempel-Ziv & Welch algorithm (\c +.IR Compression =5). +These characteristics can overriden, or explicitly specified +with the options described below. +.SH OPTIONS +.TP +.B \-c +Specify a compression scheme to use when writing image data: +.B "\-c none" +for no compression, +.B "-c packbits" +for the PackBits compression algorithm, +.B "-c zip" +for the Deflate compression algorithm, +and +.B "\-c lzw" +for Lempel-Ziv & Welch (the default). +.TP +.B \-r +Write data with a specified number of rows per strip; +by default the number of rows/strip is selected so that each strip +is approximately 8 kilobytes. +.SH NOTES +The program is based on Paul Haeberli's +.I fromgif +program which, in turn, is based on Marcel J.E. Mol's GIF reader. +.SH BUGS +Should have more options to control output format. +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/libtiff.3t b/man/libtiff.3t new file mode 100644 index 00000000..00b0ff12 --- /dev/null +++ b/man/libtiff.3t @@ -0,0 +1,511 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/libtiff.3t,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH INTRO 3T "August 21, 1997" +.SH NAME +libtiff \- introduction to +.IR libtiff , +a library for reading and writing +.SM TIFF +files +.SH SYNOPSIS +.B "#include " +.br +cc file.c +.B -ltiff +.SH DESCRIPTION +.I libtiff +is a library for reading and writing data files encoded with the +.I "Tag Image File" +format, Revision 6.0 (or revision 5.0 or revision 4.0). +This file format is suitable for archiving multi-color and +monochromatic image data. +.PP +The library supports several compression algorithms, as indicated +by the +.I Compression +field, including: +no compression (1), +.SM CCITT +1D Huffman compression (2), +.SM CCITT +Group 3 Facsimile compression (3), +.SM CCITT +Group 4 Facsimile compression (4), +Lempel-Ziv & Welch compression (5), +baseline JPEG compression (7), +word-aligned 1D Huffman compression (32771), +and +PackBits compression (32773). +In addition, several nonstandard compression algorithms are supported: +the 4-bit compression algorithm used +by the +.I ThunderScan +program (32809) (decompression only), +NeXT's 2-bit compression algorithm (32766) (decompression only), +an experimental LZ-style algorithm known as Deflate (32946), and +an experimental CIE LogLuv compression scheme designed for images +with high dynamic range (32845 for LogL and 32845 for LogLuv). +Directory information may be in either little- or big-endian byte +order\-byte swapping is automatically done by the library. +Data bit ordering may be either Most Significant Bit (\c +.SM MSB\c +) to Least Significant Bit (\c +.SM LSB\c +) or +.SM LSB +to +.SM MSB. +Finally, the library does not support files in which the +.IR BitsPerSample , +.IR Compression , +.IR MinSampleValue , +or +.IR MaxSampleValue +fields are defined differently on a per-sample basis +(in Rev. 6.0 the +.I Compression +tag is not defined on a per-sample basis, so this is immaterial). +.SH "DATA TYPES" +The library makes extensive use of C typedefs to promote portability. +Two sets of typedefs are used, one for communication with clients +of the library and one for internal data structures and parsing of the +.SM TIFF +format. +The following typedefs are exposed to users either through +function definitions or through parameters passed through the +varargs interfaces. +.in +.5i +.sp 5p +.ta +\w'typedef unsigned <\fIthing\fP> uint32; 'u +.nf +typedef unsigned short uint16; 16-bit unsigned integer +typedef unsigned <\fIthing\fP> uint32; 32-bit unsigned integer +.sp 5p +typedef unsigned int ttag_t; directory tag +typedef uint16 tdir_t; directory index +typedef uint16 tsample_t; sample number +typedef uint32 tstrip_t; strip number +typedef uint32 ttile_t; tile number +typedef int32 tsize_t; i/o size in bytes +typedef void* tdata_t; image data ref +typedef void* thandle_t; client data handle +typedef int32 toff_t; file offset +.fi +.sp 5p +.in -.5i +Note that +.IR tstrip_t , +.IR ttile_t , +and +.I tsize_t +are constrained to be no more than 32-bit quantities by +32-bit fields they are stored in in the +.SM TIFF +image. +Likewise +.I tsample_t +is limited by the 16-bit field used to store the +.I SamplesPerPixel +tag. +.I tdir_t +constrains the maximum number of +.SM IFDs +that may appear in an image and may be an arbitrary size (w/o penalty). +.I ttag_t +must be either int, unsigned int, pointer, or double because +the library uses a varargs interface and +.SM "ANSI C" +restricts the type of the parameter before an ellipsis to be a +promoted type. +.I toff_t +is defined as int32 because TIFF file offsets are (unsigned) 32-bit +quantities. +A signed value is used because some interfaces return \-1 on error. +Finally, note that user-specified data references are +passed as opaque handles and only cast at the lowest layers where +their type is presumed. +.SH "LIST OF ROUTINES" +The following routines are part of the library. +Consult specific manual pages for details on their operation. +The manual page names listed below are for systems +where the full function names can not be encoded in the filesystem; +on most systems doing ``man function-name'' will work. +.sp 5p +.nf +.ta \w'TIFFWriteEncodedStrip'u+2n +\w'Appears on Page'u+2n +\fIName\fP \fIAppears on Page\fP \fIDescription\fP +.sp 5p +TIFFCheckTile tile.3t very x,y,z,sample is within image +TIFFClientOpen open.3t open a file for reading or writing +TIFFClose close.3t close an open file +TIFFComputeStrip strip.3t return strip containing y,sample +TIFFComputeTile tile.3t return tile containing x,y,z,sample +TIFFCurrentDirectory query.3t return index of current directory +TIFFCurrentRow query.3t return index of current scanline +TIFFCurrentStrip query.3t return index of current strip +TIFFCurrentTile query.3t return index of current tile +TIFFError error.3t library error handler +TIFFFdOpen open.3t open a file for reading or writing +TIFFFileName query.3t return name of open file +TIFFFileno query.3t return open file descriptor +TIFFFlush flush.3t flush all pending writes +TIFFFlushData flush.3t flush pending data writes +TIFFGetBitRevTable swab.3t return bit reversal table +TIFFGetField getfield.3t return tag value in current directory +TIFFGetFieldDefaulted getfield.3t return tag value in current directory +TIFFGetMode query.3t return open file mode +TIFFGetVersion query.3t return library version string +TIFFIsTiled query.3t return true if image data is tiled +TIFFIsByteSwapped query.3t return true if image data is byte-swapped +TIFFNumberOfStrips strip.3t return number of strips in an image +TIFFNumberOfTiles tile.3t return number of tiles in an image +TIFFOpen open.3t open a file for reading or writing +TIFFPrintDirectory print.3t print description of the current directory +TIFFReadBufferSetup rdbuf.3t specify i/o buffer for reading +TIFFReadDirectory readdir.3t read the next directory +TIFFReadEncodedStrip rdestrip.3t read and decode a strip of data +TIFFReadEncodedTile rdetile.3t read and decode a tile of data +TIFFReadRawStrip rdrstrip.3t read a raw strip of data +TIFFReadRawTile rdrtile.3t read a raw tile of data +TIFFReadRGBAImage rdimage.3t read an image into a fixed format raster +TIFFReadScanline readline.3t read and decode a row of data +TIFFReadTile readtile.3t read and decode a tile of data +TIFFReverseBits swab.3t reverse bits in an array of bytes +TIFFRGBAImageBegin rgbaimage.3t setup decoder state for TIFFRGBAImageGet +TIFFRGBAImageEnd rgbaimage.3t release TIFFRGBAImage decoder state +TIFFRGBAImageGet rgbaimage.3t read and decode an image +TIFFRGBAImageOK rgbaimage.3t is image readable by TIFFRGBAImageGet +TIFFScanlineSize size.3t return size of a scanline +TIFFSetDirectory setdir.3t set the current directory +TIFFSetSubDirectory setdir.3t set the current directory +TIFFSetErrorHandler error.3t set error handler function +TIFFSetField setfield.3t set a tag's value in the current directory +TIFFSetWarningHandler error.3t set warning handler function +TIFFStripSize size.3t return size of a strip +TIFFSwabShort swab.3t swap bytes of short +TIFFSwabLong swab.3t swap bytes of long +TIFFSwabArrayOfShort swab.3t swap bytes of an array of shorts +TIFFSwabArrayOfLong swab.3t swap bytes of an array of longs +TIFFTileRowSize size.3t return size of a row in a tile +TIFFTileSize size.3t return size of a tile +TIFFVGetField getfield.3t return tag value in current directory +TIFFVGetFieldDefaulted getfield.3t return tag value in current directory +TIFFVSetField setfield.3t set a tag's value in the current directory +TIFFWarning warning.3t library warning handler +TIFFWriteDirectory writedir.3t write the current directory +TIFFWriteEncodedStrip wrestrip.3t compress and write a strip of data +TIFFWriteEncodedTile wretile.3t compress and write a tile of data +TIFFWriteRawStrip wrrstrip.3t write a raw strip of data +TIFFWriteRawTile wrrtile.3t write a raw tile of data +TIFFWriteScanline writeline.3t write a scanline of data +TIFFWriteTile wrrtile.3t compress and write a tile of data +.fi +.SH "TAG USAGE" +The table below lists the +.SM TIFF +tags that are recognized and handled by the library. +If no use is indicated in the table, then the library +reads and writes the tag, but does not use it internally. +Note that some tags are meaningful only when a particular +compression scheme is being used; e.g. +.I Group3Options +is only useful if +.I Compression +is set to +.SM CCITT +Group 3 encoding. +Tags of this sort are considered +.I codec-specific +tags and the library does not recognize them except when the +.I Compression +tag has been previously set to the relevant compression scheme. +.sp 5p +.nf +.ta \w'TIFFTAG_JPEGTABLESMODE'u+2n +\w'Value'u+2n +\w'R/W'u+2n +\fITag Name\fP \fIValue\fP \fIR/W\fP \fILibrary Use/Notes\fP +.sp 5p +.nf +Artist 315 R/W +BadFaxLines 326 R/W +BitsPerSample 258 R/W lots +CellLength 265 parsed but ignored +CellWidth 264 parsed but ignored +CleanFaxData 327 R/W +ColorMap 320 R/W +ColorResponseUnit 300 parsed but ignored +Compression 259 R/W choosing codec +ConsecutiveBadFaxLines 328 R/W +DataType 32996 R obsoleted by SampleFormat tag +DateTime 306 R/W +DocumentName 269 R/W +DotRange 336 R/W +ExtraSamples 338 R/W lots +FaxRecvParams 34908 R/W +FaxSubAddress 34909 R/W +FaxRecvTime 34910 R/W +FillOrder 266 R/W control bit order +FreeByteCounts 289 parsed but ignored +FreeOffsets 288 parsed but ignored +GrayResponseCurve 291 parsed but ignored +GrayResponseUnit 290 parsed but ignored +Group3Options 292 R/W used by Group 3 codec +Group4Options 293 R/W +HostComputer 316 R/W +ImageDepth 32997 R/W tile/strip calculations +ImageDescription 270 R/W +ImageLength 257 R/W lots +ImageWidth 256 R/W lots +InkNames 333 R/W +InkSet 332 R/W +JPEGTables 347 R/W used by JPEG codec +Make 271 R/W +Matteing 32995 R obsoleted by ExtraSamples tag +MaxSampleValue 281 R/W +MinSampleValue 280 R/W +Model 272 R/W +NewSubFileType 254 R/W called SubFileType in spec +NumberOfInks 334 R/W +Orientation 274 R/W +PageName 285 R/W +PageNumber 297 R/W +PhotometricInterpretation 262 R/W used by Group 3 and JPEG codecs +PlanarConfiguration 284 R/W data i/o +Predictor 317 R/W used by LZW and Deflate codecs +PrimaryChromacities 319 R/W +ReferenceBlackWhite 532 R/W +ResolutionUnit 296 R/W used by Group 3 codec +RowsPerStrip 278 R/W data i/o +SampleFormat 339 R/W +SamplesPerPixel 277 R/W lots +SMinSampleValue 340 R/W +SMaxSampleValue 341 R/W +Software 305 R/W +StoNits 37439 R/W +StripByteCounts 279 R/W data i/o +StripOffsets 273 R/W data i/o +SubFileType 255 R/W called OSubFileType in spec +TargetPrinter 337 R/W +Thresholding 263 R/W +TileByteCounts 324 R/W data i/o +TileDepth 32998 R/W tile/strip calculations +TileLength 323 R/W data i/o +TileOffsets 324 R/W data i/o +TileWidth 322 R/W data i/o +TransferFunction 301 R/W +WhitePoint 318 R/W +XPosition 286 R/W +XResolution 282 R/W +YCbCrCoefficients 529 R/W used by TIFFRGBAImage support +YCbCrPositioning 531 R/W tile/strip size calulcations +YCbCrSubsampling 530 R/W +YPosition 286 R/W +YResolution 283 R/W used by Group 3 codec +.SH "PSEUDO TAGS" +In addition to the normal +.SM TIFF +tags the library supports a collection of +tags whose values lie in a range outside the valid range of +.SM TIFF +tags. +These tags are termed +.I pseud-tags +and are used to control various codec-specific functions within the library. +The table below summarizes the defined pseudo-tags. +.sp 5p +.nf +.ta \w'TIFFTAG_JPEGTABLESMODE'u+2n +\w'Codec'u+2n +\w'R/W'u+2n +\fITag Name\fP \fICodec\fP \fIR/W\fP \fILibrary Use/Notes\fP +.sp 5p +.nf +TIFFTAG_FAXMODE G3 R/W general codec operation +TIFFTAG_FAXFILLFUNC G3/G4 R/W bitmap fill function +TIFFTAG_JPEGQUALITY JPEG R/W compression quality control +TIFFTAG_JPEGCOLORMODE JPEG R/W control colorspace conversions +TIFFTAG_JPEGTABLESMODE JPEG R/W control contents of \fIJPEGTables\fP tag +TIFFTAG_ZIPQUALITY Deflate R/W compression quality level +TIFFTAG_PIXARLOGDATAFMT PixarLog R/W user data format +TIFFTAG_PIXARLOGQUALITY PixarLog R/W compression quality level +TIFFTAG_SGILOGDATAFMT SGILog R/W user data format +.fi +.TP +.B TIFFTAG_FAXMODE +Control the operation of the Group 3 codec. +Possible values (independent bits that can be combined by +or'ing them together) are: +FAXMODE_CLASSIC +(enable old-style format in which the +.SM RTC +is written at the end of the last strip), +FAXMODE_NORTC +(opposite of +FAXMODE_CLASSIC; +also called +FAXMODE_CLASSF), +FAXMODE_NOEOL +(do not write +.SM EOL +codes at the start of each row of data), +FAXMODE_BYTEALIGN +(align each encoded row to an 8-bit boundary), +FAXMODE_WORDALIGN +(align each encoded row to an 16-bit boundary), +The default value is dependent on the compression scheme; this +pseudo-tag is used by the various G3 and G4 codecs to share code. +.TP +.B TIFFTAG_FAXFILLFUNC +Control the function used to convert arrays of black and white +runs to packed bit arrays. +This hook can be used to image decoded scanlines in multi-bit +depth rasters (e.g. for display in colormap mode) +or for other purposes. +The default value is a pointer to a builtin function that images +packed bilevel data. +.TP +.B TIFFTAG_JPEGQUALITY +Control the compression quality level used in the baseline algorithm. +Note that quality levels are in the range 0-100 with a default value of 75. +.TP +.B TIFFTAG_JPEGCOLORMODE +Control whether or not conversion is done between +RGB and YCbCr colorspaces. +Possible values are: +JPEGCOLORMODE_RAW +(do not convert), and +JPEGCOLORMODE_RGB +(convert to/from RGB) +The default value is JPEGCOLORMODE_RAW. +.TP +.B TIFFTAG_JPEGTABLESMODE +Control the information written in the +.I JPEGTables +tag. +Possible values (independent bits that can be combined by +or'ing them together) are: +JPEGTABLESMODE_QUANT +(include quantization tables), +and +JPEGTABLESMODE_HUFF +(include Huffman encoding tables). +The default value is JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF. +.TP +.B TIFFTAG_ZIPQUALITY +Control the compression technique used by the Deflate codec. +Quality levels are in the range 1-9 with larger numbers yielding better +compression at the cost of more computation. +The default quality level is 6 which yields a good time-space tradeoff. +.TP +.B TIFFTAG_PIXARLOGDATAFMT +Control the format of user data passed +.I in +to the PixarLog codec when encoding and passed +.I out +from when decoding. +Possible values are: +PIXARLOGDATAFMT_8BIT +for 8-bit unsigned pixels, +PIXARLOGDATAFMT_8BITABGR +for 8-bit unsigned ABGR-ordered pixels, +PIXARLOGDATAFMT_11BITLOG +for 11-bit log-encoded raw data, +PIXARLOGDATAFMT_12BITPICIO +for 12-bit PICIO-compatible data, +PIXARLOGDATAFMT_16BIT +for 16-bit signed samples, +and +PIXARLOGDATAFMT_FLOAT +for 32-bit IEEE floating point samples. +.TP +.B TIFFTAG_PIXARLOGQUALITY +Control the compression technique used by the PixarLog codec. +This value is treated identically to TIFFTAG_ZIPQUALITY; see the +above description. +.TP +.B TIFFTAG_SGILOGDATAFMT +Control the format of client data passed +.I in +to the SGILog codec when encoding and passed +.I out +from when decoding. +Possible values are: +SGILOGDATAFMT_FLTXYZ +for converting between LogLuv and 32-bit IEEE floating valued XYZ pixels, +SGILOGDATAFMT_16BITLUV +for 16-bit encoded Luv pixels, +SGILOGDATAFMT_32BITRAW and SGILOGDATAFMT_24BITRAW +for no conversion of data, +SGILOGDATAFMT_8BITRGB +for returning 8-bit RGB data (valid only when decoding LogLuv-encoded data), +SGILOGDATAFMT_FLTY +for converting between LogL and 32-bit IEEE floating valued Y pixels, +SGILOGDATAFMT_16BITL +for 16-bit encoded L pixels, +and +SGILOGDATAFMT_8BITGRY +for returning 8-bit greyscale data +(valid only when decoding LogL-encoded data). +.SH DIAGNOSTICS +All error messages are directed through the +.IR TIFFError +routine. +By default messages are directed to +.B stderr +in the form: +.IR "module: message\en." +Warning messages are likewise directed through the +.IR TIFFWarning +routine. +.SH "SEE ALSO" +.IR fax2tiff (1), +.IR gif2tiff (1), +.IR pal2rgb (1), +.IR ppm2tiff (1), +.IR rgb2ycbcr (1), +.IR ras2tiff (1), +.IR sgi2tiff (1), +.IR tiff2bw (1), +.IR tiffdither (1), +.IR tiffdump (1), +.IR tiffcp (1), +.IR tiffcmp (1), +.IR tiffgt (1), +.IR tiffinfo (1), +.IR tiffmedian (1), +.IR tiffsplit (1), +.IR tiffsv (1), +.PP +.IR "Tag Image File Format Specification \(em Revision 6.0" , +an Aldus Technical Memorandum. +.PP +.IR "The Spirit of TIFF Class F" , +an appendix to the TIFF 5.0 specification prepared by Cygnet Technologies. +.SH BUGS +The library does not support multi-sample images +where some samples have different bits/sample. +.PP +The library does not support random access to compressed data +that is organized with more than one row per tile or strip. +The library discards unknown tags. +The library should do more validity checking of a directory's contents. diff --git a/man/pal2rgb.1 b/man/pal2rgb.1 new file mode 100644 index 00000000..fdfab439 --- /dev/null +++ b/man/pal2rgb.1 @@ -0,0 +1,108 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/pal2rgb.1,v 1.1 1999-07-27 21:50:27 mike Exp $ +.\" +.\" Copyright (c) 1990-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH PAL2RGB 1 "October 15, 1995" +.SH NAME +pal2rgb \- convert a palette color +.SM TIFF +image to a full color image +.SH SYNOPSIS +.B pal2rgb +[ +.I options +] +.I input.tif +.I output.tif +.SH DESCRIPTION +.I Pal2rgb +converts a palette color +.SM TIFF +image to a full color image by +applying the colormap of the palette image to each sample +to generate a full color +.SM RGB +image. +.SH OPTIONS +Options that affect the interpretation of input data are: +.TP +.B \-C +This option overrides the default behaviour of +.I pal2rgb +in determining whether or not +colormap entries contain 16-bit or 8-bit values. +By default the colormap is inspected and +if no colormap entry greater than 255 is found, +the colormap is assumed to have only 8-bit values; otherwise +16-bit values (as required by the +.SM TIFF +specification) are assumed. +The +.B \-C +option can be used to explicitly specify the number of +bits for colormap entries: +.B "\-C 8" +for 8-bit values, +.B "\-C 16" +for 16-bit values. +.PP +Options that affect the output file format are: +.TP +.B \-p +Explicitly select the planar configuration used in organizing +data samples in the output image: +.B "\-p contig" +for samples packed contiguously, and +.B "\-p separate" +for samples stored separately. +By default samples are packed. +.TP +.B \-c +Use the specific compression algorithm to encoded image data +in the output file: +.B "\-c packbits" +for Macintosh Packbits, +.B "\-c lzw" +for Lempel-Ziv & Welch, +.B "\-c zip" +for Deflate, +.B "\-c none" +for no compression. +If no compression-related option is specified, the input +file's compression algorithm is used. +.TP +.B \-r +Explicitly specify the number of rows in each strip of the +output file. +If the +.B \-r +option is not specified, a number is selected such that each +output strip has approximately 8 kilobytes of data in it. +.SH BUGS +Only 8-bit images are handled. +.SH "SEE ALSO" +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/ppm2tiff.1 b/man/ppm2tiff.1 new file mode 100644 index 00000000..06e7bd3f --- /dev/null +++ b/man/ppm2tiff.1 @@ -0,0 +1,97 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/ppm2tiff.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH PPM2TIFF 1 "October 15, 1995" +.SH NAME +ppm2tiff \- create a +.SM TIFF +file from a +.SM PPM +image file +.SH SYNOPSIS +.B ppm2tiff +[ +.I options +] [ +.I input.ppm +] +.I output.tif +.SH DESCRIPTION +.I ppm2tiff +converts a file in the +.SM PPM +image format to +.SM TIFF. +By default, the +.SM TIFF +image is created with data samples packed (\c +.IR PlanarConfiguration =1), +compressed with the Lempel-Ziv & Welch algorithm (\c +.IR Compression =5), +and with each strip no more than 8 kilobytes. +These characteristics can be overriden, or explicitly specified +with the options described below +.PP +If the +.SM PPM +file contains greyscale data, then the +.I PhotometricInterpretation +tag is set to 1 (min-is-black), +otherwise it is set to 2 (RGB). +.PP +If no +.SM PPM +file is specified on the command line, +.I ppm2tiff +will read from the standard input. +.SH OPTIONS +.TP +.B \-c +Specify a compression scheme to use when writing image data: +.B "\-c none" +for no compression, +.B "-c packbits" +for the PackBits compression algorithm, +.B "-c jpeg" +for the baseline JPEG compression algorithm, +.B "-c zip +for the Deflate compression algorithm, +and +.B "\-c lzw" +for Lempel-Ziv & Welch compression (the default). +.TP +.B \-r +Write data with a specified number of rows per strip; +by default the number of rows/strip is selected so that each strip +is approximately 8 kilobytes. +.TP +.B \-R +Mark the resultant image to have the specified +X and Y resolution (in dots/inch). +.SH "SEE ALSO" +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/ras2tiff.1 b/man/ras2tiff.1 new file mode 100644 index 00000000..e4c5330e --- /dev/null +++ b/man/ras2tiff.1 @@ -0,0 +1,92 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/ras2tiff.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1990-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH RAS2TIFF 1 "October 15, 1995" +.SH NAME +ras2tiff \- create a +.SM TIFF +file from a Sun rasterfile +.SH SYNOPSIS +.B ras2tiff +[ +.I options +] +.I input.ras +.I output.tif +.SH DESCRIPTION +.I ras2tiff +converts a file in the Sun rasterfile format to +.SM TIFF. +By default, the +.SM TIFF +image is created with data samples packed (\c +.IR PlanarConfiguration =1), +compressed with the Lempel-Ziv & Welch algorithm (\c +.IR Compression =5), +and with each strip no more than 8 kilobytes. +These characteristics can overriden, or explicitly specified +with the options described below. +.PP +Any colormap information in the rasterfile is carried over to the +.SM TIFF +file by including a +.I Colormap +tag in the output file. +If the rasterfile has a colormap, the +.I PhotometricInterpretation +tag is set to 3 (palette); +otherwise it is set to 2 (RGB) if the depth +is 24 or 1 (min-is-black) if the depth is not 24. +.SH OPTIONS +.TP +.B \-c +Specify a compression scheme to use when writing image data: +.B "\-c none" +for no compression, +.B "-c packbits" +for the PackBits compression algorithm, +.B "-c jpeg" +for the baseline JPEG compression algorithm, +.B "-c zip +for the Deflate compression algorithm, +and +.B "\-c lzw" +for Lempel-Ziv & Welch (the default). +.TP +.B \-r +Write data with a specified number of rows per strip; +by default the number of rows/strip is selected so that each strip +is approximately 8 kilobytes. +.SH BUGS +Does not handle all possible rasterfiles. +In particular, +.I ras2tiff +does not handle run-length encoded images. +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/rgb2ycbcr.1 b/man/rgb2ycbcr.1 new file mode 100644 index 00000000..12256f96 --- /dev/null +++ b/man/rgb2ycbcr.1 @@ -0,0 +1,98 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/rgb2ycbcr.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH RGB2YCBCR 1 "October 15, 1995" +.SH NAME +rgb2ycbcr \- convert non-YCbCr +.SM TIFF +images to a YCbCr +.SM TIFF +image +.SH SYNOPSIS +.B rgb2ycbcr +[ +.I options +] +.I "src1.tif src2.tif ... dst.tif" +.SH DESCRIPTION +.I rgb2ycbcr +converts +.SM RGB +color, greyscale, or bi-level +.SM TIFF +images to YCbCr images by +transforming and sampling pixel data. +If multiple files are specified on the command line +each source file is converted to a separate directory +in the destination file. +.PP +By default, chrominance samples are created by sampling +2 by 2 blocks of luminance values; this can be changed with +the +.B \-h +and +.B \-v +options. +Output data are compressed with the +.SM LZW +compression scheme, by default; an alternate scheme can be +selected with the +.B \-c +option. +By default, output data are compressed in strips with +the number of rows in each strip selected so that the +size of a strip is never more than 8 kilobytes; +the +.B \-r +option can be used to explicitly set the number of +rows per strip. +.SH OPTIONS +.TP +.B \-c +Specify a compression scheme to use when writing image data: +.B "\-c none" +for no compression, +.B "-c packbits" +for the PackBits compression algorithm, +.B "-c jpeg" +for the JPEG compression algorithm, +and +.B "\-c lzw" +for Lempel-Ziv & Welch (the default). +.TP +.B \-h +Set the horizontal sampling dimension to one of: 1, 2 (default), or 4. +.TP +.B \-r +Write data with a specified number of rows per strip; +by default the number of rows/strip is selected so that each strip +is approximately 8 kilobytes. +.TP +.B \-v +Set the vertical sampling dimension to one of: 1, 2 (default), or 4. +.SH "SEE ALSO" +.IR tiffinfo (1), +.IR tiffcp (1), +.IR libtiff (3) diff --git a/man/sgi2tiff.1 b/man/sgi2tiff.1 new file mode 100644 index 00000000..f395c055 --- /dev/null +++ b/man/sgi2tiff.1 @@ -0,0 +1,90 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/sgi2tiff.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1991-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH SGI2TIFF 1 "October 15, 1995" +.SH NAME +sgi2tiff \- create a +.SM TIFF +file from an +.SM SGI +image file +.SH SYNOPSIS +.B sgi2tiff +[ +.I options +] +.I input.rgb +.I output.tif +.SH DESCRIPTION +.I sgi2tiff +converts a file in the +.SM SGI +image format to +.SM TIFF. +By default, the +.SM TIFF +image is created with data samples packed (\c +.IR PlanarConfiguration =1), +compressed with the Lempel-Ziv & Welch algorithm (\c +.IR Compression =5), +and with each strip no more than 8 kilobytes. +These characteristics can overriden, or explicitly specified +with the options described below. +.SH OPTIONS +.TP +.B \-c +Specify a compression scheme to use when writing image data: +.B "\-c none" +for no compression, +.B "-c packbits" +for the PackBits compression algorithm), +.B "-c jpeg" +for the baseline JPEG compression algorithm, +.B "-c zip +for the Deflate compression algorithm, +and +.B "\-c lzw" +for Lempel-Ziv & Welch (the default). +.TP +.B \-p +Explicitly select the planar configuration used in organizing +data samples in the output image: +.B "\-p contig" +for samples packed contiguously, and +.B "\-p separate" +for samples stored separately. +By default samples are packed. +.TP +.B \-r +Write data with a specified number of rows per strip; +by default the number of rows/strip is selected so that each strip +is approximately 8 kilobytes. +.SH BUGS +Does not record colormap information. +.SH "SEE ALSO" +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/thumbnail.1 b/man/thumbnail.1 new file mode 100644 index 00000000..ab544676 --- /dev/null +++ b/man/thumbnail.1 @@ -0,0 +1,87 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/thumbnail.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1994-1997 Sam Leffler +.\" Copyright (c) 1994-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH THUMBNAIL 1 "September 26, 1994" +.SH NAME +thumbnail \- create a +.SM TIFF +file with thumbnail images +.SH SYNOPSIS +.B thumbnail +[ +.I options +] +.I input.tif +.I output.tif +.SH DESCRIPTION +.I thumbnail +is a program written to show how one might use the +SubIFD tag (#330) to store thumbnail images. +.I thumbnail +copies a +.SM TIFF +Class F facsimile file to the output file +and for each image an 8-bit greyscale +.IR "thumbnail sketch" . +The output file contains the thumbnail image with the associated +full-resolution page linked below with the SubIFD tag. +.PP +By default, thumbnail images are 216 pixels wide by 274 pixels high. +Pixels are calculated by sampling and filtering the input image +with each pixel value passed through a contrast curve. +.SH OPTIONS +.TP +.B \-w +Specify the width of thumbnail images in pixels. +.TP +.B \-h +Specify the height of thumbnail images in pixels. +.TP +.B \-c +Specify a contrast curve to apply in generating the thumbnail images. +By default pixels values are passed through a linear contrast curve +that simply maps the pixel value ranges. +Alternative curves are: +.B exp50 +for a 50% exponential curve, +.B exp60 +for a 60% exponential curve, +.B exp70 +for a 70% exponential curve, +.B exp80 +for a 80% exponential curve, +.B exp90 +for a 90% exponential curve, +.B exp +for a pure exponential curve, +.B linear +for a linear curve. +.SH BUGS +There are no options to control the format of the saved thumbnail images. +.SH "SEE ALSO" +.IR tiffdump (1), +.IR tiffgt (1), +.IR tiffinfo (1), +.IR libtiff (3) diff --git a/man/tiff2bw.1 b/man/tiff2bw.1 new file mode 100644 index 00000000..5d979a60 --- /dev/null +++ b/man/tiff2bw.1 @@ -0,0 +1,91 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiff2bw.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFF2BW 1 "October 15, 1995" +.SH NAME +tiff2bw \- convert a color +.SM TIFF +image to greyscale +.SH SYNOPSIS +.B tiff2bw +[ +options +] +.I input.tif +.I output.tif +.SH DESCRIPTION +.I Tiff2bw +converts an +.SM RGB +or Palette color +.SM TIFF +image to a greyscale image by +combining percentages of the red, green, and blue channels. +By default, output samples are created by taking +28% of the red channel, 59% of the green channel, and 11% of +the blue channel. +To alter these percentages, the +.BR \-R , +.BR \-G , +and +.BR \-B +options may be used. +.SH OPTIONS +.TP +.B \-c +Specify a compression scheme to use when writing image data: +.B "\-c none" +for no compression, +.B "-c packbits" +for the PackBits compression algorithm, +.B "-c zip +for the Deflate compression algorithm, +.B "-c g3 +for the CCITT Group 3 compression algorithm, +.B "-c g4 +for the CCITT Group 4 compression algorithm, +and +.B "\-c lzw" +for Lempel-Ziv & Welch (the default). +.TP +.B \-r +Write data with a specified number of rows per strip; +by default the number of rows/strip is selected so that each strip +is approximately 8 kilobytes. +.TP +.B \-R +Specify the percentage of the red channel to use (default 28). +.TP +.B \-G +Specify the percentage of the green channel to use (default 59). +.TP +.B \-B +Specify the percentage of the blue channel to use (default 11). +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/tiff2ps.1 b/man/tiff2ps.1 new file mode 100644 index 00000000..8a422779 --- /dev/null +++ b/man/tiff2ps.1 @@ -0,0 +1,177 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiff2ps.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.ds Ps P\s-2OST\s+2S\s-2CRIPT\s+2 +.TH TIFF2PS 1 "January 27, 1997" +.SH NAME +tiff2ps \- convert a +.SM TIFF +image to \*(Ps\(tm +.SH SYNOPSIS +.B tiff2ps +[ +.I options +] +.I "input.tif ..." +.SH DESCRIPTION +.I tiff2ps +reads +.SM TIFF +images and writes \*(Ps or Encapsulated \*(Ps (EPS) +on the standard output. +By default, +.I tiff2ps +writes Encapsulated \*(Ps for the first image in the specified +.SM TIFF +image file. +.PP +By default, +.I tiff2ps +will generate \*(Ps that fills a printed area specified +by the +.SM TIFF +tags in the input file. +If the file does not contain +.I XResolution +or +.I YResolution +tags, then the printed area is set according to the image dimensions. +The +.B \-w +and +.B \-h +options (see below) +can be used to set the dimensions of the printed area in inches; +overriding any relevant +.SM TIFF +tags. +.PP +The \*(Ps generated for +.SM RGB, +palette, and +.SM CMYK +images uses the +.I colorimage +operator. +The \*(Ps generated for +greyscale and bilevel images +uses the +.I image +operator. +When the +.I colorimage +operator is used, \*(Ps code to emulate this operator +on older \*(Ps printers is also generated. +Note that this emulation code can be very slow. +.PP +Color images with associated alpha data are composited over +a white background. +.SH OPTIONS +.TP +.B \-1 +Generate \*(Ps Level I (the default). +.TP +.B \-2 +Generate \*(Ps Level II. +.TP +.B \-a +Generate output for all IFDs (pages) in the input file. +.TP +.B \-d +Set the initial +.SM TIFF +directory to the specified directory number. +(NB: directories are numbered starting at zero.) +This option is useful for selecting individual pages in a +multi-page (e.g. facsimile) file. +.TP +.B \-e +Force the generation of Encapsulated \*(Ps. +.TP +.B \-h +Specify the vertical size of the printed area (in inches). +.TP +.B \-o +Set the initial +.SM TIFF +directory to the +.SM IFD +at the specified file offset. +This option is useful for selecting thumbnail images and the +like which are hidden using the SubIFD tag. +.TP +.B \-p +Force the generation of (non-Encapsulated) \*(Ps. +.TP +.B \-s +Generate output for a single IFD (page) in the input file. +.TP +.B \-w +Specify the horizontal size of the printed area (in inches). +.TP +.B \-z +When generating \*(Ps Level II, data is scaled so that it does not +image into the +.I deadzone +on a page (the outer margin that the printing device is unable to mark). +This option suppresses this behaviour. +When \*(Ps Level I is generated, data is imaged to the entire printed +page and this option has no affect. +.SH EXAMPLES +The following generates \*(Ps Level II for all pages of a facsimile: +.RS +.nf +tiff2ps -a2 fax.tif | lpr +.fi +.RE +Note also that if you have version 2.6.1 or newer of Ghostscript then you +can efficiently preview facsimile generated with the above command. +.PP +To generate Encapsulated \*(Ps for a the image at directory 2 +of an image use: +.RS +.nf +tiff2ps -d 1 foo.tif +.fi +.RE +(notice that directories are numbered starting at zero.) +.SH BUGS +Because \*(Ps does not support the notion of a colormap, +8-bit palette images produce 24-bit \*(Ps images. +This conversion results in output that is six times +bigger than the original image and which takes a long time +to send to a printer over a serial line. +Matters are even worse for 4-, 2-, and 1-bit palette images. +.SH BUGS +Does not handle tiled images when generating PS Level I output. +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffgt (1), +.IR tiffmedian (1), +.IR tiff2bw (1), +.IR tiffsv (1), +.IR libtiff (3) diff --git a/man/tiffcmp.1 b/man/tiffcmp.1 new file mode 100644 index 00000000..91e37bbf --- /dev/null +++ b/man/tiffcmp.1 @@ -0,0 +1,74 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffcmp.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFCMP 1 "September 26, 1994" +.SH NAME +tiffcmp \- compare two +.SM TIFF +files +.SH SYNOPSIS +.B tiffcmp +[ +.I options +] +.I "file1.tif file2.tif" +.SH DESCRIPTION +.I Tiffcmp +compares the tags and data in two files created according +to the Tagged Image File Format, Revision 6.0. +The schemes used for compressing data in each file +are immaterial when data are compared\-data are compared on +a scanline-by-scanline basis after decompression. +Most directory tags are checked; notable exceptions are: +.IR GrayResponseCurve , +.IR ColorResponseCurve , +and +.IR ColorMap +tags. +Data will not be compared if any of the +.IR BitsPerSample , +.IR SamplesPerPixel , +or +.I ImageWidth +values are not equal. +By default, +.I tiffcmp +will terminate if it encounters any difference. +.SH OPTIONS +.TP +.B \-l +List each byte of image data that differs between the files. +.TP +.B \-t +Ignore any differences in directory tags. +.SH BUGS +Tags that are not recognized by the library are not +compared; they may also generate spurious diagnostics. +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/tiffcp.1 b/man/tiffcp.1 new file mode 100644 index 00000000..82485131 --- /dev/null +++ b/man/tiffcp.1 @@ -0,0 +1,221 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffcp.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFCP 1 "January 9, 1996" +.SH NAME +tiffcp \- copy (and possibly convert) a +.SM TIFF +file +.SH SYNOPSIS +.B tiffcp +[ +.I options +] +.I "src1.tif ... srcN.tif dst.tif" +.SH DESCRIPTION +.I tiffcp +combines one or more files created according +to the Tag Image File Format, Revision 6.0 +into a single +.SM TIFF +file. +Because the output file may be compressed using a different +algorithm than the input files, +.I tiffcp +is most often used to convert between different compression +schemes. +.PP +By default, +.I tiffcp +will copy all the understood tags in a +.SM TIFF +directory of an input +file to the associated directory in the output file. +.PP +.I tiffcp +can be used to reorganize the storage characteristics of data +in a file, but it is explicitly intended to not alter or convert +the image data content in any way. +.SH OPTIONS +.TP +.B \-B +Force output to be written with Big-Endian byte order. +This option only has an effect when the output file is created or +overwritten and not when it is appended to. +.TP +.B \-C +Suppress the use of ``strip chopping'' when reading images +that have a single strip/tile of uncompressed data. +.TP +.B \-c +Specify the compression to use for data written to the output file: +.B none +for no compression, +.B packbits +for PackBits compression, +.B lzw +for Lempel-Ziv & Welch compression, +.B jpeg +for baseline JPEG compression, +.B zip +for Deflate compression, +.B g3 +for CCITT Group 3 (T.4) compression, +and +.B g4 +for CCITT Group 4 (T.6) compression. +By default +.I tiffcp +will compress data according to the value of the +.I Compression +tag found in the source file. +.IP +The +.SM CCITT +Group 3 and Group 4 compression algorithms can only +be used with bilevel data. +.IP +Group 3 compression can be specified together with several +T.4-specific options: +.B 1d +for 1-dimensional encoding, +.B 2d +for 2-dimensional encoding, +and +.B fill +to force each encoded scanline to be zero-filled so that the +terminating EOL code lies on a byte boundary. +Group 3-specific options are specified by appending a ``:''-separated +list to the ``g3'' option; e.g. +.B "\-c g3:2d:fill" +to get 2D-encoded data with byte-aligned EOL codes. +.IP +.SM LZW +compression can be specified together with a +.I predictor +value. +A predictor value of 2 causes +each scanline of the output image to undergo horizontal +differencing before it is encoded; a value +of 1 forces each scanline to be encoded without differencing. +LZW-specific options are specified by appending a ``:''-separated +list to the ``lzw'' option; e.g. +.B "\-c lzw:2" +for +.SM LZW +compression with horizontal differencing. +.TP +.B \-f +Specify the bit fill order to use in writing output data. +By default, +.I tiffcp +will create a new file with the same fill order as the original. +Specifying +.B "\-f lsb2msb" +will force data to be written with the FillOrder tag set to +.SM LSB2MSB, +while +.B "\-f msb2lsb" +will force data to be written with the FillOrder tag set to +.SM MSB2LSB. +.TP +.B \-l +Specify the length of a tile (in pixels). +.I tiffcp +attempts to set the tile dimensions so +that no more than 8 kilobytes of data appear in a tile. +.TP +.B \-L +Force output to be written with Little-Endian byte order. +This option only has an effect when the output file is created or +overwritten and not when it is appended to. +.TP +.B \-M +Suppress the use of memory-mapped files when reading images. +.TP +.B \-p +Specify the planar configuration to use in writing image data +that has one 8-bit sample per pixel. +By default, +.I tiffcp +will create a new file with the same planar configuration as +the original. +Specifying +.B "\-p contig" +will force data to be written with multi-sample data packed +together, while +.B "\-p separate" +will force samples to be written in separate planes. +.TP +.B \-r +Specify the number of rows (scanlines) in each strip of data +written to the output file. +By default, +.I tiffcp +attempts to set the rows/strip +that no more than 8 kilobytes of data appear in a strip. +.TP +.B \-s +Force the output file to be written with data organized in strips +(rather than tiles). +.TP +.B \-t +Force the output file to be written wtih data organized in tiles +(rather than strips). +options can be used to force the resultant image to be written +as strips or tiles of data, respectively. +.TP +.B \-w +Specify the width of a tile (in pixels). +.I tiffcp +attempts to set the tile dimensions so +that no more than 8 kilobytes of data appear in a tile. +.SH EXAMPLES +The following concatenates two files and writes the result using +.SM LZW +encoding: +.RS +.nf +tiffcp -c lzw a.tif b.tif result.tif +.fi +.RE +.PP +To convert a G3 1d-encoded +.SM TIFF +to a single strip of G4-encoded data the following might be used: +.RS +.nf +tiffcp -c g4 -r 10000 g3.tif g4.tif +.fi +.RE +(1000 is just a number that is larger than the number of rows in +the source file.) +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcmp (1), +.IR tiffmedian (1), +.IR tiffsplit (1), +.IR libtiff (3) diff --git a/man/tiffdither.1 b/man/tiffdither.1 new file mode 100644 index 00000000..1f8684cf --- /dev/null +++ b/man/tiffdither.1 @@ -0,0 +1,125 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffdither.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1990-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFDITHER 1 "October 15, 1995" +.SH NAME +tiffdither \- convert a greyscale image to bilevel using dithering +.SH SYNOPSIS +.B tiffdither +[ +.I options +] +.I input.tif +.I output.tif +.SH DESCRIPTION +.I tiffdither +converts a single channel 8-bit greyscale image to a bilevel image +using Floyd-Steinberg error propagation with threholding. +.SH OPTIONS +.TP +.B \-c +Specify the compression to use for data written to the output file: +.B none +for no compression, +.B packbits +for PackBits compression, +.B lzw +for Lempel-Ziv & Welch compression, +.B zip +for Deflate compression, +.B g3 +for CCITT Group 3 (T.4) compression, +and +.B g4 +for CCITT Group 4 (T.6) compression. +By default +.I tiffdither +will compress data according to the value of the +.I Compression +tag found in the source file. +.IP +The +.SM CCITT +Group 3 and Group 4 compression algorithms can only +be used with bilevel data. +.IP +Group 3 compression can be specified together with several +T.4-specific options: +.B 1d +for 1-dimensional encoding, +.B 2d +for 2-dimensional encoding, +and +.B fill +to force each encoded scanline to be zero-filled so that the +terminating EOL code lies on a byte boundary. +Group 3-specific options are specified by appending a ``:''-separated +list to the ``g3'' option; e.g. +.B "\-c g3:2d:fill" +to get 2D-encoded data with byte-aligned EOL codes. +.IP +.SM LZW +compression can be specified together with a +.I predictor +value. +A predictor value of 2 causes +each scanline of the output image to undergo horizontal +differencing before it is encoded; a value +of 1 forces each scanline to be encoded without differencing. +LZW-specific options are specified by appending a ``:''-separated +list to the ``lzw'' option; e.g. +.B "\-c lzw:2" +for +.SM LZW +compression with horizontal differencing. +.TP +.B \-f +Specify the bit fill order to use in writing output data. +By default, +.I tiffdither +will create a new file with the same fill order as the original. +Specifying +.B "\-f lsb2msb" +will force data to be written with the FillOrder tag set to +.SM LSB2MSB , +while +.B "\-f msb2lsb" +will force data to be written with the FillOrder tag set to +.SM MSB2LSB . +.TP +.B \-t +Set the threshold value for dithering. +By default the threshold value is 128. +.SH NOTES +The dither algorithm is taken from the +.IR tiffmedian (1) +program (written by Paul Heckbert). +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR fax2tiff (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiff2bw (1), +.IR libtiff (3) diff --git a/man/tiffdump.1 b/man/tiffdump.1 new file mode 100644 index 00000000..efc91551 --- /dev/null +++ b/man/tiffdump.1 @@ -0,0 +1,74 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffdump.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFDUMP 1 "October 15, 1995" +.SH NAME +tiffdump \- print verbatim information about +.SM TIFF +files +.SH SYNOPSIS +.B tiffdump +[ +.I options +] +.I "name \&..." +.SH DESCRIPTION +.I tiffdump +displays directory information from files created according +to the Tag Image File Format, Revision 6.0. +The header of each +.SM TIFF +file (magic number, version, and first directory offset) +is displayed, followed by the tag contents of each directory in the file. +For each tag, the name, datatype, count, and value(s) is displayed. +When the symbolic name for a tag or datatype is known, the symbolic +name is displayed followed by it's numeric (decimal) value. +Tag values are displayed enclosed in ``<>'' characters immediately +preceded by the value of the count field. +For example, an +.I ImageWidth +tag might be displayed as ``ImageWidth (256) SHORT (3) 1<800>''. +.PP +.I tiffdump +is particularly useful for investigating the contents of +.SM TIFF +files that +.I libtiff +does not understand. +.SH OPTIONS +.TP +.B \-h +Force numeric data to be printed in hexadecimal rather than the +default decimal. +.TP +.B \-o +Dump the contents of the +.SM IFD +at the a particular file offset. +The file offset may be specified using the usual C-style syntax; +i.e. a leading ``0x'' for hexadecimal and a leading ``0'' for octal. +.SH "SEE ALSO" +.IR tiffinfo (1), +.IR libtiff (3) diff --git a/man/tiffgt.1 b/man/tiffgt.1 new file mode 100644 index 00000000..1e2a2c05 --- /dev/null +++ b/man/tiffgt.1 @@ -0,0 +1,242 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffgt.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFGT 1 "October 15, 1995" +.SH NAME +tiffgt \- display an image stored in a +.SM TIFF +file (Silicon Graphics version) +.SH SYNOPSIS +.B tiffgt +[ +.I options +] +.I "input.tif ..." +.SH DESCRIPTION +.I tiffgt +displays one or more images stored using the +Tag Image File Format, Revision 6.0. +Each image is placed in a fixed size window that the +user must position on the display (unless configured +otherwise through X defaults). +If the display has fewer than 24 bitplanes, or if the +image does not warrant full color, then +.SM RGB +color values are mapped to the closest values that exist in +the colormap (this is done using the +.I rgbi +routine found in the graphics utility library +.BR \-lgutil .) +.PP +.I tiffgt +correctly handles files with any of the following characteristics: +.sp .5 +.in +0.5i +.ta \w'\fIPhotometricInterpretation\fP 'u +.nf +BitsPerSample 1, 2, 4, 8, 16 +SamplesPerPixel 1, 3, 4 (the 4th sample is ignored) +PhotometricInterpretation 0 (min-is-white), 1 (min-is-black), 2 (RGB), 3 (palette), 6 (YCbCr) +PlanarConfiguration 1 (contiguous), 2 (separate) +Orientation 1 (top-left), 4 (bottom-left) +.fi +.in -0.5i +.sp .5 +Data may be organized as strips or tiles and may be +compressed with any of the compression algorithms supported +by the +.IR libtiff (3) +library. +.PP +For palette images (\c +.IR PhotomatricInterpretation =3), +.I tiffgt +inspects the colormap values and assumes either 16-bit +or 8-bit values according to the maximum value. +That is, if no colormap entry greater than 255 is found, +.I tiffgt +assumes the colormap has only 8-bit values; otherwise +it assumes 16-bit values. +This inspection is done to handle old images written by +previous (incorrect) versions of +.IR libtiff . +.PP +.I tiffgt +can be used to display multiple images one-at-a-time. +The left mouse button switches the display to the first image in the +.I next +file in the list of files specified on the command line. +The right mouse button switches to the first image in the +.I previous +file in the list. +The middle mouse button causes the first image in the first file +specified on the command line to be displayed. +In addition the following keyboard commands are recognized: +.TP +.B b +Use a +.I PhotometricIntepretation +of MinIsBlack in displaying the current image. +.TP +.B l +Use a +.I FillOrder +of lsb-to-msb in decoding the current image. +.TP +.B m +Use a +.I FillOrder +of msb-tolmsb in decoding the current image. +.TP +.B c +Use a colormap visual to display the current image. +.TP +.B r +Use a true color (24-bit RGB) visual to display the current image. +.TP +.B w +Use a +.I PhotometricIntepretation +of MinIsWhite in displaying the current image. +.TP +.B W +Toggle (enable/disable) display of warning messages from the +.SM TIFF +library when decoding images. +.TP +.B E +Toggle (enable/disable) display of error messages from the +.SM TIFF +library when decoding images. +.TP +.B z +Reset all parameters to their default settings (\c +.IR FillOrder , +.IR PhotometricInterpretation , +handling of warnings and errors). +.TP +.B PageUp +Display the previous image in the current file or the last +image in the previous file. +.TP +.B PageDown +Display the next image in the current file or the first image +in the next file. +.TP +.B Home +Display the first image in the current file. +.TP +.B End +Display the last image in the current file (unimplemented). +.SH OPTIONS +.TP +.B \-c +Force image display in a colormap window. +.TP +.B \-d +Specify an image to display by directory number. +By default the first image in the file is displayed. +Directories are numbered starting at zero. +.TP +.B \-e +Enable reporting of error messages from the +.SM TIFF +library. +By default +.I tiffgt +silently ignores images that cannot be read. +.TP +.B \-f +Force +.I tiffgt +to run as a foreground process. +By default +.I tiffgt +will place itself in the background once it has opened the +requested image file. +.TP +.B \-l +Force the presumed bit ordering to be +.SM LSB +to +.SM MSB. +.TP +.B \-m +Force the presumed bit ordering to be +.SM MSB +to +.SM LSB. +.TP +.B \-o +Specify an image to display by directory offset. +By default the first image in the file is displayed. +Directories offsets may be specified using C-style syntax; +i.e. a leading ``0x'' for hexadecimal and a leading ``0'' for octal. +.TP +.B \-p +Override the value of the +.I PhotometricInterpretation +tag; the parameter may be one of: +.IR miniswhite , +.IR minisblack , +.IR rgb , +.IR palette , +.IR mask , +.IR separated , +.IR ycbcr , +and +.IR cielab . +.TP +.B \-r +Force image display in a full color window. +.TP +.B \-s +Stop on the first read error. +By default all errors in the input data are ignored and +.I tiffgt +does it's best to display as much of an image as possible. +.TP +.B \-w +Enable reporting of warning messages from the +.SM TIFF +library. +By default +.I tiffgt +ignores warning messages generated when reading an image. +.TP +.B \-v +Place information in the title bar describing +what type of window (full color or colormap) is being +used, the name of the input file, and the directory +index of the image (if non-zero). +By default, the window type is not shown in the title bar. +.SH BUGS +Images wider and taller than the display are silently truncated to avoid +crashing old versions of the window manager. +.SH "SEE ALSO" +.IR tiffdump (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR libtiff (3) diff --git a/man/tiffinfo.1 b/man/tiffinfo.1 new file mode 100644 index 00000000..811918fc --- /dev/null +++ b/man/tiffinfo.1 @@ -0,0 +1,85 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffinfo.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFINFO 1 "January 27, 1997" +.SH NAME +tiffinfo \- print information about +.SM TIFF +files +.SH SYNOPSIS +.B tiffinfo +[ +.I options +] +.I "input.tif \&..." +.SH DESCRIPTION +.I Tiffinfo +displays information about files created according +to the Tag Image File Format, Revision 6.0. +By default, the contents of each +.SM TIFF +directory in each file +is displayed, with the value of each tag shown symbolically +(where sensible). +.SH OPTIONS +.TP +.B \-c +Display the colormap and color/gray response curves, if present. +.TP +.B \-D +In addition to displaying the directory tags, +read and decompress all the data in each image (but not display it). +.TP +.B \-d +In addition to displaying the directory tags, +print each byte of decompressed data in hexadecimal. +.TP +.B \-j +Display any \s-2JPEG\s0-related tags that are present. +.TP +.B \-o +Set the initial +.SM TIFF +directory according to the specified file offset. +The file offset may be specified using the usual C-style syntax; +i.e. a leading ``0x'' for hexadecimal and a leading ``0'' for octal. +.TP +.B \-s +Display the offsets and byte counts for each data strip in a directory. +.TP +.B \-z +Enable strip chopping when reading image data. +.TP +.B \-# +Set the initial +.SM TIFF +directory to +.IR # . +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffcp (1), +.IR tiffcmp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/man/tiffmedian.1 b/man/tiffmedian.1 new file mode 100644 index 00000000..7b6c9466 --- /dev/null +++ b/man/tiffmedian.1 @@ -0,0 +1,109 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffmedian.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1990-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFMEDIAN 1 "October 15, 1995" +.SH NAME +tiffmedian \- apply the median cut algorithm to data in a +.SM TIFF +file +.SH SYNOPSIS +.B tiffmedian +[ +.I options +] +.I input.tif +.I output.tif +.SH DESCRIPTION +.I tiffmedian +applys the median cut algorithm to an +.SM RGB +image in +.I input.tif +to generate a palette image that is written to +.IR output.tif . +The generated colormap has, by default, 256 entries. +The image data is quantized by mapping each +pixel to the closest color values in the colormap. +.SH OPTIONS +.TP +.B \-c +Specify the compression to use for data written to the output file: +.B none +for no compression, +.B packbits +for PackBits compression, +.B lzw +for Lempel-Ziv & Welch compression, +and +.B zip +for Deflate compression. +By default +.I tiffmedian +will compress data according to the value of the +.I Compression +tag found in the source file. +.IP +.SM LZW +compression can be specified together with a +.I predictor +value. +A predictor value of 2 causes +each scanline of the output image to undergo horizontal +differencing before it is encoded; a value +of 1 forces each scanline to be encoded without differencing. +LZW-specific options are specified by appending a ``:''-separated +list to the ``lzw'' option; e.g. +.B "\-c lzw:2" +for +.SM LZW +compression with horizontal differencing. +.TP +.B \-C +Specify the number of entries to use in the generated colormap. +By default all 256 entries/colors are used. +.TP +.B \-f +Apply Floyd-Steinberg dithering before selecting a colormap entry. +.TP +.B \-r +Specify the number of rows (scanlines) in each strip of data +written to the output file. +By default, +.I tiffmedian +attempts to set the rows/strip +that no more than 8 kilobytes of data appear in a strip. +.SH NOTES +This program is derived from Paul Heckbert's +.I median +program. +.SH "SEE ALSO" +.IR pal2rgb (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffcmp (1), +.IR libtiff (3) +.PP +"Color Image Quantization for Frame Buffer Display", Paul +Heckbert, SIGGRAPH proceedings, 1982, pp. 297-307. diff --git a/man/tiffsplit.1 b/man/tiffsplit.1 new file mode 100644 index 00000000..4bf075a2 --- /dev/null +++ b/man/tiffsplit.1 @@ -0,0 +1,66 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/tiffsplit.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1992-1997 Sam Leffler +.\" Copyright (c) 1992-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFCP 1 "September 26, 1994" +.SH NAME +tiffsplit \- split a multi-image +.SM TIFF +into single-image +.SM TIFF +files +.SH SYNOPSIS +.B tiffsplit +.I src.tif +[ +.I prefix +] +.SH DESCRIPTION +.I tiffsplit +takes a multi-directory (page) +.SM TIFF +file and creates one or more single-directory (page) +.SM TIFF +files from it. +The output files are given names created by concatenating +a prefix, a lexically ordered +suffix in the range [\fIaa\fP-\fIzz\fP], the suffix +.I .tif +(e.g. +.IR xaa.tif , +.IR xab.tif , +\... +.IR xzz.tif ). +If a prefix is not specified on the command line, +the default prefix of +.I x +is used. +.SH OPTIONS +None. +.SH BUGS +Only a select set of ``known tags'' is copied when spliting. +.SH "SEE ALSO" +.IR tiffcp (1), +.IR tiffinfo (1), +.IR libtiff (3) diff --git a/man/tiffsv.1 b/man/tiffsv.1 new file mode 100644 index 00000000..ff44f7a5 --- /dev/null +++ b/man/tiffsv.1 @@ -0,0 +1,139 @@ +.\" $Header: /cvs/maptools/cvsroot/libtiff/man/Attic/tiffsv.1,v 1.1 1999-07-27 21:50:28 mike Exp $ +.\" +.\" Copyright (c) 1988-1997 Sam Leffler +.\" Copyright (c) 1991-1997 Silicon Graphics, Inc. +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and +.\" its documentation for any purpose is hereby granted without fee, provided +.\" that (i) the above copyright notices and this permission notice appear in +.\" all copies of the software and related documentation, and (ii) the names of +.\" Sam Leffler and Silicon Graphics may not be used in any advertising or +.\" publicity relating to the software without the specific, prior written +.\" permission of Sam Leffler and Silicon Graphics. +.\" +.\" THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +.\" WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +.\" +.\" IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +.\" ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +.\" OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +.\" WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +.\" LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.if n .po 0 +.TH TIFFSV 1 "October 15, 1995" +.SH NAME +tiffsv \- save an image from the framebuffer in a +.SM TIFF +file (Silicon Graphics version) +.SH SYNOPSIS +.B tiffsv +[ +.I options +] +.I output.tif +[ +.I "x1 x2 y1 y2" +] +.SH DESCRIPTION +.I tiffsv +saves all or part of the framebuffer in a file using the +Tag Image File Format, Revision 6.0. +By default, the image is saved with data samples packed (\c +.IR PlanarConfiguration =1), +compressed with the Lempel-Ziv & Welch algorithm (\c +.IR Compression =5), +and with each strip no more than 8 kilobytes. +These characteristics can be overriden, or explicitly specified +with the options described below. +.SH OPTIONS +.TP +.B \-b +Save the image as a greyscale image +as if it were processed by +.IR tiff2bw (1). +This option is included for compatibility with the standard +.IR scrsave (6D) +program. +.TP +.B \-c +Specify the compression to use for data written to the output file: +.B none +for no compression, +.B packbits +for PackBits compression, +.B jpeg +for baseline JPEG compression, +.B zip +for Deflate compression, +and +.B lzw +for Lempel-Ziv & Welch compression (default). +.IP +.SM LZW +compression can be specified together with a +.I predictor +value. +A predictor value of 2 causes +each scanline of the output image to undergo horizontal +differencing before it is encoded; a value +of 1 forces each scanline to be encoded without differencing. +LZW-specific options are specified by appending a ``:''-separated +list to the ``lzw'' option; e.g. +.B "\-c lzw:2" +for +.SM LZW +compression with horizontal differencing. +.TP +.B \-p +Specify the planar configuration to use in writing image data. +By default, +.I tiffsv +will create a new file with the data samples packed contiguously. +Specifying +.B "\-p contig" +will force data to be written with multi-sample data packed +together, while +.B "\-p separate" +will force samples to be written in separate planes. +.TP +.B \-r +Specify the number of rows (scanlines) in each strip of data +written to the output file. +By default, +.I tiffsv +attempts to set the rows/strip +that no more than 8 kilobytes of data appear in a strip. +.SH NOTE +Except for the use of +.SM TIFF, +this program is equivalent to the standard +.I scrsave +program. +This means, for example, that you can use it in conjunction with +the standard +.IR icut +program simply by creating a link called +.IR scrsave , +or by creating a shell script called +.I scrsave +that invokes +.I tiffgt +with the appropriate options. +.SH BUGS +If data are saved compressed and in separate planes, then the +rows in each strip is silently set to one to avoid limitations +in the +.IR libtiff (3) +library. +.SH "SEE ALSO" +.IR scrsave (6D) +.IR pal2rgb (1), +.IR tiffdump (1), +.IR tiffgt (1), +.IR tiffinfo (1), +.IR tiffcp (1), +.IR tiffmedian (1), +.IR libtiff (3) diff --git a/port/Makefile.in b/port/Makefile.in new file mode 100644 index 00000000..3df5c53f --- /dev/null +++ b/port/Makefile.in @@ -0,0 +1,67 @@ +#! smake +# $Header: /cvs/maptools/cvsroot/libtiff/port/Makefile.in,v 1.1 1999-07-27 21:50:28 mike Exp $ +# +# @WARNING@ +# +# Tag Image File Format Library +# +# Copyright (c) 1995-1997 Sam Leffler +# Copyright (c) 1995-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +SRCDIR = @RELSRCDIR@/port +VPATH = @RELSRCDIR@/port + +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# CCOMPILER: @CCOMPILER@ +# + +SHELL = @SCRIPT_SH@ +NULL = +CC = @CCOMPILER@ +AR = @AR@ +AROPTS = @AROPTS@ +RANLIB = @RANLIB@ + +IPATH = -I. -I${SRCDIR} +COPTS = @GCOPTS@ +OPTIMIZER=-O +CFLAGS = @ENVOPTS@ ${COPTS} ${OPTIMIZER} ${IPATH} + +CFILES = @PORTFUNCS@ +OBJECTS = ${CFILES:.c=.o} +TARGETS = libport.a + +default all: ${TARGETS} + +libport.a: ${OBJECTS} + @rm -f $@; + ${AR} ${AROPTS} $@ ${OBJECTS} + ${RANLIB} $@ +${PORT}/libport.a: libport.a + +install: default + +clean: + rm -f ${TARGETS} ${OBJS} core a.out diff --git a/port/getopt.c b/port/getopt.c new file mode 100644 index 00000000..e25a74d6 --- /dev/null +++ b/port/getopt.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * get option letter from argument vector + */ +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt; /* character checked for validity */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define EMSG "" + +int +getopt(int nargc, char** nargv, char* ostr) +{ + static char *place = EMSG; /* option letter processing */ + register char *oli; /* option letter list index */ + char *p; + + if (!*place) { /* update scanning pointer */ + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return(EOF); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return(EOF); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means EOF. + */ + if (optopt == (int)'-') + return(EOF); + if (!*place) + ++optind; + if (opterr) { + if (!(p = strrchr(*nargv, '/'))) + p = *nargv; + else + ++p; + (void)fprintf(stderr, "%s: illegal option -- %c\n", + p, optopt); + } + return(BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (!(p = strrchr(*nargv, '/'))) + p = *nargv; + else + ++p; + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + p, optopt); + return(BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return(optopt); /* dump back option letter */ +} diff --git a/port/install.sh b/port/install.sh new file mode 100644 index 00000000..db875e5d --- /dev/null +++ b/port/install.sh @@ -0,0 +1,246 @@ +#! /bin/sh +# $Header: /cvs/maptools/cvsroot/libtiff/port/Attic/install.sh,v 1.1 1999-07-27 21:50:28 mike Exp $ +# +# Warning, this file was automatically created by the TIFF configure script +# +# HylaFAX Facsimile Software +# +# Copyright (c) 1990-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# HylaFAX is a trademark of Silicon Graphics +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# +# Warning, this file was automatically created by the HylaFAX configure script +# +# VERSION: v3.4beta037 +# DATE: Wed Feb 3 19:53:27 EST 1999 +# TARGET: i586-unknown-linux +# + +# +# Shell script to emulate Silicon Graphics install program. +# We emulate the non-standard interface used by install so +# that we can build SGI inst packages on SGI systems. Note +# that we cannot emulate everything because we don't maintain +# a history of installed software; thus we cannot tell when +# configuration files have been modified and save old copies. +# +# NB: we don't do chown/chmod/chgrp by default; it must be +# explicitly set on the command line. +# + +# +# install [options] files ... +# +# Options are: +# +# -o save existing target foo as OLDfoo +# -O remove existing target foo, if it fails save as OLDfoo +# -m mode set mode of installed target +# -u uid set uid of installed target +# -g gid set gid of installed target +# -root path set ROOT directory for target pathnames +# -dir create directories +# -fifo create FIFO special files +# -ln path create hard link +# -lns path create symbolic link +# -src path source pathname different from target +# -f dir install files in the target directory ROOT/dir +# -F dir like -f, but create directories that do not exist +# -v echo actions +# -idb stuff specify package and, optionally, do special work +# +preopts= +postopts= +SaveFirst=no +HasSource=yes +RemoveFirst=no +NoUpdate=no +Suggested=no +Updated=no + +CMD=cp +SRC= +FILES= +DESTDIR= +CHMOD=":" +CHOWN=":" +CHGRP=":" +RM="rm -f" +MV="mv -f" +ECHO=echo +VERBOSE=":" +STRIP="/usr/bin/strip" +CMP=cmp + +TARGETS= +while [ x"$1" != x ] +do + arg=$1 + case $arg in + -m) shift; CHMOD="/bin/chmod $1";; + -u) shift; CHOWN="@CHOWN@ $1";; + -g) shift; CHGRP="@CHGRP@ $1";; + -o) SaveFirst=yes;; + -O) RemoveFirst=yes; SaveFirst=yes;; + -root) shift; ROOT=$1;; + -dir) CMD=mkdir; HasSource=no; + RM=":"; STRIP=":" + ;; + -fifo) CMD=@MKFIFO@; HasSource=no; + x=`echo $CMD | /bin/sed 's;.*/;;'`; + test $x = mknod && postopts="p"; + STRIP=":" + ;; + -ln) shift; CMD=/bin/ln; SRC="$1" + STRIP=":" + ;; + -lns) shift; CMD=/bin/ln; preopts="-s"; SRC="$1" + STRIP=":" + ;; + -src) shift; SRC="$1";; + -[fF]) shift; DESTDIR="$1";; + -idb) shift; opt="$1" + case "$opt" in + *config\(update\)*) Updated=yes;; + *config\(suggest\)*) Suggested=yes;; + *config\(noupdate\)*) NoUpdate=yes;; + *nostrip*) STRIP=":";; + esac + ;; + # these are skipped/not handled + -new|-rawidb|-blk|-chr) shift;; + -v) VERBOSE=$ECHO;; + -*) ;; + *) TARGETS="$TARGETS $arg";; + esac + shift +done + +# +# Install the specified target. +# +install() +{ + src=$1 target=$2 + if [ $RemoveFirst = yes -a -f $target ]; then + $VERBOSE "$RM $target" + $RM $target + fi + if [ $SaveFirst = yes -a -f $target ]; then + bf=`echo $src | /bin/sed 's;.*/;;'` + $VERBOSE "$MV $target $ROOT/$DESTDIR/OLD$bf" + $MV $target $ROOT/$DESTDIR/OLD$bf + fi + if [ -z "$SRC" -a $HasSource = yes ]; then + $VERBOSE "$CMD $preopts $src $target $postopts" + $CMD $preopts $f $target $postopts + else + $VERBOSE "$CMD $preopts $SRC $target $postopts" + $CMD $preopts $SRC $target $postopts + fi + if [ $? -eq 0 ]; then + $VERBOSE "$CHOWN $target" + $CHOWN $target + $VERBOSE "$CHGRP $target" + $CHGRP $target + $VERBOSE "$CHMOD $target" + $CHMOD $target + if [ $STRIP != ":" -a -x $ROOT/$DESTDIR/$f ]; then + $STRIP $target >/dev/null 2>&1 || true + $VERBOSE "$STRIP $target" + fi + fi +} + +if [ $Suggested = yes ]; then + # + # A suggested file. If an existing target does + # not exist, then install it. Otherwise, install + # it as target.N if it's different from the current + # installed target. + # + # NB: cannot be used with a special file 'cuz we + # use test -f to see if the file exists. + # + for f in $TARGETS; do + t=$ROOT/$DESTDIR/$f + if [ -f $t ]; then + if [ -z "$SRC" -a $HasSource = yes ]; then + $CMP -s $f $t || { + $ECHO "*** Warning, target has local changes, installing $f as $t.N" + install $f $t.N; + } + else + $CMP -s $SRC $t || { + $ECHO "*** Warning, target has local changes, installing $f as $t.N" + install $f $t.N + } + fi + else + install $f $t + fi + done +elif [ $Updated = yes ]; then + # + # A file to be updated. If an existing target does + # not exist, then install it. Otherwise, install + # it as target and save the old version as target.O + # if the old version is different from the current + # installed target. + # + # NB: cannot be used with a special file 'cuz we + # use test -f to see if the file exists. + # + for f in $TARGETS; do + t=$ROOT/$DESTDIR/$f + if [ -f $t ]; then + if [ -z "$SRC" -a $HasSource = yes ]; then + $CMP -s $f $t || $MV $t $t.O + else + $CMP -s $SRC $t || $MV $t $t.O + fi + fi + install $f $t + done +elif [ $NoUpdate = yes ]; then + # + # A file that is never to be updated; the target + # is created only if it does not exist. + # + # NB: cannot be used with a special file 'cuz we + # use test -f to see if the file exists. + # + for f in $TARGETS; do + t=$ROOT/$DESTDIR/$f + test -f $t || install $f $t + done +else + # + # Normal case, a target that should be installed + # with the existing copy, optionally, saved first. + # + for f in $TARGETS; do + install $f $ROOT/$DESTDIR/$f + done +fi diff --git a/port/install.sh.in b/port/install.sh.in new file mode 100644 index 00000000..055a8c0b --- /dev/null +++ b/port/install.sh.in @@ -0,0 +1,246 @@ +#! @SCRIPT_SH@ +# $Header: /cvs/maptools/cvsroot/libtiff/port/Attic/install.sh.in,v 1.1 1999-07-27 21:50:28 mike Exp $ +# +# @WARNING@ +# +# HylaFAX Facsimile Software +# +# Copyright (c) 1990-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# HylaFAX is a trademark of Silicon Graphics +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Sam Leffler and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +# +# Warning, this file was automatically created by the HylaFAX configure script +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# + +# +# Shell script to emulate Silicon Graphics install program. +# We emulate the non-standard interface used by install so +# that we can build SGI inst packages on SGI systems. Note +# that we cannot emulate everything because we don't maintain +# a history of installed software; thus we cannot tell when +# configuration files have been modified and save old copies. +# +# NB: we don't do chown/chmod/chgrp by default; it must be +# explicitly set on the command line. +# + +# +# install [options] files ... +# +# Options are: +# +# -o save existing target foo as OLDfoo +# -O remove existing target foo, if it fails save as OLDfoo +# -m mode set mode of installed target +# -u uid set uid of installed target +# -g gid set gid of installed target +# -root path set ROOT directory for target pathnames +# -dir create directories +# -fifo create FIFO special files +# -ln path create hard link +# -lns path create symbolic link +# -src path source pathname different from target +# -f dir install files in the target directory ROOT/dir +# -F dir like -f, but create directories that do not exist +# -v echo actions +# -idb stuff specify package and, optionally, do special work +# +preopts= +postopts= +SaveFirst=no +HasSource=yes +RemoveFirst=no +NoUpdate=no +Suggested=no +Updated=no + +CMD=cp +SRC= +FILES= +DESTDIR= +CHMOD=":" +CHOWN=":" +CHGRP=":" +RM="rm -f" +MV="mv @MV_F@" +ECHO=echo +VERBOSE=":" +STRIP="@STRIP@" +CMP=cmp + +TARGETS= +while [ x"$1" != x ] +do + arg=$1 + case $arg in + -m) shift; CHMOD="@CHMOD@ $1";; + -u) shift; CHOWN="@CHOWN@ $1";; + -g) shift; CHGRP="@CHGRP@ $1";; + -o) SaveFirst=yes;; + -O) RemoveFirst=yes; SaveFirst=yes;; + -root) shift; ROOT=$1;; + -dir) CMD=mkdir; HasSource=no; + RM=":"; STRIP=":" + ;; + -fifo) CMD=@MKFIFO@; HasSource=no; + x=`echo $CMD | @SED@ 's;.*/;;'`; + test $x = mknod && postopts="p"; + STRIP=":" + ;; + -ln) shift; CMD=@LN@; SRC="$1" + STRIP=":" + ;; + -lns) shift; CMD=@LN@; preopts="@LN_S@"; SRC="$1" + STRIP=":" + ;; + -src) shift; SRC="$1";; + -[fF]) shift; DESTDIR="$1";; + -idb) shift; opt="$1" + case "$opt" in + *config\(update\)*) Updated=yes;; + *config\(suggest\)*) Suggested=yes;; + *config\(noupdate\)*) NoUpdate=yes;; + *nostrip*) STRIP=":";; + esac + ;; + # these are skipped/not handled + -new|-rawidb|-blk|-chr) shift;; + -v) VERBOSE=$ECHO;; + -*) ;; + *) TARGETS="$TARGETS $arg";; + esac + shift +done + +# +# Install the specified target. +# +install() +{ + src=$1 target=$2 + if [ $RemoveFirst = yes -a -f $target ]; then + $VERBOSE "$RM $target" + $RM $target + fi + if [ $SaveFirst = yes -a -f $target ]; then + bf=`echo $src | @SED@ 's;.*/;;'` + $VERBOSE "$MV $target $ROOT/$DESTDIR/OLD$bf" + $MV $target $ROOT/$DESTDIR/OLD$bf + fi + if [ -z "$SRC" -a $HasSource = yes ]; then + $VERBOSE "$CMD $preopts $src $target $postopts" + $CMD $preopts $f $target $postopts + else + $VERBOSE "$CMD $preopts $SRC $target $postopts" + $CMD $preopts $SRC $target $postopts + fi + if [ $? -eq 0 ]; then + $VERBOSE "$CHOWN $target" + $CHOWN $target + $VERBOSE "$CHGRP $target" + $CHGRP $target + $VERBOSE "$CHMOD $target" + $CHMOD $target + if [ $STRIP != ":" -a -x $ROOT/$DESTDIR/$f ]; then + $STRIP $target >/dev/null 2>&1 || true + $VERBOSE "$STRIP $target" + fi + fi +} + +if [ $Suggested = yes ]; then + # + # A suggested file. If an existing target does + # not exist, then install it. Otherwise, install + # it as target.N if it's different from the current + # installed target. + # + # NB: cannot be used with a special file 'cuz we + # use test -f to see if the file exists. + # + for f in $TARGETS; do + t=$ROOT/$DESTDIR/$f + if [ -f $t ]; then + if [ -z "$SRC" -a $HasSource = yes ]; then + $CMP -s $f $t || { + $ECHO "*** Warning, target has local changes, installing $f as $t.N" + install $f $t.N; + } + else + $CMP -s $SRC $t || { + $ECHO "*** Warning, target has local changes, installing $f as $t.N" + install $f $t.N + } + fi + else + install $f $t + fi + done +elif [ $Updated = yes ]; then + # + # A file to be updated. If an existing target does + # not exist, then install it. Otherwise, install + # it as target and save the old version as target.O + # if the old version is different from the current + # installed target. + # + # NB: cannot be used with a special file 'cuz we + # use test -f to see if the file exists. + # + for f in $TARGETS; do + t=$ROOT/$DESTDIR/$f + if [ -f $t ]; then + if [ -z "$SRC" -a $HasSource = yes ]; then + $CMP -s $f $t || $MV $t $t.O + else + $CMP -s $SRC $t || $MV $t $t.O + fi + fi + install $f $t + done +elif [ $NoUpdate = yes ]; then + # + # A file that is never to be updated; the target + # is created only if it does not exist. + # + # NB: cannot be used with a special file 'cuz we + # use test -f to see if the file exists. + # + for f in $TARGETS; do + t=$ROOT/$DESTDIR/$f + test -f $t || install $f $t + done +else + # + # Normal case, a target that should be installed + # with the existing copy, optionally, saved first. + # + for f in $TARGETS; do + install $f $ROOT/$DESTDIR/$f + done +fi diff --git a/port/irix/so_locations b/port/irix/so_locations new file mode 100644 index 00000000..9226d4fc --- /dev/null +++ b/port/irix/so_locations @@ -0,0 +1,4 @@ +libtiff.so \ + :st = .text 0x5ff70000, 0x00030000:\ + :st = .data 0x5ffd0000, 0x00030000:\ + diff --git a/port/strcasecmp.c b/port/strcasecmp.c new file mode 100644 index 00000000..96784029 --- /dev/null +++ b/port/strcasecmp.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#include +#include + +#if defined(LIBC_SCCS) && !defined(lint) +static const char sccsid[] = "@(#)strcasecmp.c 5.9 (Berkeley) 6/1/90"; +#endif /* LIBC_SCCS and not lint */ + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static const unsigned char charmap[] = { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', + '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', + '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', + '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', + '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', + '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', + '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', + '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', + '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', + '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', + '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', + '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', + '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', + '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', + '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', + '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', +}; + +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + register const unsigned char *cm = charmap, + *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return (0); + return (cm[*us1] - cm[*--us2]); +} + +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + register size_t n; +{ + if (n != 0) { + register const unsigned char *cm = charmap, + *us1 = (const unsigned char *)s1, + *us2 = (const unsigned char *)s2; + + do { + if (cm[*us1] != cm[*us2++]) + return (cm[*us1] - cm[*--us2]); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} diff --git a/port/strtoul.c b/port/strtoul.c new file mode 100644 index 00000000..ed8c1080 --- /dev/null +++ b/port/strtoul.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strtoul.c 5.3 (Berkeley) 2/23/91"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +/* + * Convert a string to an unsigned long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +unsigned long +strtoul(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; + cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = any ? s - 1 : (char *)nptr; + return (acc); +} diff --git a/tiff.h b/tiff.h new file mode 100644 index 00000000..55440996 --- /dev/null +++ b/tiff.h @@ -0,0 +1,421 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/Attic/tiff.h,v 1.1 1999-07-27 21:50:26 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFF_ +#define _TIFF_ +/* + * Tag Image File Format (TIFF) + * + * Based on Rev 6.0 from: + * Developer's Desk + * Aldus Corporation + * 411 First Ave. South + * Suite 200 + * Seattle, WA 98104 + * 206-622-5500 + */ +#define TIFF_VERSION 42 + +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 + +#ifndef _TIFF_DATA_TYPEDEFS_ +#define _TIFF_DATA_TYPEDEFS_ +/* + * Intrinsic data types required by the file format: + * + * 8-bit quantities int8/uint8 + * 16-bit quantities int16/uint16 + * 32-bit quantities int32/uint32 + * strings unsigned char* + */ +#ifdef __STDC__ +typedef signed char int8; /* NB: non-ANSI compilers may not grok */ +#else +typedef char int8; +#endif +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; /* sizeof (uint16) must == 2 */ +#if defined(__alpha) || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) +typedef int int32; +typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ +#else +typedef long int32; +typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ +#endif +#endif /* _TIFF_DATA_TYPEDEFS_ */ + +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint32 tiff_diroff; /* byte offset to first directory */ +} TIFFHeader; + +/* + * TIFF Image File Directories are comprised of + * a table of field descriptors of the form shown + * below. The table is sorted in ascending order + * by tag. The values associated with each entry + * are disjoint and may appear anywhere in the file + * (so long as they are placed on a word boundary). + * + * If the value is 4 bytes or less, then it is placed + * in the offset field to save space. If the value + * is less than 4 bytes, it is left-justified in the + * offset field. + */ +typedef struct { + uint16 tdir_tag; /* see below */ + uint16 tdir_type; /* data type; see below */ + uint32 tdir_count; /* number of items; length in spec */ + uint32 tdir_offset; /* byte offset to field data */ +} TIFFDirEntry; + +/* + * NB: In the comments below, + * - items marked with a + are obsoleted by revision 5.0, + * - items marked with a ! are introduced in revision 6.0. + * - items marked with a % are introduced post revision 6.0. + * - items marked with a $ are obsoleted by revision 6.0. + */ + +/* + * Tag data type information. + * + * Note: RATIONALs are the ratio of two 32-bit integer values. + */ +typedef enum { + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12 /* !64-bit IEEE floating point */ +} TIFFDataType; + +/* + * TIFF Tag Definitions. + */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !rows/data tile */ +#define TIFFTAG_TILELENGTH 323 /* !cols/data tile */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +/* + * Tags 512-521 are obsoleted by Technical Note #2 + * which specifies a revised JPEG-in-TIFF scheme. + */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +/* tags 32952-32956 are private tags registered to Island Graphics */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +/* tags 32995-32999 are private tags registered to SGI */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +/* tags 33300-33309 are private tags registered to Pixar */ +/* + * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH + * are set when an image has been cropped out of a larger image. + * They reflect the size of the original uncropped image. + * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used + * to determine the position of the smaller image in the larger one. + */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ +/* tag 33405 is a private tag registered to Eastman Kodak */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +/* IPTC TAG from RichTIFF specifications */ +#define TIFFTAG_RICHTIFFIPTC 33723 +/* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +/* tag 34929 is a private tag registered to FedEx */ +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +/* tag 65535 is an undefined tag used by Eastman Kodak */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ + +/* + * The following are ``pseudo tags'' that can be + * used to control codec-specific functionality. + * These tags are not written to file. Note that + * these values start at 0xffff+1 so that they'll + * never collide with Aldus-assigned tags. + * + * If you want your private pseudo tags ``registered'' + * (i.e. added to this file), send mail to sam@sgi.com + * with the appropriate C definitions to add. + */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +/* 65550-65556 are allocated to Oceana Matrix */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +/* 65559 is allocated to Oceana Matrix */ +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#endif /* _TIFF_ */ diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 00000000..c909b095 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,251 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/Makefile,v 1.1 1999-07-27 21:50:28 mike Exp $ +# +# Warning, this file was automatically created by the TIFF configure script +# +# TIFF Library Tools +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +DEPTH = .. + +SRCDIR = ../tools +LIBDIR = ../libtiff + +# +# VERSION: v3.4beta037 +# DATE: Wed Feb 3 19:53:27 EST 1999 +# TARGET: i586-unknown-linux +# CCOMPILER: /usr/bin/gcc +# +SHELL = /bin/sh +NULL = +CC = /usr/bin/gcc +INSTALL = ${SHELL} ../port/install.sh +# +COPTS = -g +OPTIMIZER=-O +IPATH = -I. -I${SRCDIR} -I${LIBDIR} +CFLAGS = ${COPTS} ${OPTIMIZER} ${IPATH} +# +TIFFLIB = ${DEPTH}/libtiff/libtiff.a +LIBJPEG = +LIBGZ = +LIBTIFF = ${DEPTH}/libtiff/libtiff.a +LIBPORT = +MACHLIBS= -lm +LIBS = ${LIBTIFF} ${LIBJPEG} ${LIBGZ} ${LIBPORT} ${MACHLIBS} +# +OBJS= \ + fax2tiff.o \ + fax2ps.o \ + gif2tiff.o \ + pal2rgb.o \ + ppm2tiff.o \ + rgb2ycbcr.o \ + ras2tiff.o \ + thumbnail.o \ + tiff2bw.o \ + tiff2ps.o \ + tiffcmp.o \ + tiffcp.o \ + tiffdither.o \ + tiffdump.o \ + tiffinfo.o \ + tiffmedian.o \ + tiffsplit.o \ + ${NULL} +TARGETS =\ + fax2tiff \ + fax2ps \ + gif2tiff \ + pal2rgb \ + ppm2tiff \ + rgb2ycbcr \ + thumbnail \ + ras2tiff \ + tiff2bw \ + tiff2ps \ + tiffcmp \ + tiffcp \ + tiffdither \ + tiffdump \ + tiffinfo \ + tiffmedian \ + tiffsplit \ + ${NULL} + +all: ${TARGETS} + @if [ "no" = yes ]; then \ + ${MAKE} sgi2tiff; \ + else \ + true; \ + fi + @if [ "no" = yes ]; then \ + ${MAKE} tiffgt tiffsv; \ + else \ + true; \ + fi +install: all + ${INSTALL} -idb tiff.sw.tools -m 755 -dir /usr/local/bin + ${INSTALL} -idb tiff.sw.tools -m 755 -F /usr/local/bin -O ${TARGETS} + @if [ "no" = yes ]; then \ + ${INSTALL} -idb tiff.sw.tools -m 755 -F /usr/local/bin -O sgi2tiff; \ + else \ + true; \ + fi + @if [ "no" = yes ]; then \ + ${INSTALL} -idb tiff.sw.tools -m 755 -F /usr/local/bin -O tiffgt tiffsv;\ + else \ + true; \ + fi +clean: + rm -f ${TARGETS} ${OBJS} sgigt.o tiffgt sgisv.o tiffsv \ + sgi2tiff.o sgi2tiff core a.out ycbcr + +# +# System-independent tools +# + +tiffinfo: tiffinfo.o ${TIFFLIB} + ${CC} -o tiffinfo ${CFLAGS} tiffinfo.o ${LIBS} +tiffinfo.o: ${SRCDIR}/tiffinfo.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffinfo.c + +tiffcmp:tiffcmp.o ${TIFFLIB} + ${CC} -o tiffcmp ${CFLAGS} tiffcmp.o ${LIBS} +tiffcmp.o: ${SRCDIR}/tiffcmp.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffcmp.c + +tiffcp: tiffcp.o ${TIFFLIB} + ${CC} -o tiffcp ${CFLAGS} tiffcp.o ${LIBS} +tiffcp.o: ${SRCDIR}/tiffcp.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffcp.c + +tiffdump: tiffdump.o + ${CC} -o tiffdump ${CFLAGS} tiffdump.o ${LIBS} +tiffdump.o: ${SRCDIR}/tiffdump.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffdump.c + +tiffmedian: tiffmedian.o ${TIFFLIB} + ${CC} -o tiffmedian ${CFLAGS} tiffmedian.o ${LIBS} +tiffmedian.o: ${SRCDIR}/tiffmedian.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffmedian.c + +tiffsplit: tiffsplit.o ${TIFFLIB} + ${CC} -o tiffsplit ${CFLAGS} tiffsplit.o ${LIBS} +tiffsplit.o: ${SRCDIR}/tiffsplit.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffsplit.c + +tiff2ps: tiff2ps.o ${TIFFLIB} + ${CC} -o tiff2ps ${CFLAGS} tiff2ps.o ${LIBS} +tiff2ps.o: ${SRCDIR}/tiff2ps.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiff2ps.c + +# +# Junky stuff... programs that are more examples of how +# to use the library than full-blown useful tools. +# + +# convert RGB image to B&W +tiff2bw: tiff2bw.o ${TIFFLIB} + ${CC} -o tiff2bw ${CFLAGS} tiff2bw.o ${LIBS} +tiff2bw.o: ${SRCDIR}/tiff2bw.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiff2bw.c + +# convert B&W image to bilevel w/ FS dithering +tiffdither: tiffdither.o ${TIFFLIB} + ${CC} -o tiffdither ${CFLAGS} tiffdither.o ${LIBS} +tiffdither.o: ${SRCDIR}/tiffdither.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffdither.c + +# simple Sun rasterfile converter +ras2tiff: ras2tiff.o ${TIFFLIB} + ${CC} -o ras2tiff ${CFLAGS} ras2tiff.o ${LIBS} +ras2tiff.o: ${SRCDIR}/ras2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/ras2tiff.c + +# simple GIF converter +gif2tiff: gif2tiff.o ${TIFFLIB} + ${CC} -o gif2tiff ${CFLAGS} gif2tiff.o ${LIBS} +gif2tiff.o: ${SRCDIR}/gif2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/gif2tiff.c + +# very limited PBM converter +ppm2tiff: ppm2tiff.o ${TIFFLIB} + ${CC} -o ppm2tiff ${CFLAGS} ppm2tiff.o ${LIBS} +ppm2tiff.o: ${SRCDIR}/ppm2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/ppm2tiff.c + +# Group 3/4 FAX file converter +fax2tiff: fax2tiff.o ${TIFFLIB} + ${CC} -o fax2tiff ${CFLAGS} fax2tiff.o ${LIBS} +fax2tiff.o: ${SRCDIR}/fax2tiff.c + ${CC} -c -I${LIBDIR} -I${DEPTH}/libtiff ${CFLAGS} ${SRCDIR}/fax2tiff.c + +# Group 3/4 FAX to encoded PS converter +fax2ps: fax2ps.o ${TIFFLIB} + ${CC} -o fax2ps ${CFLAGS} fax2ps.o ${LIBS} +fax2ps.o: ${SRCDIR}/fax2ps.c + ${CC} -c ${CFLAGS} ${SRCDIR}/fax2ps.c + +# convert Palette image to RGB +pal2rgb: pal2rgb.o ${TIFFLIB} + ${CC} -o pal2rgb ${CFLAGS} pal2rgb.o ${LIBS} +pal2rgb.o: ${SRCDIR}/pal2rgb.c + ${CC} -c ${CFLAGS} ${SRCDIR}/pal2rgb.c + +# convert RGB image to YCbCr +rgb2ycbcr: rgb2ycbcr.o ${TIFFLIB} + ${CC} -o rgb2ycbcr ${CFLAGS} rgb2ycbcr.o ${LIBS} +rgb2ycbcr.o: ${SRCDIR}/rgb2ycbcr.c + ${CC} -c ${CFLAGS} ${SRCDIR}/rgb2ycbcr.c + +# generate thumbnail images from fax (example of SubIFD usage) +thumbnail: thumbnail.o ${TIFFLIB} + ${CC} -o thumbnail ${CFLAGS} thumbnail.o ${LIBS} +thumbnail.o: ${SRCDIR}/thumbnail.c + ${CC} -c ${CFLAGS} ${SRCDIR}/thumbnail.c + +# +# System-specific tools. +# + +# +# sgi2tiff converts SGI RGB images to TIFF; it requires +# the SGI image library -limage. +# +sgi2tiff: sgi2tiff.o ${TIFFLIB} + ${CC} -o sgi2tiff ${CFLAGS} sgi2tiff.o -limage ${LIBS} +sgi2tiff.o: ${SRCDIR}/sgi2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgi2tiff.c + +# SGI versions of tiffgt & tiffsv that require -lgl +tiffgt: sgigt.o ${TIFFLIB} + ${CC} -o tiffgt ${CFLAGS} sgigt.o -lgutil -lgl ${LIBS} +sgigt.o: ${SRCDIR}/sgigt.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgigt.c + +tiffsv: sgisv.o ${TIFFLIB} + ${CC} -o tiffsv ${CFLAGS} sgisv.o -lgutil -lgl ${LIBS} +sgisv.o: ${SRCDIR}/sgisv.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgisv.c diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 00000000..dcf3865a --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,251 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/tools/Makefile.in,v 1.1 1999-07-27 21:50:28 mike Exp $ +# +# @WARNING@ +# +# TIFF Library Tools +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +DEPTH = .. + +SRCDIR = @RELSRCDIR@/tools +LIBDIR = @RELSRCDIR@/libtiff + +# +# VERSION: @VERSION@ +# DATE: @DATE@ +# TARGET: @TARGET@ +# CCOMPILER: @CCOMPILER@ +# +SHELL = @SCRIPT_SH@ +NULL = +CC = @CCOMPILER@ +INSTALL = @INSTALL@ +# +COPTS = @GCOPTS@ +OPTIMIZER=-O +IPATH = -I. -I${SRCDIR} -I${LIBDIR} +CFLAGS = @ENVOPTS@ ${COPTS} ${OPTIMIZER} ${IPATH} +# +TIFFLIB = ${DEPTH}/libtiff/libtiff.@DSOSUF@ +LIBJPEG = @LIBJPEG@ +LIBGZ = @LIBGZ@ +LIBTIFF = @TIFFLIBREF@ +LIBPORT = @LIBPORT@ +MACHLIBS= @MACHDEPLIBS@ +LIBS = ${LIBTIFF} ${LIBJPEG} ${LIBGZ} ${LIBPORT} ${MACHLIBS} +# +OBJS= \ + fax2tiff.o \ + fax2ps.o \ + gif2tiff.o \ + pal2rgb.o \ + ppm2tiff.o \ + rgb2ycbcr.o \ + ras2tiff.o \ + thumbnail.o \ + tiff2bw.o \ + tiff2ps.o \ + tiffcmp.o \ + tiffcp.o \ + tiffdither.o \ + tiffdump.o \ + tiffinfo.o \ + tiffmedian.o \ + tiffsplit.o \ + ${NULL} +TARGETS =\ + fax2tiff \ + fax2ps \ + gif2tiff \ + pal2rgb \ + ppm2tiff \ + rgb2ycbcr \ + thumbnail \ + ras2tiff \ + tiff2bw \ + tiff2ps \ + tiffcmp \ + tiffcp \ + tiffdither \ + tiffdump \ + tiffinfo \ + tiffmedian \ + tiffsplit \ + ${NULL} + +all: ${TARGETS} + @if [ "@LIBIMAGE@" = yes ]; then \ + ${MAKE} sgi2tiff; \ + else \ + true; \ + fi + @if [ "@LIBGL@" = yes ]; then \ + ${MAKE} tiffgt tiffsv; \ + else \ + true; \ + fi +install: all + ${INSTALL} -idb tiff.sw.tools -m 755 -dir @DIR_BIN@ + ${INSTALL} -idb tiff.sw.tools -m 755 -F @DIR_BIN@ -O ${TARGETS} + @if [ "@LIBIMAGE@" = yes ]; then \ + ${INSTALL} -idb tiff.sw.tools -m 755 -F @DIR_BIN@ -O sgi2tiff; \ + else \ + true; \ + fi + @if [ "@LIBGL@" = yes ]; then \ + ${INSTALL} -idb tiff.sw.tools -m 755 -F @DIR_BIN@ -O tiffgt tiffsv;\ + else \ + true; \ + fi +clean: + rm -f ${TARGETS} ${OBJS} sgigt.o tiffgt sgisv.o tiffsv \ + sgi2tiff.o sgi2tiff core a.out ycbcr + +# +# System-independent tools +# + +tiffinfo: tiffinfo.o ${TIFFLIB} + ${CC} -o tiffinfo ${CFLAGS} tiffinfo.o ${LIBS} +tiffinfo.o: ${SRCDIR}/tiffinfo.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffinfo.c + +tiffcmp:tiffcmp.o ${TIFFLIB} + ${CC} -o tiffcmp ${CFLAGS} tiffcmp.o ${LIBS} +tiffcmp.o: ${SRCDIR}/tiffcmp.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffcmp.c + +tiffcp: tiffcp.o ${TIFFLIB} + ${CC} -o tiffcp ${CFLAGS} tiffcp.o ${LIBS} +tiffcp.o: ${SRCDIR}/tiffcp.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffcp.c + +tiffdump: tiffdump.o + ${CC} -o tiffdump ${CFLAGS} tiffdump.o ${LIBS} +tiffdump.o: ${SRCDIR}/tiffdump.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffdump.c + +tiffmedian: tiffmedian.o ${TIFFLIB} + ${CC} -o tiffmedian ${CFLAGS} tiffmedian.o ${LIBS} +tiffmedian.o: ${SRCDIR}/tiffmedian.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffmedian.c + +tiffsplit: tiffsplit.o ${TIFFLIB} + ${CC} -o tiffsplit ${CFLAGS} tiffsplit.o ${LIBS} +tiffsplit.o: ${SRCDIR}/tiffsplit.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffsplit.c + +tiff2ps: tiff2ps.o ${TIFFLIB} + ${CC} -o tiff2ps ${CFLAGS} tiff2ps.o ${LIBS} +tiff2ps.o: ${SRCDIR}/tiff2ps.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiff2ps.c + +# +# Junky stuff... programs that are more examples of how +# to use the library than full-blown useful tools. +# + +# convert RGB image to B&W +tiff2bw: tiff2bw.o ${TIFFLIB} + ${CC} -o tiff2bw ${CFLAGS} tiff2bw.o ${LIBS} +tiff2bw.o: ${SRCDIR}/tiff2bw.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiff2bw.c + +# convert B&W image to bilevel w/ FS dithering +tiffdither: tiffdither.o ${TIFFLIB} + ${CC} -o tiffdither ${CFLAGS} tiffdither.o ${LIBS} +tiffdither.o: ${SRCDIR}/tiffdither.c + ${CC} -c ${CFLAGS} ${SRCDIR}/tiffdither.c + +# simple Sun rasterfile converter +ras2tiff: ras2tiff.o ${TIFFLIB} + ${CC} -o ras2tiff ${CFLAGS} ras2tiff.o ${LIBS} +ras2tiff.o: ${SRCDIR}/ras2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/ras2tiff.c + +# simple GIF converter +gif2tiff: gif2tiff.o ${TIFFLIB} + ${CC} -o gif2tiff ${CFLAGS} gif2tiff.o ${LIBS} +gif2tiff.o: ${SRCDIR}/gif2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/gif2tiff.c + +# very limited PBM converter +ppm2tiff: ppm2tiff.o ${TIFFLIB} + ${CC} -o ppm2tiff ${CFLAGS} ppm2tiff.o ${LIBS} +ppm2tiff.o: ${SRCDIR}/ppm2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/ppm2tiff.c + +# Group 3/4 FAX file converter +fax2tiff: fax2tiff.o ${TIFFLIB} + ${CC} -o fax2tiff ${CFLAGS} fax2tiff.o ${LIBS} +fax2tiff.o: ${SRCDIR}/fax2tiff.c + ${CC} -c -I${LIBDIR} -I${DEPTH}/libtiff ${CFLAGS} ${SRCDIR}/fax2tiff.c + +# Group 3/4 FAX to encoded PS converter +fax2ps: fax2ps.o ${TIFFLIB} + ${CC} -o fax2ps ${CFLAGS} fax2ps.o ${LIBS} +fax2ps.o: ${SRCDIR}/fax2ps.c + ${CC} -c ${CFLAGS} ${SRCDIR}/fax2ps.c + +# convert Palette image to RGB +pal2rgb: pal2rgb.o ${TIFFLIB} + ${CC} -o pal2rgb ${CFLAGS} pal2rgb.o ${LIBS} +pal2rgb.o: ${SRCDIR}/pal2rgb.c + ${CC} -c ${CFLAGS} ${SRCDIR}/pal2rgb.c + +# convert RGB image to YCbCr +rgb2ycbcr: rgb2ycbcr.o ${TIFFLIB} + ${CC} -o rgb2ycbcr ${CFLAGS} rgb2ycbcr.o ${LIBS} +rgb2ycbcr.o: ${SRCDIR}/rgb2ycbcr.c + ${CC} -c ${CFLAGS} ${SRCDIR}/rgb2ycbcr.c + +# generate thumbnail images from fax (example of SubIFD usage) +thumbnail: thumbnail.o ${TIFFLIB} + ${CC} -o thumbnail ${CFLAGS} thumbnail.o ${LIBS} +thumbnail.o: ${SRCDIR}/thumbnail.c + ${CC} -c ${CFLAGS} ${SRCDIR}/thumbnail.c + +# +# System-specific tools. +# + +# +# sgi2tiff converts SGI RGB images to TIFF; it requires +# the SGI image library -limage. +# +sgi2tiff: sgi2tiff.o ${TIFFLIB} + ${CC} -o sgi2tiff ${CFLAGS} sgi2tiff.o -limage ${LIBS} +sgi2tiff.o: ${SRCDIR}/sgi2tiff.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgi2tiff.c + +# SGI versions of tiffgt & tiffsv that require -lgl +tiffgt: sgigt.o ${TIFFLIB} + ${CC} -o tiffgt ${CFLAGS} sgigt.o -lgutil -lgl ${LIBS} +sgigt.o: ${SRCDIR}/sgigt.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgigt.c + +tiffsv: sgisv.o ${TIFFLIB} + ${CC} -o tiffsv ${CFLAGS} sgisv.o -lgutil -lgl ${LIBS} +sgisv.o: ${SRCDIR}/sgisv.c + ${CC} -c ${CFLAGS} ${SRCDIR}/sgisv.c diff --git a/tools/Makefile.lcc b/tools/Makefile.lcc new file mode 100644 index 00000000..5238c33b --- /dev/null +++ b/tools/Makefile.lcc @@ -0,0 +1,132 @@ +# $Header: /cvs/maptools/cvsroot/libtiff/tools/Makefile.lcc,v 1.1 1999-07-27 21:50:28 mike Exp $ +# +# TIFF Library Tools +# +# Copyright (c) 1988-1997 Sam Leffler +# Copyright (c) 1991-1997 Silicon Graphics, Inc. +# +# Permission to use, copy, modify, distribute, and sell this software and +# its documentation for any purpose is hereby granted without fee, provided +# that (i) the above copyright notices and this permission notice appear in +# all copies of the software and related documentation, and (ii) the names of +# Sam Leffler and Silicon Graphics may not be used in any advertising or +# publicity relating to the software without the specific, prior written +# permission of Stanford and Silicon Graphics. +# +# THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +# EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +# WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +# +# IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR +# ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF +# LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +NULL= +IPATH= -I..\libtiff +# +# If you don't want the public domain getopt code, then +# simply null this out and you'll get whatever is in your +# libc (or similar). +# +GETOPT= getopt.o +# +# Library-wide configuration defines: +# Note that if you change the library-wide configuration, you'll +# need to manual force a full rebuild. +# +CONF_LIBRARY=\ + ${NULL} +COPTS= -Oloop -cwagshf -d1 -b0 -v -DNDEBUG -rr -j135i +CFLAGS= ${COPTS} ${IPATH} -DBINMODE='"b"' +# +LIBTIFF=..\libtiff\tiffrnb.lib +LIBS= -l${LIBTIFF} -lm +MACHALL=ras2tiff.ttp +OBJS=\ + fax2tiff.o \ + gif2tiff.o \ + pal2rgb.o \ + ppm2tiff.o \ + rgb2ycbcr.o \ + tiff2bw.o \ + tiff2ps.o \ + tiffcmp.o \ + tiffcp.o \ + tiffdither.o \ + tiffdump.o \ + tiffinfo.o \ + tiffmedian.o \ + tiffsplit.o \ + ras2tiff.o \ + ${GETOPT} \ + ${NULL} +ALL=\ + fax2tiff.ttp \ + gif2tiff.ttp \ + pal2rgb.ttp \ + ppm2tiff.ttp \ + rgb2ycbcr.ttp \ + tiff2bw.ttp \ + tiff2ps.ttp \ + tiffcmp.ttp \ + tiffcp.ttp \ + tiffdither.ttp \ + tiffdump.ttp \ + tiffinfo.ttp \ + tiffmedian.ttp \ + tiffsplit.ttp \ + ${MACHALL} \ + ${NULL} + +all: ${ALL} + +tiffinfo.ttp: tiffinfo.c ${GETOPT} ${LIBTIFF} + ${CC} -o tiffinfo.ttp ${CFLAGS} tiffinfo.c ${GETOPT} ${LIBS} +tiffcmp.ttp: tiffcmp.c ${GETOPT} ${LIBTIFF} + ${CC} -o tiffcmp.ttp ${CFLAGS} tiffcmp.c ${GETOPT} ${LIBS} +tiffcp.ttp: tiffcp.c ${LIBTIFF} + ${CC} -o tiffcp.ttp ${CFLAGS} tiffcp.c ${LIBS} +tiffdump.ttp: tiffdump.c + ${CC} -o tiffdump.ttp ${CFLAGS} tiffdump.c -lm ${LIBS} +tiffmedian.ttp: tiffmedian.c ${LIBTIFF} + ${CC} -o tiffmedian.ttp ${CFLAGS} tiffmedian.c ${LIBS} +tiffsplit.ttp: tiffsplit.c ${LIBTIFF} + ${CC} -o tiffsplit.ttp ${CFLAGS} tiffsplit.c ${LIBS} +tiff2ps.ttp: tiff2ps.c ${LIBTIFF} + ${CC} -o tiff2ps.ttp ${CFLAGS} tiff2ps.c ${LIBS} +# junky stuff... +# convert RGB image to B&W +tiff2bw.ttp: tiff2bw.c ${GETOPT} ${LIBTIFF} + ${CC} -o tiff2bw.ttp ${CFLAGS} tiff2bw.c ${GETOPT} ${LIBS} +# convert B&W image to bilevel w/ FS dithering +tiffdither.ttp: tiffdither.c ${LIBTIFF} + ${CC} -o tiffdither.ttp ${CFLAGS} tiffdither.c ${LIBS} +# Group 3 FAX file converter +fax2tiff.ttp: fax2tiff.c ${GETOPT} ${LIBTIFF} + ${CC} -o fax2tiff.ttp ${CFLAGS} ${CONF_LIBRARY} fax2tiff.c ${GETOPT} ${LIBS} +# convert Palette image to RGB +pal2rgb.ttp: pal2rgb.c ${LIBTIFF} + ${CC} -o pal2rgb.ttp ${CFLAGS} pal2rgb.c ${LIBS} +# convert RGB image to YCbCr +rgb2ycbcr.ttp: rgb2ycbcr.c ${GETOPT} ${LIBTIFF} + ${CC} -o rgb2ycbcr.ttp ${CFLAGS} rgb2ycbcr.c ${GETOPT} ${LIBS} +# GIF converter +gif2tiff.ttp: gif2tiff.c ${LIBTIFF} + ${CC} -o gif2tiff.ttp ${CFLAGS} gif2tiff.c ${LIBS} +# PBM converter +ppm2tiff.ttp: ppm2tiff.c ${LIBTIFF} + ${CC} -o ppm2tiff.ttp ${CFLAGS} ppm2tiff.c ${LIBS} +# Sun rasterfile converter +ras2tiff.ttp: ras2tiff.c ${LIBTIFF} + ${CC} -o ras2tiff.ttp ${CFLAGS} ras2tiff.c ${LIBS} +# generate thumbnail images from fax +thumbnail: thumbnail.c ${LIBTIFF} + ${CC} -o thumbnail ${CFLAGS} thumbnail.c ${LIBS} -lm + +install: all + +clean: + rm -f ${ALL} ${OBJS} ycbcr.ttp diff --git a/tools/fax2ps.c b/tools/fax2ps.c new file mode 100644 index 00000000..b52ceba8 --- /dev/null +++ b/tools/fax2ps.c @@ -0,0 +1,433 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/fax2ps.c,v 1.1 1999-07-27 21:50:28 mike Exp $" */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#ifndef VMS +#include +#else +#include +#endif + +#include "tiffio.h" + +float defxres = 204.; /* default x resolution (pixels/inch) */ +float defyres = 98.; /* default y resolution (lines/inch) */ +const float basePageWidth = 8.5; +const float basePageHeight = 11.0; +const float half = 0.5; +const float points = 72.0; +float pageWidth = 8.5; /* image page width (inches) */ +float pageHeight = 11.0; /* image page length (inches) */ +int scaleToPage = 0; /* if true, scale raster to page dimensions */ +int totalPages = 0; /* total # pages printed */ +int row; /* current output row */ +int maxline = 512; /* max output line of PostScript */ + +/* + * Turn a bit-mapped scanline into the appropriate sequence + * of PostScript characters to be rendered. + * + * Original version written by Bret D. Whissel, + * Florida State University Meteorology Department + * March 13-15, 1995. + */ +static void +printruns(unsigned char* buf, uint16* runs, uint16* erun, uint32 lastx) +{ + static struct { + char white, black; + short width; + } WBarr[] = { + { 'd', 'n', 512 }, { 'e', 'o', 256 }, { 'f', 'p', 128 }, + { 'g', 'q', 64 }, { 'h', 'r', 32 }, { 'i', 's', 16 }, + { 'j', 't', 8 }, { 'k', 'u', 4 }, { 'l', 'v', 2 }, + { 'm', 'w', 1 } + }; + static char* svalue = + " !\"#$&'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abc"; + int colormode = 1; /* 0 for white, 1 for black */ + int runlength = 0; + int n = maxline; + int x = 0; + int l; + + (void) buf; + printf("%d m(", row++); + while (runs < erun) { + if (!runlength) { + colormode ^= 1; + runlength = *runs++; + if (x+runlength > lastx) + runlength = runs[-1] = lastx-x; + x += runlength; + if (!colormode && runs == erun) + break; /* don't bother printing the final white run */ + } + /* + * If a runlength is greater than 6 pixels, then spit out + * black or white characters until the runlength drops to + * 6 or less. Once a runlength is <= 6, then combine black + * and white runlengths until a 6-pixel pattern is obtained. + * Then write out the special character. Six-pixel patterns + * were selected since 64 patterns is the largest power of + * two less than the 92 "easily printable" PostScript + * characters (i.e., no escape codes or octal chars). + */ + l = 0; + while (runlength > 6) { /* Run is greater than six... */ + if (runlength >= WBarr[l].width) { + if (n == 0) { + putchar('\n'); + n = maxline; + } + putchar(colormode ? WBarr[l].black : WBarr[l].white), n--; + runlength -= WBarr[l].width; + } else + l++; + } + while (runlength > 0 && runlength <= 6) { + int bitsleft = 6; + int t = 0; + while (bitsleft) { + if (runlength <= bitsleft) { + if (colormode) + t |= ((1 << runlength)-1) << (bitsleft-runlength); + bitsleft -= runlength; + runlength = 0; + if (bitsleft) { + if (runs >= erun) + break; + colormode ^= 1; + runlength = *runs++; + if (x+runlength > lastx) + runlength = runs[-1] = lastx-x; + x += runlength; + } + } else { /* runlength exceeds bits left */ + if (colormode) + t |= ((1 << bitsleft)-1); + runlength -= bitsleft; + bitsleft = 0; + } + } + if (n == 0) { + putchar('\n'); + n = maxline; + } + putchar(svalue[t]), n--; + } + } + printf(")s\n"); +} + +void +printTIF(TIFF* tif, int pageNumber) +{ + uint32 w, h; + uint16 unit; + float xres, yres; + tstrip_t s, ns; + + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); + if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)) { + TIFFWarning(TIFFFileName(tif), + "No x-resolution, assuming %g dpi", defxres); + xres = defxres; + } + if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)) { + TIFFWarning(TIFFFileName(tif), + "No y-resolution, assuming %g lpi", defyres); + yres = defyres; /* XXX */ + } + if (TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &unit) && + unit == RESUNIT_CENTIMETER) { + xres *= 25.4; + yres *= 25.4; + } + + printf("%%%%Page: \"%d\" %d\n", pageNumber, pageNumber); + printf("/$pageTop save def gsave\n"); + if (scaleToPage) { + float yscale = pageHeight / (h/yres); + float xscale = pageWidth / (w/xres); + printf("%d %d translate\n", + (int) (((basePageWidth - pageWidth) * points) * half), + (int)((yscale*(h/yres)*points) + + (basePageHeight - pageHeight) * points * half) ); + printf("%g %g scale\n", (72.*xscale)/xres, -(72.*yscale)/yres); + } else { + printf("%d %d translate\n", + (int) ((basePageWidth - pageWidth) * points * half), + (int)((72.*h/yres) + + (basePageHeight - pageHeight) * points * half) ); + printf("%g %g scale\n", 72./xres, -72./yres); + } + printf("0 setgray\n"); + TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, printruns); + ns = TIFFNumberOfStrips(tif); + row = 0; + for (s = 0; s < ns; s++) + (void) TIFFReadEncodedStrip(tif, s, (tdata_t) NULL, (tsize_t) -1); + printf("p\n"); + printf("grestore $pageTop restore\n"); + totalPages++; +} + +#define GetPageNumber(tif) \ +TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pn, &ptotal) + +int +findPage(TIFF* tif, int pageNumber) +{ + uint16 pn = (uint16) -1; + uint16 ptotal = (uint16) -1; + if (GetPageNumber(tif)) { + while (pn != pageNumber && TIFFReadDirectory(tif) && GetPageNumber(tif)) + ; + return (pn == pageNumber); + } else + return (TIFFSetDirectory(tif, pageNumber-1)); +} + +void +fax2ps(TIFF* tif, int npages, int* pages, char* filename) +{ + if (npages > 0) { + uint16 pn, ptotal; + int i; + + if (!GetPageNumber(tif)) + fprintf(stderr, "%s: No page numbers, counting directories.\n", + filename); + for (i = 0; i < npages; i++) { + if (findPage(tif, pages[i])) + printTIF(tif, pages[i]); + else + fprintf(stderr, "%s: No page number %d\n", filename, pages[i]); + } + } else { + int pageNumber = 1; + do + printTIF(tif, pageNumber++); + while (TIFFReadDirectory(tif)); + } +} + +#undef GetPageNumber + +/* + * Create a special PostScript font for printing FAX documents. By taking + * advantage of the font-cacheing mechanism, a substantial speed-up in + * rendering time is realized. + */ +static void +emitFont(FILE* fd) +{ + static const char* fontPrologue[] = { + "/newfont 10 dict def newfont begin /FontType 3 def /FontMatrix [1", + "0 0 1 0 0] def /FontBBox [0 0 512 1] def /Encoding 256 array def", + "0 1 31{Encoding exch /255 put}for 120 1 255{Encoding exch /255", + "put}for Encoding 37 /255 put Encoding 40 /255 put Encoding 41 /255", + "put Encoding 92 /255 put /count 0 def /ls{Encoding exch count 3", + "string cvs cvn put /count count 1 add def}def 32 1 36{ls}for", + "38 1 39{ls}for 42 1 91{ls}for 93 1 99{ls}for /count 100", + "def 100 1 119{ls}for /CharDict 5 dict def CharDict begin /white", + "{dup 255 eq{pop}{1 dict begin 100 sub neg 512 exch bitshift", + "/cw exch def cw 0 0 0 cw 1 setcachedevice end}ifelse}def /black", + "{dup 255 eq{pop}{1 dict begin 110 sub neg 512 exch bitshift", + "/cw exch def cw 0 0 0 cw 1 setcachedevice 0 0 moveto cw 0 rlineto", + "0 1 rlineto cw neg 0 rlineto closepath fill end}ifelse}def /numbuild", + "{dup 255 eq{pop}{6 0 0 0 6 1 setcachedevice 0 1 5{0 moveto", + "dup 32 and 32 eq{1 0 rlineto 0 1 rlineto -1 0 rlineto closepath", + "fill newpath}if 1 bitshift}for pop}ifelse}def /.notdef {}", + "def /255 {}def end /BuildChar{exch begin dup 110 ge{Encoding", + "exch get 3 string cvs cvi CharDict /black get}{dup 100 ge {Encoding", + "exch get 3 string cvs cvi CharDict /white get}{Encoding exch get", + "3 string cvs cvi CharDict /numbuild get}ifelse}ifelse exec end", + "}def end /Bitfont newfont definefont 1 scalefont setfont", + NULL + }; + int i; + for (i = 0; fontPrologue[i] != NULL; i++) + fprintf(fd, "%s\n", fontPrologue[i]); +} + +static int +pcompar(const void* va, const void* vb) +{ + const int* pa = (const int*) va; + const int* pb = (const int*) vb; + return (*pa - *pb); +} + +static void usage(int code); + +int +main(int argc, char** argv) +{ + extern int optind; + extern char* optarg; + int c, pageNumber; + int* pages = 0, npages = 0; + int dowarnings = 0; /* if 1, enable library warnings */ + time_t t; + TIFF* tif; + + while ((c = getopt(argc, argv, "l:p:x:y:W:H:wS")) != -1) + switch (c) { + case 'H': /* page height */ + pageHeight = atof(optarg); + break; + case 'S': /* scale to page */ + scaleToPage = 1; + break; + case 'W': /* page width */ + pageWidth = atof(optarg); + break; + case 'p': /* print specific page */ + pageNumber = atoi(optarg); + if (pageNumber < 1) { + fprintf(stderr, "%s: Invalid page number (must be > 0).\n", + optarg); + usage(-1); + } + if (pages) + pages = (int*) realloc((char*) pages, (npages+1)*sizeof (int)); + else + pages = (int*) malloc(sizeof (int)); + pages[npages++] = pageNumber; + break; + case 'w': + dowarnings = 1; + break; + case 'x': + defxres = atof(optarg); + break; + case 'y': + defyres = atof(optarg); + break; + case 'l': + maxline = atoi(optarg); + break; + case '?': + usage(-1); + } + if (npages > 0) + qsort(pages, npages, sizeof (int), pcompar); + if (!dowarnings) + TIFFSetWarningHandler(0); + printf("%%!PS-Adobe-3.0\n"); + printf("%%%%Creator: fax2ps\n"); +#ifdef notdef + printf("%%%%Title: %s\n", file); +#endif + t = time(0); + printf("%%%%CreationDate: %s", ctime(&t)); + printf("%%%%Origin: 0 0\n"); + printf("%%%%BoundingBox: 0 0 %u %u\n", + (int)(pageHeight*72), (int)(pageWidth*72)); /* XXX */ + printf("%%%%Pages: (atend)\n"); + printf("%%%%EndComments\n"); + printf("%%%%BeginProlog\n"); + emitFont(stdout); + printf("/d{bind def}def\n"); /* bind and def proc */ + printf("/m{0 exch moveto}d\n"); + printf("/s{show}d\n"); + printf("/p{showpage}d \n"); /* end page */ + printf("%%%%EndProlog\n"); + if (optind < argc) { + do { + tif = TIFFOpen(argv[optind], "r"); + if (tif) { + fax2ps(tif, npages, pages, argv[optind]); + TIFFClose(tif); + } else + fprintf(stderr, "%s: Can not open, or not a TIFF file.\n", + argv[optind]); + } while (++optind < argc); + } else { + int n; + FILE* fd; + char temp[1024], buf[16*1024]; + + strcpy(temp, "/tmp/fax2psXXXXXX"); + (void) mktemp(temp); + fd = fopen(temp, "w"); + if (fd == NULL) { + fprintf(stderr, "Could not create temp file \"%s\"\n", temp); + exit(-2); + } + while ((n = read(fileno(stdin), buf, sizeof (buf))) > 0) + write(fileno(fd), buf, n); + tif = TIFFOpen(temp, "r"); +#ifndef VMS + unlink(temp); +#else + remove(temp); +#endif + if (tif) { + fax2ps(tif, npages, pages, ""); + TIFFClose(tif); + } else + fprintf(stderr, "%s: Can not open, or not a TIFF file.\n", temp); + fclose(fd); + } + printf("%%%%Trailer\n"); + printf("%%%%Pages: %u\n", totalPages); + printf("%%%%EOF\n"); + + return (0); +} + +char* stuff[] = { +"usage: fax2ps [options] [input.tif ...]", +"where options are:", +" -w suppress warning messages", +" -l chars set maximum output line length for generated PostScript", +" -p page# select page to print (can use multiple times)", +" -x xres set default horizontal resolution of input data (dpi)", +" -y yres set default vertical resolution of input data (lpi)", +" -S scale output to page size", +" -W width set output page width (inches), default is 8.5", +" -H height set output page height (inchest), default is 11", +NULL +}; + +static void +usage(int code) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(code); +} diff --git a/tools/fax2tiff.c b/tools/fax2tiff.c new file mode 100644 index 00000000..2381709b --- /dev/null +++ b/tools/fax2tiff.c @@ -0,0 +1,358 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/fax2tiff.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * Convert a CCITT Group 3 FAX file to TIFF Group 3 format. + */ +#include +#include /* should have atof & getopt */ +#include "tiffiop.h" + +#ifndef BINMODE +#define BINMODE +#endif + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + +TIFF *faxTIFF; +#define XSIZE 1728 +char rowbuf[TIFFhowmany(XSIZE,8)]; +char refbuf[TIFFhowmany(XSIZE,8)]; + +int verbose; +int stretch; +uint16 badfaxrun; +uint32 badfaxlines; + +int copyFaxFile(TIFF* tifin, TIFF* tifout); +static void usage(void); + +static tsize_t +DummyReadProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + (void) fd; (void) buf; (void) size; + return (0); +} + +static tsize_t +DummyWriteProc(thandle_t fd, tdata_t buf, tsize_t size) +{ + (void) fd; (void) buf; (void) size; + return (size); +} + +int +main(int argc, char* argv[]) +{ + FILE *in; + TIFF *out = NULL; + TIFFErrorHandler whandler; + int compression = COMPRESSION_CCITTFAX3; + int fillorder = FILLORDER_LSB2MSB; + uint32 group3options = GROUP3OPT_FILLBITS|GROUP3OPT_2DENCODING; + int photometric = PHOTOMETRIC_MINISWHITE; + int mode = FAXMODE_CLASSF; + int rows; + int c; + int pn, npages; + extern int optind; + extern char* optarg; + + /* smuggle a descriptor out of the library */ + faxTIFF = TIFFClientOpen("(FakeInput)", "w", (thandle_t) -1, + DummyReadProc, DummyWriteProc, + NULL, NULL, NULL, NULL, NULL); + if (faxTIFF == NULL) + return (EXIT_FAILURE); + faxTIFF->tif_mode = O_RDONLY; + + TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH, XSIZE); + TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE, 1); + TIFFSetField(faxTIFF, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); + TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); + TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION, 196.); + TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); + /* NB: this is normally setup when a directory is read */ + faxTIFF->tif_scanlinesize = TIFFScanlineSize(faxTIFF); + + while ((c = getopt(argc, argv, "R:o:2BLMW14cflmpsvwz")) != -1) + switch (c) { + /* input-related options */ + case '2': /* input is 2d-encoded */ + TIFFSetField(faxTIFF, + TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING); + break; + case 'B': /* input has 0 mean black */ + TIFFSetField(faxTIFF, + TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + break; + case 'L': /* input has lsb-to-msb fillorder */ + TIFFSetField(faxTIFF, + TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); + break; + case 'M': /* input has msb-to-lsb fillorder */ + TIFFSetField(faxTIFF, + TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); + break; + case 'R': /* input resolution */ + TIFFSetField(faxTIFF, + TIFFTAG_YRESOLUTION, atof(optarg)); + break; + case 'W': /* input has 0 mean white */ + TIFFSetField(faxTIFF, + TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); + break; + + /* output-related options */ + case '1': /* generate 1d-encoded output */ + group3options &= ~GROUP3OPT_2DENCODING; + break; + case '4': /* generate g4-encoded output */ + compression = COMPRESSION_CCITTFAX4; + break; + case 'c': /* generate "classic" g3 format */ + mode = FAXMODE_CLASSIC; + break; + case 'f': /* generate Class F format */ + mode = FAXMODE_CLASSF; + break; + case 'm': /* output's fillorder is msb-to-lsb */ + fillorder = FILLORDER_MSB2LSB; + break; + case 'o': + out = TIFFOpen(optarg, "w"); + if (out == NULL) + return EXIT_FAILURE; + break; + case 'p': /* zero pad output scanline EOLs */ + group3options &= ~GROUP3OPT_FILLBITS; + break; + case 's': /* stretch image by dup'ng scanlines */ + stretch = 1; + break; + case 'w': /* undocumented -- for testing */ + photometric = PHOTOMETRIC_MINISBLACK; + break; + + case 'z': /* undocumented -- for testing */ + compression = COMPRESSION_LZW; + break; + + case 'v': /* -v for info */ + verbose++; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (out == NULL) { + out = TIFFOpen("fax.tif", "w"); + if (out == NULL) + return (EXIT_FAILURE); + } + faxTIFF->tif_readproc = out->tif_readproc; /* XXX */ + faxTIFF->tif_writeproc = out->tif_writeproc; /* XXX */ + faxTIFF->tif_seekproc = out->tif_seekproc; /* XXX */ + faxTIFF->tif_closeproc = out->tif_closeproc; /* XXX */ + faxTIFF->tif_sizeproc = out->tif_sizeproc; /* XXX */ + faxTIFF->tif_mapproc = out->tif_mapproc; /* XXX */ + faxTIFF->tif_unmapproc = out->tif_unmapproc; /* XXX */ + + npages = argc - optind; + if (npages < 1) + usage(); + + /* NB: this must be done after directory info is setup */ + TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3); + for (pn = 0; optind < argc; pn++, optind++) { + in = fopen(argv[optind], "r" BINMODE); + if (in == NULL) { + fprintf(stderr, + "%s: %s: Can not open\n", argv[0], argv[optind]); + continue; + } + faxTIFF->tif_fd = fileno(in); + faxTIFF->tif_clientdata = (thandle_t) faxTIFF->tif_fd; + faxTIFF->tif_name = argv[optind]; + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, XSIZE); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1); + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); + if (compression == COMPRESSION_CCITTFAX3) { + TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options); + TIFFSetField(out, TIFFTAG_FAXMODE, mode); + } + if (compression == COMPRESSION_CCITTFAX3 || + compression == COMPRESSION_CCITTFAX4) + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, -1L); + else + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, 0)); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); + TIFFSetField(out, TIFFTAG_SOFTWARE, "fax2tiff"); + TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0); + if (!stretch) { + float yres; + TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &yres); + TIFFSetField(out, TIFFTAG_YRESOLUTION, yres); + } else + TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.); + TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); + TIFFSetField(out, TIFFTAG_PAGENUMBER, pn+1, npages); + + if (!verbose) + whandler = TIFFSetWarningHandler(NULL); + rows = copyFaxFile(faxTIFF, out); + fclose(in); + if (!verbose) + (void) TIFFSetWarningHandler(whandler); + + TIFFSetField(out, TIFFTAG_IMAGELENGTH, rows); + + if (verbose) { + fprintf(stderr, "%s:\n", argv[optind]); + fprintf(stderr, "%d rows in input\n", rows); + fprintf(stderr, "%ld total bad rows\n", + (long) badfaxlines); + fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun); + } + if (compression == COMPRESSION_CCITTFAX3 && + mode == FAXMODE_CLASSF) { + TIFFSetField(out, TIFFTAG_BADFAXLINES, badfaxlines); + TIFFSetField(out, TIFFTAG_CLEANFAXDATA, badfaxlines ? + CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN); + TIFFSetField(out, TIFFTAG_CONSECUTIVEBADFAXLINES, badfaxrun); + } + TIFFWriteDirectory(out); + } + TIFFClose(out); + return (EXIT_SUCCESS); +} + +int +copyFaxFile(TIFF* tifin, TIFF* tifout) +{ + uint32 row; + uint16 badrun; + int ok; + + tifin->tif_rawdatasize = TIFFGetFileSize(tifin); + tifin->tif_rawdata = _TIFFmalloc(tifin->tif_rawdatasize); + if (!ReadOK(tifin, tifin->tif_rawdata, tifin->tif_rawdatasize)) { + TIFFError(tifin->tif_name, "%s: Read error at scanline 0"); + return (0); + } + tifin->tif_rawcp = tifin->tif_rawdata; + tifin->tif_rawcc = tifin->tif_rawdatasize; + + (*tifin->tif_setupdecode)(tifin); + (*tifin->tif_predecode)(tifin, (tsample_t) 0); + tifin->tif_row = 0; + badfaxlines = 0; + badfaxrun = 0; + + _TIFFmemset(refbuf, 0, sizeof (refbuf)); + row = 0; + badrun = 0; /* current run of bad lines */ + while (tifin->tif_rawcc > 0) { + ok = (*tifin->tif_decoderow)(tifin, rowbuf, sizeof (rowbuf), 0); + if (!ok) { + badfaxlines++; + badrun++; + /* regenerate line from previous good line */ + _TIFFmemcpy(rowbuf, refbuf, sizeof (rowbuf)); + } else { + if (badrun > badfaxrun) + badfaxrun = badrun; + badrun = 0; + _TIFFmemcpy(refbuf, rowbuf, sizeof (rowbuf)); + } + tifin->tif_row++; + + if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) { + fprintf(stderr, "%s: Write error at row %ld.\n", + tifout->tif_name, (long) row); + break; + } + row++; + if (stretch) { + if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) { + fprintf(stderr, "%s: Write error at row %ld.\n", + tifout->tif_name, (long) row); + break; + } + row++; + } + } + if (badrun > badfaxrun) + badfaxrun = badrun; + _TIFFfree(tifin->tif_rawdata); + return (row); +} + +char* stuff[] = { +"usage: fax2tiff [options] input.g3...", +"where options are:", +" -2 input data is 2d encoded", +" -B input data has min 0 means black", +" -L input data has LSB2MSB bit order (default)", +" -M input data has MSB2LSB bit order", +" -W input data has min 0 means white (default)", +" -R # input data has # resolution (lines/inch) (default is 196)", +"", +" -o out.tif write output to out.tif", +" -1 generate 1d-encoded output (default is G3 2d)", +" -4 generate G4-encoded output (default is G3 2D)", +" -c generate \"classic\" TIFF format (default is TIFF/F)", +" -f generate TIFF Class F (TIFF/F) format (default)", +" -m output fill order is MSB2LSB (default is LSB2MSB)", +" -p do not byte-align EOL codes in output (default is byte-align)", +" -s stretch image by duplicating scanlines", +" -v print information about conversion work", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(EXIT_FAILURE); +} diff --git a/tools/gif2tiff.c b/tools/gif2tiff.c new file mode 100644 index 00000000..ceea8154 --- /dev/null +++ b/tools/gif2tiff.c @@ -0,0 +1,512 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/gif2tiff.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +/* + * convert a GIF file into a TIFF file. + * based on Paul Haeberli's fromgif program which in turn is + * based on a GIF file reader by Marcel J.E. Mol March 23 1989 + * + * if input is 320 by 200 pixel aspect is probably 1.2 + * if input is 640 350 pixel aspect is probably 1.37 + * + */ +#include +#include +#include +#include + +#include "tiffio.h" + +#if defined(_WINDOWS) || defined(MSDOS) +#define BINMODE "b" +#else +#define BINMODE +#endif + +#define GIFGAMMA (1.5) /* smaller makes output img brighter */ +#define IMAX 0xffff /* max intensity value */ +#define EXTRAFUDGE 128 /* some people write BAD .gif files */ + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +unsigned short gamtab[256]; + +void +makegamtab(float gam) +{ + int i; + + for(i=0; i<256; i++) + gamtab[i] = IMAX*pow(i/255.0,gam)+0.5; +} + +char* stuff[] = { +"usage: gif2tiff [options] input.gif output.tif", +"where options are:", +" -r # make each strip have no more than # rows", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} + +#define COLSIZE 256 + +unsigned char *stackp; +unsigned int prefix[4096]; +unsigned char suffix[4096]; +unsigned char stack[4096]; +int datasize,codesize,codemask; /* Decoder working variables */ +int clear,eoi; /* Special code values */ +int avail, oldcode; + +FILE *infile; +int global; /* Is there a global color map? */ +int globalbits; /* Number of bits of global colors */ +unsigned char globalmap[COLSIZE][3];/* RGB values for global color map */ +unsigned char *raster; /* Decoded image data */ +unsigned long width, height; +unsigned short red[COLSIZE]; +unsigned short green[COLSIZE]; +unsigned short blue[COLSIZE]; +char *filename, *imagename; + +static uint16 compression = COMPRESSION_LZW; +static uint16 predictor = 0; +static uint32 rowsperstrip = (uint32) -1; +static int processCompressOptions(char*); + +int convert(void); +int checksignature(void); +void readscreen(void); +int readgifimage(char*); +void readextension(void); +int readraster(void); +int process(int, unsigned char**); +void initcolors(unsigned char [COLSIZE][3], int); +void rasterize(int, char*); + +int +main(int argc, char* argv[]) +{ + extern int optind; + extern char *optarg; + int c, status; + + while ((c = getopt(argc, argv, "c:r:")) != -1) + switch (c) { + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind != 2) + usage(); + + makegamtab(GIFGAMMA); + filename = argv[optind]; + imagename = argv[optind+1]; + if ((infile = fopen(imagename, "r" BINMODE)) != NULL) { + int c; + fclose(infile); + printf("overwrite %s? ", imagename); fflush(stdout); + c = getc(stdin); + if (c != 'y' && c != 'Y') + return (1); + } + if ((infile = fopen(filename, "r" BINMODE)) == NULL) { + perror(filename); + return (1); + } + status = convert(); + fclose(infile); + return (status); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +int +convert(void) +{ + int ch; + char* mode = "w"; + + if (!checksignature()) + return (-1); + readscreen(); + while ((ch = getc(infile)) != ';' && ch != EOF) { + switch (ch) { + case '\0': break; /* this kludge for non-standard files */ + case ',': if (!readgifimage(mode)) + return (-1); + mode = "a"; /* subsequent images append */ + break; + case '!': readextension(); + break; + default: fprintf(stderr, "illegal GIF block type\n"); + return (-1); + } + } + return (0); +} + +int +checksignature(void) +{ + char buf[6]; + + fread(buf,1,6,infile); + if (strncmp(buf,"GIF",3)) { + fprintf(stderr, "file is not a GIF file\n"); + return 0; + } + if (strncmp(&buf[3],"87a",3)) { + fprintf(stderr, "unknown GIF version number\n"); + return 0; + } + return 1; +} + +/* + * readscreen - + * Get information which is global to all the images stored + * in the file + */ +void +readscreen(void) +{ + unsigned char buf[7]; + + fread(buf,1,7,infile); + global = buf[4] & 0x80; + if (global) { + globalbits = (buf[4] & 0x07) + 1; + fread(globalmap,3,1< 0; count = getc(infile)) { + fread(buf,1,count,infile); + for (ch=buf; count-- > 0; ch++) { + datum += (unsigned long) *ch << bits; + bits += 8; + while (bits >= codesize) { + code = datum & codemask; + datum >>= codesize; + bits -= codesize; + if (code == eoi) { /* This kludge put in */ + goto exitloop; /* because some GIF files*/ + } /* aren't standard */ + if (!process(code, &fill)) { + status = 0; + goto exitloop; + } + } + } + if (fill >= raster + width*height) { + fprintf(stderr, "raster full before eoi code\n"); + break; + } + } +exitloop: + if (fill != raster + width*height) { + fprintf(stderr, "warning: wrong rastersize: %ld bytes\n", + (long) (fill-raster)); + fprintf(stderr, " instead of %ld bytes\n", + (long) width*height); + } + return status; +} + +/* + * process - + * Process a compression code. "clear" resets the code table. + * Otherwise make a new code table entry, and output the bytes + * associated with the code. + */ +int +process(register int code, unsigned char** fill) +{ + int incode; + static unsigned char firstchar; + + if (code == clear) { + codesize = datasize + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + return 1; + } + + if (oldcode == -1) { + *(*fill)++ = suffix[code]; + firstchar = oldcode = code; + return 1; + } + if (code > avail) { + fprintf(stderr, "code %d too large for %d\n", code, avail); + return 0; + } + + incode = code; + if (code == avail) { /* the first code is always < avail */ + *stackp++ = firstchar; + code = oldcode; + } + while (code > clear) { + *stackp++ = suffix[code]; + code = prefix[code]; + } + + *stackp++ = firstchar = suffix[code]; + prefix[avail] = oldcode; + suffix[avail] = firstchar; + avail++; + + if (((avail & codemask) == 0) && (avail < 4096)) { + codesize++; + codemask += avail; + } + oldcode = incode; + do { + *(*fill)++ = *--stackp; + } while (stackp > stack); + return 1; +} + +/* + * initcolors - + * Convert a color map (local or global) to arrays with R, G and B + * values. + * + */ +void +initcolors(unsigned char colormap[COLSIZE][3], int ncolors) +{ + register int i; + + for (i = 0; i < ncolors; i++) { + red[i] = gamtab[colormap[i][0]]; + green[i] = gamtab[colormap[i][1]]; + blue[i] = gamtab[colormap[i][2]]; + } +} + +void +rasterize(int interleaved, char* mode) +{ + register long row; + unsigned char *newras; + unsigned char *ras; + TIFF *tif; + tstrip_t strip; + tsize_t stripsize; + + if ((newras = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) { + fprintf(stderr, "not enough memory for image\n"); + return; + } +#define DRAWSEGMENT(offset, step) { \ + for (row = offset; row < height; row += step) { \ + _TIFFmemcpy(newras + row*width, ras, width);\ + ras += width; \ + } \ + } + ras = raster; + if (interleaved) { + DRAWSEGMENT(0, 8); + DRAWSEGMENT(4, 8); + DRAWSEGMENT(2, 4); + DRAWSEGMENT(1, 2); + } else + DRAWSEGMENT(0, 1); +#undef DRAWSEGMENT + + tif = TIFFOpen(imagename, mode); + if (!tif) { + TIFFError(imagename,"Can not open output image"); + exit(-1); + } + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) width); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) height); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, + rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip)); + TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); + switch (compression) { + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor); + break; + } + TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue); + TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + strip = 0; + stripsize = TIFFStripSize(tif); + for (row=0; row +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +static void usage(void); +static void cpTags(TIFF* in, TIFF* out); + +static int +checkcmap(int n, uint16* r, uint16* g, uint16* b) +{ + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + fprintf(stderr, "Warning, assuming 8-bit colormap.\n"); + return (8); +} + +#define CopyField(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) +#define CopyField3(tag, v1, v2, v3) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) + +static uint16 compression = (uint16) -1; +static uint16 predictor = 0; +static int quality = 75; /* JPEG quality */ +static int jpegcolormode = JPEGCOLORMODE_RGB; +static int processCompressOptions(char*); + +int +main(int argc, char* argv[]) +{ + uint16 bitspersample, shortv; + uint32 imagewidth, imagelength; + uint16 config = PLANARCONFIG_CONTIG; + uint32 rowsperstrip = (uint32) -1; + uint16 photometric = PHOTOMETRIC_RGB; + uint16 *rmap, *gmap, *bmap; + uint32 row; + int cmap = -1; + TIFF *in, *out; + int c; + extern int optind; + extern char* optarg; + + while ((c = getopt(argc, argv, "C:c:p:r:")) != -1) + switch (c) { + case 'C': /* force colormap interpretation */ + cmap = atoi(optarg); + break; + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'p': /* planar configuration */ + if (streq(optarg, "separate")) + config = PLANARCONFIG_SEPARATE; + else if (streq(optarg, "contig")) + config = PLANARCONFIG_CONTIG; + else + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind != 2) + usage(); + in = TIFFOpen(argv[optind], "r"); + if (in == NULL) + return (-1); + if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) || + shortv != PHOTOMETRIC_PALETTE) { + fprintf(stderr, "%s: Expecting a palette image.\n", + argv[optind]); + return (-1); + } + if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) { + fprintf(stderr, + "%s: No colormap (not a valid palette image).\n", + argv[optind]); + return (-1); + } + bitspersample = 0; + TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + if (bitspersample != 8) { + fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n", + argv[optind]); + return (-1); + } + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-2); + cpTags(in, out); + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength); + if (compression != (uint16)-1) + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + else + TIFFGetField(in, TIFFTAG_COMPRESSION, &compression); + switch (compression) { + case COMPRESSION_JPEG: + if (jpegcolormode == JPEGCOLORMODE_RGB) + photometric = PHOTOMETRIC_YCBCR; + else + photometric = PHOTOMETRIC_RGB; + TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, config); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip)); + (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv); + if (cmap == -1) + cmap = checkcmap(1<= 0; i--) { +#define CVT(x) (((x) * 255) / ((1L<<16)-1)) + rmap[i] = CVT(rmap[i]); + gmap[i] = CVT(gmap[i]); + bmap[i] = CVT(bmap[i]); + } + } + { unsigned char *ibuf, *obuf; + register unsigned char* pp; + register uint32 x; + ibuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(in)); + obuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(out)); + switch (config) { + case PLANARCONFIG_CONTIG: + for (row = 0; row < imagelength; row++) { + if (!TIFFReadScanline(in, ibuf, row, 0)) + goto done; + pp = obuf; + for (x = 0; x < imagewidth; x++) { + *pp++ = rmap[ibuf[x]]; + *pp++ = gmap[ibuf[x]]; + *pp++ = bmap[ibuf[x]]; + } + if (!TIFFWriteScanline(out, obuf, row, 0)) + goto done; + } + break; + case PLANARCONFIG_SEPARATE: + for (row = 0; row < imagelength; row++) { + if (!TIFFReadScanline(in, ibuf, row, 0)) + goto done; + for (pp = obuf, x = 0; x < imagewidth; x++) + *pp++ = rmap[ibuf[x]]; + if (!TIFFWriteScanline(out, obuf, row, 0)) + goto done; + for (pp = obuf, x = 0; x < imagewidth; x++) + *pp++ = gmap[ibuf[x]]; + if (!TIFFWriteScanline(out, obuf, row, 0)) + goto done; + for (pp = obuf, x = 0; x < imagewidth; x++) + *pp++ = bmap[ibuf[x]]; + if (!TIFFWriteScanline(out, obuf, row, 0)) + goto done; + } + break; + } + _TIFFfree(ibuf); + _TIFFfree(obuf); + } +done: + (void) TIFFClose(in); + (void) TIFFClose(out); + return (0); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "jpeg", 4)) { + char* cp = strchr(opt, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + compression = COMPRESSION_JPEG; + } else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +#define CopyField1(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) +#define CopyField2(tag, v1, v2) \ + if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) +#define CopyField3(tag, v1, v2, v3) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) +#define CopyField4(tag, v1, v2, v3, v4) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4) + +static void +cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type) +{ + uint16 shortv, shortv2, *shortav; + float floatv, *floatav; + char *stringv; + uint32 longv; + + switch (type) { + case TIFF_SHORT: + if (count == 1) { + CopyField1(tag, shortv); + } else if (count == 2) { + CopyField2(tag, shortv, shortv2); + } else if (count == (uint16) -1) { + CopyField2(tag, shortv, shortav); + } + break; + case TIFF_LONG: + CopyField1(tag, longv); + break; + case TIFF_RATIONAL: + if (count == 1) { + CopyField1(tag, floatv); + } else if (count == (uint16) -1) { + CopyField1(tag, floatav); + } + break; + case TIFF_ASCII: + CopyField1(tag, stringv); + break; + } +} +#undef CopyField4 +#undef CopyField3 +#undef CopyField2 +#undef CopyField1 + +static struct cpTag { + uint16 tag; + uint16 count; + TIFFDataType type; +} tags[] = { + { TIFFTAG_IMAGEWIDTH, 1, TIFF_LONG }, + { TIFFTAG_IMAGELENGTH, 1, TIFF_LONG }, + { TIFFTAG_BITSPERSAMPLE, 1, TIFF_SHORT }, + { TIFFTAG_COMPRESSION, 1, TIFF_SHORT }, + { TIFFTAG_FILLORDER, 1, TIFF_SHORT }, + { TIFFTAG_ROWSPERSTRIP, 1, TIFF_LONG }, + { TIFFTAG_GROUP3OPTIONS, 1, TIFF_LONG }, + { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG }, + { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT }, + { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII }, + { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII }, + { TIFFTAG_MAKE, 1, TIFF_ASCII }, + { TIFFTAG_MODEL, 1, TIFF_ASCII }, + { TIFFTAG_ORIENTATION, 1, TIFF_SHORT }, + { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT }, + { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT }, + { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_PAGENAME, 1, TIFF_ASCII }, + { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG }, + { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT }, + { TIFFTAG_PAGENUMBER, 2, TIFF_SHORT }, + { TIFFTAG_SOFTWARE, 1, TIFF_ASCII }, + { TIFFTAG_DATETIME, 1, TIFF_ASCII }, + { TIFFTAG_ARTIST, 1, TIFF_ASCII }, + { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII }, + { TIFFTAG_WHITEPOINT, 1, TIFF_RATIONAL }, + { TIFFTAG_PRIMARYCHROMATICITIES, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT }, + { TIFFTAG_BADFAXLINES, 1, TIFF_LONG }, + { TIFFTAG_CLEANFAXDATA, 1, TIFF_SHORT }, + { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG }, + { TIFFTAG_INKSET, 1, TIFF_SHORT }, + { TIFFTAG_INKNAMES, 1, TIFF_ASCII }, + { TIFFTAG_DOTRANGE, 2, TIFF_SHORT }, + { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII }, + { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT }, + { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT }, + { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT }, + { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL }, +}; +#define NTAGS (sizeof (tags) / sizeof (tags[0])) + +static void +cpTags(TIFF* in, TIFF* out) +{ + struct cpTag *p; + for (p = tags; p < &tags[NTAGS]; p++) + cpTag(in, out, p->tag, p->count, p->type); +} +#undef NTAGS + +char* stuff[] = { +"usage: pal2rgb [options] input.tif output.tif", +"where options are:", +" -p contig pack samples contiguously (e.g. RGBRGB...)", +" -p separate store samples separately (e.g. RRR...GGG...BBB...)", +" -r # make each strip have no more than # rows", +" -C 8 assume 8-bit colormap values (instead of 16-bit)", +" -C 16 assume 16-bit colormap values", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/ppm2tiff.c b/tools/ppm2tiff.c new file mode 100644 index 00000000..9d6cd624 --- /dev/null +++ b/tools/ppm2tiff.c @@ -0,0 +1,241 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/ppm2tiff.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include "tiffio.h" + +#if defined(_WINDOWS) || defined(MSDOS) +#define BINMODE "b" +#else +#define BINMODE +#endif + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +static uint16 compression = COMPRESSION_LZW; +static uint16 predictor = 0; +static int quality = 75; /* JPEG quality */ +static int jpegcolormode = JPEGCOLORMODE_RGB; + +static void usage(void); +static int processCompressOptions(char*); + +static void +BadPPM(char* file) +{ + fprintf(stderr, "%s: Not a PPM file.\n", file); + exit(-2); +} + +int +main(int argc, char* argv[]) +{ + uint16 photometric; + uint32 rowsperstrip = (uint32) -1; + double resolution = -1; + unsigned char *buf = NULL; + uint32 row; + tsize_t linebytes; + uint16 spp; + TIFF *out; + FILE *in; + uint32 w, h; + int prec; + char *infile; + int c; + extern int optind; + extern char* optarg; + + while ((c = getopt(argc, argv, "c:r:R:")) != -1) + switch (c) { + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case 'R': /* resolution */ + resolution = atof(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + + /* + * If only one file is specified, read input from + * stdin; otherwise usage is: ppm2tiff input output. + */ + if (argc - optind > 1) { + infile = argv[optind++]; + in = fopen(infile, "r" BINMODE); + if (in == NULL) { + fprintf(stderr, "%s: Can not open.\n", infile); + return (-1); + } + } else { + infile = ""; + in = stdin; + } + + if (getc(in) != 'P') + BadPPM(infile); + switch (getc(in)) { + case '5': /* it's a PGM file */ + spp = 1; + photometric = PHOTOMETRIC_MINISBLACK; + break; + case '6': /* it's a PPM file */ + spp = 3; + photometric = PHOTOMETRIC_RGB; + if (compression == COMPRESSION_JPEG && + jpegcolormode == JPEGCOLORMODE_RGB) + photometric = PHOTOMETRIC_YCBCR; + break; + default: + BadPPM(infile); + } + if (fscanf(in, " %ld %ld %d", &w, &h, &prec) != 3) + BadPPM(infile); + if (getc(in) != '\n' || w <= 0 || h <= 0 || prec != 255) + BadPPM(infile); + + out = TIFFOpen(argv[optind], "w"); + if (out == NULL) + return (-4); + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, w); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, h); + TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + switch (compression) { + case COMPRESSION_JPEG: + TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + linebytes = spp * w; + if (TIFFScanlineSize(out) > linebytes) + buf = (unsigned char *)_TIFFmalloc(linebytes); + else + buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + if (resolution > 0) { + TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution); + TIFFSetField(out, TIFFTAG_YRESOLUTION, resolution); + TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); + } + for (row = 0; row < h; row++) { + if (fread(buf, linebytes, 1, in) != 1) { + fprintf(stderr, "%s: scanline %lu: Read error.\n", + infile, (unsigned long) row); + break; + } + if (TIFFWriteScanline(out, buf, row, 0) < 0) + break; + } + (void) TIFFClose(out); + if (buf) + _TIFFfree(buf); + return (0); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "jpeg", 4)) { + char* cp = strchr(opt, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + compression = COMPRESSION_JPEG; + } else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +char* stuff[] = { +"usage: ppm2tiff [options] input.ppm output.tif", +"where options are:", +" -r # make each strip have no more than # rows", +" -R # set x&y resolution (dpi)", +"", +" -c jpeg[:opts] compress output with JPEG encoding", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"JPEG options:", +" # set compression quality level (0-100, default 75)", +" r output color image as RGB rather than YCbCr", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/ras2tiff.c b/tools/ras2tiff.c new file mode 100644 index 00000000..46b2e2f5 --- /dev/null +++ b/tools/ras2tiff.c @@ -0,0 +1,265 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/ras2tiff.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include "rasterfile.h" +#include "tiffio.h" + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +#ifndef BINMODE +#define BINMODE +#endif + +static uint16 compression = (uint16) -1; +static int jpegcolormode = JPEGCOLORMODE_RGB; +static int quality = 75; /* JPEG quality */ +static uint16 predictor = 0; + +static void usage(void); +static int processCompressOptions(char*); + +int +main(int argc, char* argv[]) +{ + unsigned char* buf; + uint32 row; + tsize_t linebytes, scanline; + TIFF *out; + FILE *in; + struct rasterfile h; + uint16 photometric; + uint16 config = PLANARCONFIG_CONTIG; + uint32 rowsperstrip = (uint32) -1; + int c; + extern int optind; + extern char* optarg; + + while ((c = getopt(argc, argv, "c:r:")) != -1) + switch (c) { + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind != 2) + usage(); + in = fopen(argv[optind], "r" BINMODE); + if (in == NULL) { + fprintf(stderr, "%s: Can not open.\n", argv[optind]); + return (-1); + } + if (fread(&h, sizeof (h), 1, in) != 1) { + fprintf(stderr, "%s: Can not read header.\n", argv[optind]); + return (-2); + } + if (h.ras_magic != RAS_MAGIC) { + fprintf(stderr, "%s: Not a rasterfile.\n", argv[optind]); + return (-3); + } + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-4); + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) h.ras_width); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) h.ras_height); + TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, h.ras_depth > 8 ? 3 : 1); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, h.ras_depth > 1 ? 8 : 1); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, config); + if (h.ras_maptype != RMT_NONE) { + uint16* red; + register uint16* map; + register int i, j; + int mapsize; + + buf = (unsigned char *)_TIFFmalloc(h.ras_maplength); + if (buf == NULL) { + fprintf(stderr, "No space to read in colormap.\n"); + return (-5); + } + if (fread(buf, h.ras_maplength, 1, in) != 1) { + fprintf(stderr, "%s: Read error on colormap.\n", + argv[optind]); + return (-6); + } + mapsize = 1< mapsize*3) { + fprintf(stderr, + "%s: Huh, %d colormap entries, should be %d?\n", + argv[optind], h.ras_maplength, mapsize*3); + return (-7); + } + red = (uint16*)_TIFFmalloc(mapsize * 3 * sizeof (uint16)); + if (red == NULL) { + fprintf(stderr, "No space for colormap.\n"); + return (-8); + } + map = red; + for (j = 0; j < 3; j++) { +#define SCALE(x) (((x)*((1L<<16)-1))/255) + for (i = h.ras_maplength/3; i-- > 0;) + *map++ = SCALE(*buf++); + if ((i = h.ras_maplength/3) < mapsize) { + i = mapsize - i; + _TIFFmemset(map, 0, i*sizeof (uint16)); + map += i; + } + } + TIFFSetField(out, TIFFTAG_COLORMAP, + red, red + mapsize, red + 2*mapsize); + photometric = PHOTOMETRIC_PALETTE; + if (compression == (uint16) -1) + compression = COMPRESSION_PACKBITS; + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + } else { + /* XXX this is bogus... */ + photometric = h.ras_depth == 24 ? + PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK; + if (compression == (uint16) -1) + compression = COMPRESSION_LZW; + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + } + switch (compression) { + case COMPRESSION_JPEG: + if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB) + photometric = PHOTOMETRIC_YCBCR; + TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric); + linebytes = ((h.ras_depth*h.ras_width+15) >> 3) &~ 1; + scanline = TIFFScanlineSize(out); + if (scanline > linebytes) { + buf = (unsigned char *)_TIFFmalloc(scanline); + _TIFFmemset(buf+linebytes, 0, scanline-linebytes); + } else + buf = (unsigned char *)_TIFFmalloc(linebytes); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + for (row = 0; row < h.ras_height; row++) { + if (fread(buf, linebytes, 1, in) != 1) { + fprintf(stderr, "%s: scanline %lu: Read error.\n", + argv[optind], (unsigned long) row); + break; + } + if (h.ras_type == RT_STANDARD && h.ras_depth == 24) { + tsize_t cc = h.ras_width; + unsigned char* cp = buf; +#define SWAP(a,b) { unsigned char t = (a); (a) = (b); (b) = t; } + do { + SWAP(cp[0], cp[2]); + cp += 3; + } while (--cc); + } + if (TIFFWriteScanline(out, buf, row, 0) < 0) + break; + } + (void) TIFFClose(out); + return (0); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "jpeg", 4)) { + char* cp = strchr(opt, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + compression = COMPRESSION_JPEG; + } else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +char* stuff[] = { +"usage: ras2tiff [options] input.ras output.tif", +"where options are:", +" -r # make each strip have no more than # rows", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c jpeg[:opts]compress output with JPEG encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"JPEG options:", +" # set compression quality level (0-100, default 75)", +" r output color image as RGB rather than YCbCr", +"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/rasterfile.h b/tools/rasterfile.h new file mode 100644 index 00000000..5b25324f --- /dev/null +++ b/tools/rasterfile.h @@ -0,0 +1,41 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/rasterfile.h,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Description of header for files containing raster images + */ +struct rasterfile { + int ras_magic; /* magic number */ + int ras_width; /* width (pixels) of image */ + int ras_height; /* height (pixels) of image */ + int ras_depth; /* depth (1, 8, or 24 bits) of pixel */ + int ras_length; /* length (bytes) of image */ + int ras_type; /* type of file; see RT_* below */ + int ras_maptype; /* type of colormap; see RMT_* below */ + int ras_maplength; /* length (bytes) of following map */ + /* color map follows for ras_maplength bytes, followed by image */ +}; +#define RAS_MAGIC 0x59a66a95 + + /* Sun supported ras_type's */ +#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */ +#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */ +#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */ +#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */ + + /* Sun registered ras_maptype's */ +#define RMT_RAW 2 + /* Sun supported ras_maptype's */ +#define RMT_NONE 0 /* ras_maplength is expected to be 0 */ +#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */ + +/* + * NOTES: + * Each line of the image is rounded out to a multiple of 16 bits. + * This corresponds to the rounding convention used by the memory pixrect + * package (/usr/include/pixrect/memvar.h) of the SunWindows system. + * The ras_encoding field (always set to 0 by Sun's supported software) + * was renamed to ras_length in release 2.0. As a result, rasterfiles + * of type 0 generated by the old software claim to have 0 length; for + * compatibility, code reading rasterfiles must be prepared to compute the + * true length from the width, height, and depth fields. + */ diff --git a/tools/rgb2ycbcr.c b/tools/rgb2ycbcr.c new file mode 100644 index 00000000..1e43d37e --- /dev/null +++ b/tools/rgb2ycbcr.c @@ -0,0 +1,340 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/rgb2ycbcr.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcmp(a,b) == 0) +#define CopyField(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#define roundup(x, y) (howmany(x,y)*((uint32)(y))) + +#define LumaRed ycbcrCoeffs[0] +#define LumaGreen ycbcrCoeffs[1] +#define LumaBlue ycbcrCoeffs[2] + +uint16 compression = COMPRESSION_LZW; +uint32 rowsperstrip = (uint32) -1; + +uint16 horizSubSampling = 2; /* YCbCr horizontal subsampling */ +uint16 vertSubSampling = 2; /* YCbCr vertical subsampling */ +float ycbcrCoeffs[3] = { .299, .587, .114 }; +/* default coding range is CCIR Rec 601-1 with no headroom/footroom */ +float refBlackWhite[6] = { 0., 255., 128., 255., 128., 255. }; + +static int tiffcvt(TIFF* in, TIFF* out); +static void usage(void); +static void setupLumaTables(void); + +int +main(int argc, char* argv[]) +{ + TIFF *in, *out; + int c; + extern int optind; + extern char *optarg; + + while ((c = getopt(argc, argv, "c:h:r:v:z")) != -1) + switch (c) { + case 'c': + if (streq(optarg, "none")) + compression = COMPRESSION_NONE; + else if (streq(optarg, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (streq(optarg, "lzw")) + compression = COMPRESSION_LZW; + else if (streq(optarg, "jpeg")) + compression = COMPRESSION_JPEG; + else + usage(); + break; + case 'h': + horizSubSampling = atoi(optarg); + break; + case 'v': + vertSubSampling = atoi(optarg); + break; + case 'r': + rowsperstrip = atoi(optarg); + break; + case 'z': /* CCIR Rec 601-1 w/ headroom/footroom */ + refBlackWhite[0] = 16.; + refBlackWhite[1] = 235.; + refBlackWhite[2] = 128.; + refBlackWhite[3] = 240.; + refBlackWhite[4] = 128.; + refBlackWhite[5] = 240.; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind < 2) + usage(); + out = TIFFOpen(argv[argc-1], "w"); + if (out == NULL) + return (-2); + setupLumaTables(); + for (; optind < argc-1; optind++) { + in = TIFFOpen(argv[optind], "r"); + if (in != NULL) { + do { + if (!tiffcvt(in, out) || + !TIFFWriteDirectory(out)) { + (void) TIFFClose(out); + return (1); + } + } while (TIFFReadDirectory(in)); + (void) TIFFClose(in); + } + } + (void) TIFFClose(out); + return (0); +} + +float *lumaRed; +float *lumaGreen; +float *lumaBlue; +float D1, D2; +int Yzero; + +static float* +setupLuma(float c) +{ + float *v = (float *)_TIFFmalloc(256 * sizeof (float)); + int i; + for (i = 0; i < 256; i++) + v[i] = c * i; + return (v); +} + +static unsigned +V2Code(float f, float RB, float RW, int CR) +{ + unsigned int c = (unsigned int)((((f)*(RW-RB)/CR)+RB)+.5); + return (c > 255 ? 255 : c); +} + +static void +setupLumaTables(void) +{ + lumaRed = setupLuma(LumaRed); + lumaGreen = setupLuma(LumaGreen); + lumaBlue = setupLuma(LumaBlue); + D1 = 1./(2 - 2*LumaBlue); + D2 = 1./(2 - 2*LumaRed); + Yzero = V2Code(0, refBlackWhite[0], refBlackWhite[1], 255); +} + +static void +cvtClump(unsigned char* op, uint32* raster, uint32 ch, uint32 cw, uint32 w) +{ + float Y, Cb = 0, Cr = 0; + int j, k; + /* + * Convert ch-by-cw block of RGB + * to YCbCr and sample accordingly. + */ + for (k = 0; k < ch; k++) { + for (j = 0; j < cw; j++) { + uint32 RGB = (raster - k*w)[j]; + Y = lumaRed[TIFFGetR(RGB)] + + lumaGreen[TIFFGetG(RGB)] + + lumaBlue[TIFFGetB(RGB)]; + /* accumulate chrominance */ + Cb += (TIFFGetB(RGB) - Y) * D1; + Cr += (TIFFGetR(RGB) - Y) * D2; + /* emit luminence */ + *op++ = V2Code(Y, + refBlackWhite[0], refBlackWhite[1], 255); + } + for (; j < horizSubSampling; j++) + *op++ = Yzero; + } + for (; k < vertSubSampling; k++) { + for (j = 0; j < horizSubSampling; j++) + *op++ = Yzero; + } + /* emit sampled chrominance values */ + *op++ = V2Code(Cb / (ch*cw), refBlackWhite[2], refBlackWhite[3], 127); + *op++ = V2Code(Cr / (ch*cw), refBlackWhite[4], refBlackWhite[5], 127); +} +#undef LumaRed +#undef LumaGreen +#undef LumaBlue +#undef V2Code + +/* + * Convert a strip of RGB data to YCbCr and + * sample to generate the output data. + */ +static void +cvtStrip(unsigned char* op, uint32* raster, uint32 nrows, uint32 width) +{ + uint32 x; + int clumpSize = vertSubSampling * horizSubSampling + 2; + uint32 *tp; + + for (; nrows >= vertSubSampling; nrows -= vertSubSampling) { + tp = raster; + for (x = width; x >= horizSubSampling; x -= horizSubSampling) { + cvtClump(op, tp, + vertSubSampling, horizSubSampling, width); + op += clumpSize; + tp += horizSubSampling; + } + if (x > 0) { + cvtClump(op, tp, vertSubSampling, x, width); + op += clumpSize; + } + raster -= vertSubSampling*width; + } + if (nrows > 0) { + tp = raster; + for (x = width; x >= horizSubSampling; x -= horizSubSampling) { + cvtClump(op, tp, nrows, horizSubSampling, width); + op += clumpSize; + tp += horizSubSampling; + } + if (x > 0) + cvtClump(op, tp, nrows, x, width); + } +} + +static int +cvtRaster(TIFF* tif, uint32* raster, uint32 width, uint32 height) +{ + uint32 y; + tstrip_t strip = 0; + tsize_t cc, acc; + unsigned char* buf; + uint32 rwidth = roundup(width, horizSubSampling); + uint32 rheight = roundup(height, vertSubSampling); + uint32 nrows = (rowsperstrip > rheight ? rheight : rowsperstrip); + + cc = nrows*rwidth + + 2*((nrows*rwidth) / (horizSubSampling*vertSubSampling)); + buf = (unsigned char*)_TIFFmalloc(cc); + for (y = height; (int32) y > 0; y -= nrows) { + uint32 nr = (y > nrows ? nrows : y); + cvtStrip(buf, raster + (y-1)*width, nr, width); + nr = roundup(nr, vertSubSampling); + acc = nr*rwidth + + 2*((nr*rwidth)/(horizSubSampling*vertSubSampling)); + if (!TIFFWriteEncodedStrip(tif, strip++, buf, acc)) { + _TIFFfree(buf); + return (0); + } + } + _TIFFfree(buf); + return (1); +} + +static int +tiffcvt(TIFF* in, TIFF* out) +{ + uint32 width, height; /* image width & height */ + uint32* raster; /* retrieve RGBA image */ + uint16 shortv; + float floatv; + char *stringv; + uint32 longv; + + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); + raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); + if (raster == 0) { + TIFFError(TIFFFileName(in), "No space for raster buffer"); + return (0); + } + if (!TIFFReadRGBAImage(in, width, height, raster, 0)) { + _TIFFfree(raster); + return (0); + } + + CopyField(TIFFTAG_SUBFILETYPE, longv); + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); + if (compression == COMPRESSION_JPEG) + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); + CopyField(TIFFTAG_FILLORDER, shortv); + TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); + CopyField(TIFFTAG_XRESOLUTION, floatv); + CopyField(TIFFTAG_YRESOLUTION, floatv); + CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + { char buf[2048]; + char *cp = strrchr(TIFFFileName(in), '/'); + sprintf(buf, "YCbCr conversion of %s", cp ? cp+1 : TIFFFileName(in)); + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, buf); + } + TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion()); + CopyField(TIFFTAG_DOCUMENTNAME, stringv); + + TIFFSetField(out, TIFFTAG_REFERENCEBLACKWHITE, refBlackWhite); + TIFFSetField(out, TIFFTAG_YCBCRSUBSAMPLING, + horizSubSampling, vertSubSampling); + TIFFSetField(out, TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED); + TIFFSetField(out, TIFFTAG_YCBCRCOEFFICIENTS, ycbcrCoeffs); + rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + + return (cvtRaster(out, raster, width, height)); +} + +static char* usageMsg[] = { + "usage: rgb2ycbcr [-c comp] [-r rows] [-h N] [-v N] input... output\n", + "where comp is one of the following compression algorithms:\n", + " jpeg\t\tJPEG encoding\n", + " lzw\t\tLempel-Ziv & Welch encoding\n", + " packbits\tPackBits encoding\n", + " none\t\tno compression\n", + "and the other options are:\n", + " -r\trows/strip\n", + " -h\thorizontal sampling factor (1,2,4)\n", + " -v\tvertical sampling factor (1,2,4)\n", + NULL +}; + +static void +usage(void) +{ + int i; + for (i = 0; usageMsg[i]; i++) + fprintf(stderr, "%s", usageMsg[i]); + exit(-1); +} diff --git a/tools/sgi2tiff.c b/tools/sgi2tiff.c new file mode 100644 index 00000000..49e76b44 --- /dev/null +++ b/tools/sgi2tiff.c @@ -0,0 +1,320 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/sgi2tiff.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1991-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +static short config = PLANARCONFIG_CONTIG; +static uint16 compression = COMPRESSION_LZW; +static uint16 predictor = 0; +static uint16 fillorder = 0; +static uint32 rowsperstrip = (uint32) -1; +static int jpegcolormode = JPEGCOLORMODE_RGB; +static int quality = 75; /* JPEG quality */ +static uint16 photometric; + +static void usage(void); +static int cpContig(IMAGE*, TIFF*); +static int cpSeparate(IMAGE*, TIFF*); +static int processCompressOptions(char*); + +/* XXX image library has no prototypes */ +extern IMAGE* iopen(const char*, const char*); +extern void iclose(IMAGE*); +extern void getrow(IMAGE*, short*, int, int); + +int +main(int argc, char* argv[]) +{ + IMAGE *in; + TIFF *out; + int c; + extern int optind; + extern char* optarg; + + while ((c = getopt(argc, argv, "c:p:r:")) != -1) + switch (c) { + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'f': /* fill order */ + if (streq(optarg, "lsb2msb")) + fillorder = FILLORDER_LSB2MSB; + else if (streq(optarg, "msb2lsb")) + fillorder = FILLORDER_MSB2LSB; + else + usage(); + break; + case 'p': /* planar configuration */ + if (streq(optarg, "separate")) + config = PLANARCONFIG_SEPARATE; + else if (streq(optarg, "contig")) + config = PLANARCONFIG_CONTIG; + else + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind != 2) + usage(); + in = iopen(argv[optind], "r"); + if (in == NULL) + return (-1); + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-2); + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) in->xsize); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) in->ysize); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + if (in->zsize == 1) + photometric = PHOTOMETRIC_MINISBLACK; + else + photometric = PHOTOMETRIC_RGB; + switch (compression) { + case COMPRESSION_JPEG: + if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB) + photometric = PHOTOMETRIC_YCBCR; + TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric); + if (fillorder != 0) + TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); + TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, in->zsize); + if (in->zsize > 3) { + uint16 v[1]; + v[0] = EXTRASAMPLE_UNASSALPHA; + TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v); + } + TIFFSetField(out, TIFFTAG_MINSAMPLEVALUE, (uint16) in->min); + TIFFSetField(out, TIFFTAG_MAXSAMPLEVALUE, (uint16) in->max); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, config); + if (config != PLANARCONFIG_SEPARATE) + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + else /* force 1 row/strip for library limitation */ + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1L); + if (in->name[0] != '\0') + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, in->name); + if (config == PLANARCONFIG_CONTIG) + cpContig(in, out); + else + cpSeparate(in, out); + (void) iclose(in); + (void) TIFFClose(out); + return (0); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "jpeg", 4)) { + char* cp = strchr(opt, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + compression = COMPRESSION_JPEG; + } else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +static int +cpContig(IMAGE* in, TIFF* out) +{ + tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out)); + short *r = NULL; + int x, y; + + if (in->zsize == 3) { + short *g, *b; + + r = (short *)_TIFFmalloc(3 * in->xsize * sizeof (short)); + g = r + in->xsize; + b = g + in->xsize; + for (y = in->ysize-1; y >= 0; y--) { + uint8* pp = (uint8*) buf; + + getrow(in, r, y, 0); + getrow(in, g, y, 1); + getrow(in, b, y, 2); + for (x = 0; x < in->xsize; x++) { + pp[0] = r[x]; + pp[1] = g[x]; + pp[2] = b[x]; + pp += 3; + } + if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0) + goto bad; + } + } else if (in->zsize == 4) { + short *g, *b, *a; + + r = (short *)_TIFFmalloc(4 * in->xsize * sizeof (short)); + g = r + in->xsize; + b = g + in->xsize; + a = b + in->xsize; + for (y = in->ysize-1; y >= 0; y--) { + uint8* pp = (uint8*) buf; + + getrow(in, r, y, 0); + getrow(in, g, y, 1); + getrow(in, b, y, 2); + getrow(in, a, y, 3); + for (x = 0; x < in->xsize; x++) { + pp[0] = r[x]; + pp[1] = g[x]; + pp[2] = b[x]; + pp[3] = a[x]; + pp += 4; + } + if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0) + goto bad; + } + } else { + uint8* pp = (uint8*) buf; + + r = (short *)_TIFFmalloc(in->xsize * sizeof (short)); + for (y = in->ysize-1; y >= 0; y--) { + getrow(in, r, y, 0); + for (x = in->xsize-1; x >= 0; x--) + pp[x] = r[x]; + if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0) + goto bad; + } + } + if (r) + _TIFFfree(r); + _TIFFfree(buf); + return (1); +bad: + if (r) + _TIFFfree(r); + _TIFFfree(buf); + return (0); +} + +static int +cpSeparate(IMAGE* in, TIFF* out) +{ + tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out)); + short *r = (short *)_TIFFmalloc(in->xsize * sizeof (short)); + uint8* pp = (uint8*) buf; + int x, y, z; + + for (z = 0; z < in->zsize; z++) { + for (y = in->ysize-1; y >= 0; y--) { + getrow(in, r, y, z); + for (x = 0; x < in->xsize; x++) + pp[x] = r[x]; + if (TIFFWriteScanline(out, buf, in->ysize-y-1, z) < 0) + goto bad; + } + } + _TIFFfree(r); + _TIFFfree(buf); + return (1); +bad: + _TIFFfree(r); + _TIFFfree(buf); + return (0); +} + +char* stuff[] = { +"usage: sgi2tiff [options] input.rgb output.tif", +"where options are:", +" -r # make each strip have no more than # rows", +"", +" -p contig pack samples contiguously (e.g. RGBRGB...)", +" -p separate store samples separately (e.g. RRR...GGG...BBB...)", +"", +" -f lsb2msb force lsb-to-msb FillOrder for output", +" -f msb2lsb force msb-to-lsb FillOrder for output", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c jpeg[:opts]compress output with JPEG encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"JPEG options:", +" # set compression quality level (0-100, default 75)", +" r output color image as RGB rather than YCbCr", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/sgigt.c b/tools/sgigt.c new file mode 100644 index 00000000..fd4d009b --- /dev/null +++ b/tools/sgigt.c @@ -0,0 +1,984 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/sgigt.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#include +#include + +#include "tiffio.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +/* XXX fudge adjustment for window borders */ +#define YFUDGE 20 +#define XFUDGE 20 + +static tileContigRoutine putContig; +static tileSeparateRoutine putSeparate; +static uint32 width, height; /* window width & height */ +static uint32* raster = NULL; /* displayable image */ + +extern Colorindex greyi(int); +static void setupColormapSupport(TIFFRGBAImage*); +static void putContigAndDraw(TIFFRGBAImage*, uint32*, + uint32, uint32, uint32, uint32, int32, int32, unsigned char*); +static void putSeparateAndDraw(TIFFRGBAImage*, uint32*, + uint32, uint32, uint32, uint32, int32, int32, + unsigned char*, unsigned char*, unsigned char*, unsigned char*); + +static int prevImage(char* argv[], int ix, int b, int e, int wrap); +static int nextImage(char* argv[], int ix, int b, int e, int wrap); +static void usage(void); +static uint16 photoArg(const char*); +static void beep(void); + +extern char* optarg; +extern int optind; + +int +main(int argc, char* argv[]) +{ + static Cursor hourglass = { + 0x1ff0, 0x1ff0, 0x0820, 0x0820, + 0x0820, 0x0c60, 0x06c0, 0x0100, + 0x0100, 0x06c0, 0x0c60, 0x0820, + 0x0820, 0x0820, 0x1ff0, 0x1ff0 + }; + int isRGB0 = -1, isRGB; + int verbose = 0; + int stoponerr = 0; /* stop on read error */ + char* filename; + TIFF* tif = NULL; + int fg = 0; + int c; + int dirnum = -1; + int order0 = 0, order; + uint32 diroff = 0; + uint16 photo0 = (uint16) -1, photo; + long x, y, xmax, ymax; + int ix, nix; + TIFFErrorHandler oerror = TIFFSetErrorHandler(NULL); + TIFFErrorHandler owarning = TIFFSetWarningHandler(NULL); + uint32 w, h; + long wid = -1; + + while ((c = getopt(argc, argv, "d:o:p:cerflmsvw")) != -1) + switch (c) { + case 'c': + isRGB0 = 0; + break; + case 'd': + dirnum = atoi(optarg); + break; + case 'e': + oerror = TIFFSetErrorHandler(oerror); + break; + case 'f': + fg = 1; + break; + case 'l': + order0 = FILLORDER_LSB2MSB; + break; + case 'm': + order0 = FILLORDER_MSB2LSB; + break; + case 'o': + diroff = strtoul(optarg, NULL, 0); + break; + case 'p': + photo0 = photoArg(optarg); + break; + case 'r': + isRGB0 = 1; + break; + case 's': + stoponerr = 1; + break; + case 'w': + owarning = TIFFSetWarningHandler(owarning); + break; + case 'v': + verbose = 1; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind < 1) + usage(); + xmax = getgdesc(GD_XPMAX) - XFUDGE; + ymax = getgdesc(GD_YPMAX) - YFUDGE; + ix = optind; + do { + tif = TIFFOpen(argv[ix], "r"); + } while (tif == NULL && (ix = nextImage(argv, ix, optind, argc, FALSE))); + if (tif == NULL) + exit(0); + if (ix == optind) { + /* + * Set initial directory if user-specified + * file was opened successfully. + */ + if (dirnum != -1 && !TIFFSetDirectory(tif, dirnum)) + TIFFError(argv[ix], "Error, seeking to directory %d", dirnum); + if (diroff != 0 && !TIFFSetSubDirectory(tif, diroff)) + TIFFError(argv[ix], "Error, setting subdirectory at %#x", diroff); + } + isRGB = isRGB0; + order = order0; + photo = photo0; + goto newfile0; + for (;;) { + TIFFRGBAImage img; + char title[1024]; /* window title line */ + const char* cp; + int isrgb; + + if (order) + TIFFSetField(tif, TIFFTAG_FILLORDER, order); + if (photo != (uint16) -1) + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photo); + if (!TIFFRGBAImageBegin(&img, tif, stoponerr, title)) { + TIFFError(filename, title); + goto bad2; + } + /* + * Use a full-color window if the image is + * full color or a palette image and the + * hardware support is present. + */ + isrgb = isRGB; + if (isrgb == -1) + isrgb = (img.bitspersample >= 8 && + (img.photometric == PHOTOMETRIC_RGB || + img.photometric == PHOTOMETRIC_YCBCR || + img.photometric == PHOTOMETRIC_SEPARATED || + img.photometric == PHOTOMETRIC_PALETTE || + img.photometric == PHOTOMETRIC_LOGLUV)); + /* + * Check to see if the hardware can display 24-bit RGB. + */ + if (isrgb && getgdesc(GD_BITS_NORM_SNG_RED) < img.bitspersample && + !getgdesc(GD_DITHER)) { + if (verbose) + printf("Warning, display is incapable of full RGB,%s\n", + " using dithered colormap"); + isrgb = 0; + } + /* + * Colormap-based display is done by overriding the put + * routine to install a private method that understands + * how to convert RGBA values to suitable colormap indices. + */ + if (!isrgb) + setupColormapSupport(&img); + /* + * Override default ``put routine'' with private + * routine that also draws the raster on the display. + */ + if (img.put.any == 0) { + TIFFError(filename, + "No \"put\" routine; must not handle image format"); + goto bad3; + } + if (img.isContig) { + putContig = img.put.contig; + img.put.contig = putContigAndDraw; + } else { + putSeparate = img.put.separate; + img.put.separate = putSeparateAndDraw; + } + /* + * Setup the image raster as required. + */ + if ((w = img.width) > xmax) + w = xmax; + if ((h = img.height) > ymax) + h = ymax; + if (w != width || h != height) { + if (raster != NULL) + _TIFFfree(raster), raster = NULL; + raster = (uint32*) _TIFFmalloc(w * h * sizeof (uint32)); + if (raster == NULL) { + width = height = 0; + TIFFError(filename, "No space for raster buffer"); + goto bad3; + } + width = w; + height = h; + } + /* + * Create a new window or reconfigure an existing + * one to suit the image to be displayed. + */ + if (wid < 0) { + x = (xmax+XFUDGE-width)/2; + y = (ymax+YFUDGE-height)/2; + prefposition(x, x+width-1, y, y+height-1); + cp = strrchr(filename, '/'); + sprintf(title, "%s [%u] %s", + cp == NULL ? filename : cp+1, + (unsigned int) TIFFCurrentDirectory(tif), + isrgb ? " rgb" : " cmap"); + if (fg) + foreground(); + wid = winopen(title); + if (wid < 0) { + TIFFError(filename, "Can not create window"); + TIFFRGBAImageEnd(&img); + break; + } + curstype(C16X1); + defcursor(1, hourglass); + qdevice(LEFTMOUSE); + qdevice(MIDDLEMOUSE); + qdevice(RIGHTMOUSE); + qdevice(KEYBD); + qdevice(PAGEUPKEY); + qdevice(PAGEDOWNKEY); + qdevice(HOMEKEY); + qdevice(ENDKEY); + } else { + x = (xmax+XFUDGE-width)/2; + y = (ymax+YFUDGE-height)/2; + winposition(x, x+width-1, y, y+height-1); + viewport(0, width-1, 0, height-1); + cp = strrchr(filename, '/'); + sprintf(title, "%s [%u] %s", + cp == NULL ? filename : cp+1, + (unsigned int) TIFFCurrentDirectory(tif), + isrgb ? " rgb" : " cmap"); + wintitle(title); + } + singlebuffer(); + if (isrgb) { + RGBmode(); + gconfig(); + } else { + cmode(); + gconfig(); + } + /* + * Fetch the image. + */ + setcursor(1, 0, 0); + greyi(225); + clear(); + (void) TIFFRGBAImageGet(&img, raster, width, height); + setcursor(0, 0, 0); + /* + * Process input. + */ + for (;;) { + short val; + switch (qread(&val)) { + case KEYBD: + switch (val) { + case 'b': /* photometric MinIsBlack */ + photo = PHOTOMETRIC_MINISBLACK; + goto newpage; + case 'l': /* lsb-to-msb FillOrder */ + order = FILLORDER_LSB2MSB; + goto newpage; + case 'm': /* msb-to-lsb FillOrder */ + order = FILLORDER_MSB2LSB; + goto newpage; + case 'c': /* colormap visual */ + isRGB = 0; + goto newpage; + case 'r': /* RGB visual */ + isRGB = 1; + goto newpage; + case 'w': /* photometric MinIsWhite */ + photo = PHOTOMETRIC_MINISWHITE; + goto newpage; + case 'W': /* toggle warnings */ + owarning = TIFFSetWarningHandler(owarning); + goto newpage; + case 'E': /* toggle errors */ + oerror = TIFFSetErrorHandler(oerror); + goto newpage; + case 'z': /* reset to defaults */ + case 'Z': + order = order0; + photo = photo0; + isRGB = isRGB0; + if (owarning == NULL) + owarning = TIFFSetWarningHandler(NULL); + if (oerror == NULL) + oerror = TIFFSetErrorHandler(NULL); + goto newpage; + case 'q': /* exit */ + case '\033': + TIFFRGBAImageEnd(&img); + goto done; + } + break; + case PAGEUPKEY: /* previous logical image */ + if (val) { + if (TIFFCurrentDirectory(tif) > 0) { + if (TIFFSetDirectory(tif, TIFFCurrentDirectory(tif)-1)) + goto newpage; + beep(); /* XXX */ + } else { + ix = prevImage(argv, ix, optind, argc, TRUE); + /* XXX set directory to last image in new file */ + goto newfile; + } + } + break; + case PAGEDOWNKEY: /* next logical image */ + if (val) { + if (!TIFFLastDirectory(tif)) { + if (TIFFReadDirectory(tif)) + goto newpage; + beep(); /* XXX */ + } else { + ix = nextImage(argv, ix, optind, argc, TRUE); + goto newfile; + } + } + break; + case HOMEKEY: /* 1st image in current file */ + if (val) { + if (TIFFSetDirectory(tif, 0)) + goto newpage; + beep(); + } + break; + case ENDKEY: /* last image in current file */ + if (val) { + /* XXX */ + beep(); + } + break; + case RIGHTMOUSE: /* previous file */ + if (val) { + if (nix = prevImage(argv, ix, optind, argc, FALSE)) { + ix = nix; + goto newfile; + } + beep(); + } + break; + case LEFTMOUSE: /* next file */ + if (val) { + if (nix = nextImage(argv, ix, optind, argc, FALSE)) { + ix = nix; + goto newfile; + } + beep(); + } + break; + case MIDDLEMOUSE: /* first file */ + if (val) { + if (nix = nextImage(argv, optind-1, optind, argc, FALSE)) { + ix = nix; + goto newfile; + } + beep(); + } + break; + case REDRAW: + lrectwrite(0, 0, width-1, height-1, raster); + break; + } + } + newfile: + TIFFRGBAImageEnd(&img); + if (tif != NULL && argv[ix] != filename) + TIFFClose(tif), tif = NULL; + /* fall thru... */ + newfile0: + if (argv[ix] == NULL) + break; + filename = argv[ix]; + if (tif == NULL) { + tif = TIFFOpen(filename, "r"); + if (tif == NULL) + goto bad1; + isRGB = isRGB0; + order = order0; + photo = photo0; + } + continue; + newpage: + TIFFRGBAImageEnd(&img); + continue; + bad3: + TIFFRGBAImageEnd(&img); + bad2: + TIFFClose(tif), tif = NULL; + bad1: + argv[ix] = NULL; /* don't revisit file */ + ix = nextImage(argv, ix, optind, argc, TRUE); + goto newfile0; + } +done: + if (wid >= 0) + winclose(wid); + if (raster != NULL) + _TIFFfree(raster); + if (tif != NULL) + TIFFClose(tif); + return (0); +} + +static int +prevImage(char* argv[], int ix, int b, int e, int wrap) +{ + int i; + + for (i = ix-1; i >= b && argv[i] == NULL; i--) + ; + if (i < b) { + if (wrap) { + for (i = e-1; i > ix && argv[i] == NULL; i--) + ; + } else + i = 0; + } + return (i); +} + +static int +nextImage(char* argv[], int ix, int b, int e, int wrap) +{ + int i; + + for (i = ix+1; i < e && argv[i] == NULL; i++) + ; + if (i >= e) { + if (wrap) { + for (i = b; i < ix && argv[i] == NULL; i++) + ; + } else + i = 0; + } + return (i); +} + +static void +beep(void) +{ + greyi(0); + clear(); + sginap(5); + lrectwrite(0, 0, width-1, height-1, raster); +} + +char* stuff[] = { +"usage: tiffgt [options] file.tif", +"where options are:", +" -c use colormap visual", +" -d dirnum set initial directory (default is 0)", +" -e enable display of TIFF error messages", +" -f run program in the foreground", +" -l force lsb-to-msb FillOrder", +" -m force msb-to-lsb FillOrder", +" -o offset set initial directory offset", +" -p photo override photometric interpretation", +" -r use fullcolor visual", +" -s stop decoding on first error (default is ignore errors)", +" -v enable verbose mode", +" -w enable display of TIFF warning messages", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} + +static uint16 +photoArg(const char* arg) +{ + if (strcmp(arg, "miniswhite") == 0) + return (PHOTOMETRIC_MINISWHITE); + else if (strcmp(arg, "minisblack") == 0) + return (PHOTOMETRIC_MINISBLACK); + else if (strcmp(arg, "rgb") == 0) + return (PHOTOMETRIC_RGB); + else if (strcmp(arg, "palette") == 0) + return (PHOTOMETRIC_PALETTE); + else if (strcmp(arg, "mask") == 0) + return (PHOTOMETRIC_MASK); + else if (strcmp(arg, "separated") == 0) + return (PHOTOMETRIC_SEPARATED); + else if (strcmp(arg, "ycbcr") == 0) + return (PHOTOMETRIC_YCBCR); + else if (strcmp(arg, "cielab") == 0) + return (PHOTOMETRIC_CIELAB); + else if (strcmp(arg, "logl") == 0) + return (PHOTOMETRIC_LOGL); + else if (strcmp(arg, "logluv") == 0) + return (PHOTOMETRIC_LOGLUV); + else + return ((uint16) -1); +} + +static void +putContigAndDraw(TIFFRGBAImage* img, uint32* raster, + uint32 x, uint32 y, uint32 w, uint32 h, + int32 fromskew, int32 toskew, + unsigned char* cp) +{ + (*putContig)(img, raster, x, y, w, h, fromskew, toskew, cp); + if (x+w == width) { + w = width; + if (img->orientation == ORIENTATION_TOPLEFT) + lrectwrite(0, y-(h-1), w-1, y, raster-x-(h-1)*w); + else + lrectwrite(0, y, w-1, y+h-1, raster); + } +} + +static void +putSeparateAndDraw(TIFFRGBAImage* img, uint32* raster, + uint32 x, uint32 y, uint32 w, uint32 h, + int32 fromskew, int32 toskew, + unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a) +{ + (*putSeparate)(img, raster, x, y, w, h, fromskew, toskew, r, g, b, a); + if (x+w == width) { + w = width; + if (img->orientation == ORIENTATION_TOPLEFT) + lrectwrite(0, y-(h-1), w-1, y, raster-x-(h-1)*w); + else + lrectwrite(0, y, w-1, y+h-1, raster); + } +} + +/* + * {red,green,blue}_inverse are tables in libgutil.a that + * do an inverse map from (r,g,b) to the closest colormap + * index in the "standard" GL colormap. grey_inverse is + * the equivalent map for mapping greyscale values to + * colormap indices. We access these maps directly instead + * of through the rgbi and greyi functions to avoid the + * additional overhead of the color calls that they make. + */ +extern u_char red_inverse[256]; +extern u_char green_inverse[256]; +extern u_char blue_inverse[256]; +extern u_char grey_inverse[256]; +#define greyi(g) grey_inverse[g] + +static u_char +rgbi(u_char r, u_char g, u_char b) +{ + return (r == g && g == b ? grey_inverse[r] : + red_inverse[r] + green_inverse[g] + blue_inverse[b]); +} + +/* + * The following routines move decoded data returned + * from the TIFF library into rasters that are suitable + * for passing to lrecwrite. They do the necessary + * conversions for when a colormap drawing mode is used. + */ +#define REPEAT8(op) REPEAT4(op); REPEAT4(op) +#define REPEAT4(op) REPEAT2(op); REPEAT2(op) +#define REPEAT2(op) op; op +#define CASE8(x,op) \ + switch (x) { \ + case 7: op; case 6: op; case 5: op; \ + case 4: op; case 3: op; case 2: op; \ + case 1: op; \ + } +#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; } +#define NOP + +#define UNROLL8(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 8; _x -= 8) { \ + op1; \ + REPEAT8(op2); \ + } \ + if (_x > 0) { \ + op1; \ + CASE8(_x,op2); \ + } \ +} +#define UNROLL4(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 4; _x -= 4) { \ + op1; \ + REPEAT4(op2); \ + } \ + if (_x > 0) { \ + op1; \ + CASE4(_x,op2); \ + } \ +} +#define UNROLL2(w, op1, op2) { \ + uint32 _x; \ + for (_x = w; _x >= 2; _x -= 2) { \ + op1; \ + REPEAT2(op2); \ + } \ + if (_x) { \ + op1; \ + op2; \ + } \ +} + +#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } + +#define DECLAREContigPutFunc(name) \ +static void name(\ + TIFFRGBAImage* img, \ + uint32* cp, \ + uint32 x, uint32 y, \ + uint32 w, uint32 h, \ + int32 fromskew, int32 toskew, \ + u_char* pp \ +) + +#define DECLARESepPutFunc(name) \ +static void name(\ + TIFFRGBAImage* img,\ + uint32* cp,\ + uint32 x, uint32 y, \ + uint32 w, uint32 h,\ + int32 fromskew, int32 toskew,\ + u_char* r, u_char* g, u_char* b, u_char* a\ +) + +static tileContigRoutine libput; + +/* + * 8-bit packed samples => colormap + */ +DECLAREContigPutFunc(putcontig8bittile) +{ + int samplesperpixel = img->samplesperpixel; + TIFFRGBValue* Map = img->Map; + + (void) y; + fromskew *= samplesperpixel; + if (Map) { + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = rgbi(Map[pp[0]], Map[pp[1]], Map[pp[2]]); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } + } else { + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = rgbi(pp[0], pp[1], pp[2]); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } + } +} + +/* + * Convert 8-bit packed samples => colormap + */ +DECLAREContigPutFunc(cvtcontig8bittile) +{ + (*libput)(img, cp, x, y, w, h, fromskew, toskew, pp); + while (h-- > 0) { + UNROLL8(w, NOP, + cp[0] = rgbi(TIFFGetR(cp[0]),TIFFGetG(cp[0]),TIFFGetB(cp[0])); cp++ + ); + cp += toskew; + } +} + +/* + * 16-bit packed samples => colormap + */ +DECLAREContigPutFunc(putcontig16bittile) +{ + int samplesperpixel = img->samplesperpixel; + TIFFRGBValue* Map = img->Map; + + (void) y; + fromskew *= samplesperpixel; + if (Map) { + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = rgbi(Map[pp[0]], Map[pp[1]], Map[pp[2]]); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } + } else { + while (h-- > 0) { + for (x = w; x-- > 0;) { + *cp++ = rgbi(pp[0], pp[1], pp[2]); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } + } +} + +/* + * 8-bit unpacked samples => colormap + */ +DECLARESepPutFunc(putseparate8bittile) +{ + TIFFRGBValue* Map = img->Map; + + (void) y; (void) a; + if (Map) { + while (h-- > 0) { + for (x = w; x-- > 0;) + *cp++ = rgbi(Map[*r++], Map[*g++], Map[*b++]); + SKEW(r, g, b, fromskew); + cp += toskew; + } + } else { + while (h-- > 0) { + for (x = w; x-- > 0;) + *cp++ = rgbi(*r++, *g++, *b++); + SKEW(r, g, b, fromskew); + cp += toskew; + } + } +} + +/* + * 16-bit unpacked samples => colormap + */ +DECLARESepPutFunc(putseparate16bittile) +{ + TIFFRGBValue* Map = img->Map; + + (void) y; (void) a; + if (Map) { + while (h-- > 0) { + for (x = 0; x < w; x++) + *cp++ = rgbi(Map[*r++], Map[*g++], Map[*b++]); + SKEW(r, g, b, fromskew); + cp += toskew; + } + } else { + while (h-- > 0) { + for (x = 0; x < w; x++) + *cp++ = rgbi(*r++, *g++, *b++); + SKEW(r, g, b, fromskew); + cp += toskew; + } + } +} + +/* + * 8-bit packed CMYK samples => cmap + * + * NB: The conversion of CMYK->RGB is *very* crude. + */ +DECLAREContigPutFunc(putcontig8bitCMYKtile) +{ + int samplesperpixel = img->samplesperpixel; + TIFFRGBValue* Map = img->Map; + uint16 r, g, b, k; + + (void) y; + fromskew *= samplesperpixel; + if (Map) { + while (h-- > 0) { + for (x = w; x-- > 0;) { + k = 255 - pp[3]; + r = (k*(255-pp[0]))/255; + g = (k*(255-pp[1]))/255; + b = (k*(255-pp[2]))/255; + *cp++ = rgbi(Map[r], Map[g], Map[b]); + pp += samplesperpixel; + } + pp += fromskew; + cp += toskew; + } + } else { + while (h-- > 0) { + UNROLL8(w, NOP, + k = 255 - pp[3]; + r = (k*(255-pp[0]))/255; + g = (k*(255-pp[1]))/255; + b = (k*(255-pp[2]))/255; + *cp++ = rgbi(r, g, b); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; + } + } +} + +#define YCbCrtoRGB(dst, yc) { \ + int Y = (yc); \ + dst = rgbi( \ + clamptab[Y+Crrtab[Cr]], \ + clamptab[Y + (int)((Cbgtab[Cb]+Crgtab[Cr])>>16)], \ + clamptab[Y+Cbbtab[Cb]]); \ +} +#define YCbCrSetup \ + TIFFYCbCrToRGB* ycbcr = img->ycbcr; \ + int* Crrtab = ycbcr->Cr_r_tab; \ + int* Cbbtab = ycbcr->Cb_b_tab; \ + int32* Crgtab = ycbcr->Cr_g_tab; \ + int32* Cbgtab = ycbcr->Cb_g_tab; \ + TIFFRGBValue* clamptab = ycbcr->clamptab + +/* + * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB + */ +DECLAREContigPutFunc(putcontig8bitYCbCr22tile) +{ + YCbCrSetup; + uint32* cp1 = cp+w+toskew; + int32 incr = 2*toskew+w; + + (void) y; + /* XXX adjust fromskew */ + for (; h >= 2; h -= 2) { + x = w>>1; + do { + int Cb = pp[4]; + int Cr = pp[5]; + + YCbCrtoRGB(cp [0], pp[0]); + YCbCrtoRGB(cp [1], pp[1]); + YCbCrtoRGB(cp1[0], pp[2]); + YCbCrtoRGB(cp1[1], pp[3]); + + cp += 2, cp1 += 2; + pp += 6; + } while (--x); + cp += incr, cp1 += incr; + pp += fromskew; + } +} +#undef YCbCrSetup +#undef YCbCrtoRGB + +/* + * Setup to handle conversion for display in a colormap + * window. Many cases are handled by massaging the mapping + * tables used by the normal library code to convert 32-bit + * packed RGBA samples into colormap indices. Other cases + * are handled with special-case routines that replace the + * normal ``put routine'' installed by the library. + */ +static void +setupColormapSupport(TIFFRGBAImage* img) +{ + int bitspersample = img->bitspersample; + int i; + + if (img->BWmap) { + i = 255; + do { + uint32* p = img->BWmap[i]; + switch (bitspersample) { +#define GREY(x) p[x] = greyi(TIFFGetR(p[x])) + case 1: GREY(7); GREY(6); GREY(5); GREY(4); + case 2: GREY(3); GREY(2); + case 4: GREY(1); + case 8: GREY(0); + } +#undef GREY + } while (i--); + } else if (img->PALmap) { + i = 255; + do { + uint32 rgb; + uint32* p = img->PALmap[i]; +#define CMAP(x) \ + (rgb = p[x], p[x] = rgbi(TIFFGetR(rgb),TIFFGetG(rgb),TIFFGetB(rgb))) + switch (bitspersample) { + case 1: CMAP(7); CMAP(6); CMAP(5); CMAP(4); + case 2: CMAP(3); CMAP(2); + case 4: CMAP(1); + case 8: CMAP(0); + } +#undef CMAP + } while (i--); + } else if (img->isContig) { + switch (img->photometric) { + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_LOGLUV: + switch (bitspersample) { + case 8: img->put.contig = putcontig8bittile; break; + case 16: img->put.contig = putcontig16bittile; break; + } + break; + case PHOTOMETRIC_SEPARATED: + switch (bitspersample) { + case 8: img->put.contig = putcontig8bitCMYKtile; break; + } + break; + case PHOTOMETRIC_YCBCR: + if (img->bitspersample == 8) { + uint16 hs, vs; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, + &hs, &vs); + switch ((hs<<4)|vs) { + case 0x22: /* most common case */ + img->put.contig = putcontig8bitYCbCr22tile; + break; + default: /* all others cost more */ + libput = img->put.contig; + img->put.contig = cvtcontig8bittile; + break; + } + } + break; + } + } else { + switch (img->photometric) { + case PHOTOMETRIC_RGB: + switch (img->bitspersample) { + case 8: img->put.separate = putseparate8bittile; break; + case 16: img->put.separate = putseparate16bittile; break; + } + break; + } + } +} diff --git a/tools/sgisv.c b/tools/sgisv.c new file mode 100644 index 00000000..cb0e0c53 --- /dev/null +++ b/tools/sgisv.c @@ -0,0 +1,309 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/Attic/sgisv.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1990-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#include "tiffio.h" + +typedef unsigned char u_char; +typedef unsigned long u_long; + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +uint32 rowsperstrip = (uint32) -1; +uint16 compression = COMPRESSION_LZW; +uint16 config = PLANARCONFIG_CONTIG; +uint16 predictor = 0; +int xmaxscreen; +int ymaxscreen; +uint16 photometric = PHOTOMETRIC_RGB; +int jpegcolormode = JPEGCOLORMODE_RGB; +int quality = 75; /* JPEG quality */ + +static void usage(void); +static void tiffsv(char*, int, int, int, int); + +int +main(int argc, char* argv[]) +{ + int c; + extern int optind; + extern char* optarg; + + while ((c = getopt(argc, argv, "c:p:r:")) != -1) + switch (c) { + case 'b': /* save as b&w */ + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 'c': /* compression scheme */ + if (streq(optarg, "none")) + compression = COMPRESSION_NONE; + else if (streq(optarg, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(optarg, "jpeg", 4)) { + char* cp = strchr(optarg, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + compression = COMPRESSION_JPEG; + } else if (strneq(optarg, "lzw", 3)) { + char* cp = strchr(optarg, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else + usage(); + break; + case 'p': /* planar configuration */ + if (streq(optarg, "separate")) + config = PLANARCONFIG_SEPARATE; + else if (streq(optarg, "contig")) + config = PLANARCONFIG_CONTIG; + else + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind != 1 && argc - optind != 5) + usage(); + xmaxscreen = getgdesc(GD_XPMAX)-1; + ymaxscreen = getgdesc(GD_YPMAX)-1; + foreground(); + noport(); + winopen("tiffsv"); + if (argc - optind == 5) + tiffsv(argv[optind], + atoi(argv[optind+1]), atoi(argv[optind+2]), + atoi(argv[optind+3]), atoi(argv[optind+4])); + else + tiffsv(argv[optind], 0, xmaxscreen, 0, ymaxscreen); + return (0); +} + +char* stuff[] = { +"usage: tiffsv [options] outimage.tif [x1 x2 y1 y2] [-b]", +"where options are:", +" -p contig pack samples contiguously (e.g. RGBRGB...)", +" -p separate store samples separately (e.g. RRR...GGG...BBB...)", +"", +" -r # make each strip have no more than # rows", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c jpeg[:opts]compress output with JPEG encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"JPEG options:", +" # set compression quality level (0-100, default 75)", +" r output color image as RGB rather than YCbCr", +"", +"LZW options:", +" # set predictor value for Lempel-Ziv & Welch encoding", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} + +static void +svRGBSeparate(TIFF* tif, u_long* ss, int xsize, int ysize) +{ + tsize_t stripsize = TIFFStripSize(tif); + u_char *rbuf = (u_char *)_TIFFmalloc(3*stripsize); + u_char *gbuf = rbuf + stripsize; + u_char *bbuf = gbuf + stripsize; + register int y; + + for (y = 0; y <= ysize; y += rowsperstrip) { + u_char *rp, *gp, *bp; + register int x; + register uint32 n; + + n = rowsperstrip; + if (n > ysize-y+1) + n = ysize-y+1; + rp = rbuf; gp = gbuf; bp = bbuf; + do { + for (x = 0; x <= xsize; x++) { + u_long v = ss[x]; + rp[x] = v; + gp[x] = v >> 8; + bp[x] = v >> 16; + } + rp += xsize+1, gp += xsize+1, bp += xsize+1; + ss += xsize+1; + } while (--n); + if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0), + rbuf, stripsize) < 0) + break; + if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,1), + gbuf, stripsize) < 0) + break; + if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,2), + bbuf, stripsize) < 0) + break; + } + _TIFFfree(rbuf); +} + +static void +svRGBContig(TIFF* tif, u_long* ss, int xsize, int ysize) +{ + register int x, y; + tsize_t stripsize = TIFFStripSize(tif); + u_char *strip = (u_char *)_TIFFmalloc(stripsize); + + for (y = 0; y <= ysize; y += rowsperstrip) { + register u_char *pp = strip; + register uint32 n; + + n = rowsperstrip; + if (n > ysize-y+1) + n = ysize-y+1; + do { + for (x = 0; x <= xsize; x++) { + u_long v = ss[x]; + pp[0] = v; + pp[1] = v >> 8; + pp[2] = v >> 16; + pp += 3; + } + ss += xsize+1; + } while (--n); + if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0), + strip, stripsize) < 0) + break; + } + _TIFFfree(strip); +} + +#undef RED +#undef GREEN +#undef BLUE +#define CVT(x) (((x)*255)/100) +#define RED CVT(28) /* 28% */ +#define GREEN CVT(59) /* 59% */ +#define BLUE CVT(11) /* 11% */ + +static void +svGrey(TIFF* tif, u_long* ss, int xsize, int ysize) +{ + register int x, y; + u_char *buf = (u_char *)_TIFFmalloc(TIFFScanlineSize(tif)); + + for (y = 0; y <= ysize; y++) { + for (x = 0; x <= xsize; x++) { + u_char *cp = (u_char *)&ss[x]; + buf[x] = (RED*cp[3] + GREEN*cp[2] + BLUE*cp[1]) >> 8; + } + if (TIFFWriteScanline(tif, buf, (uint32) y, 0) < 0) + break; + ss += xsize+1; + } + _TIFFfree(buf); +} + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define ABS(x) ((x)<0?-(x):(x)) + +static void +tiffsv(char* name, int x1, int x2, int y1, int y2) +{ + TIFF *tif; + int xsize, ysize; + int xorg, yorg; + u_long *scrbuf; + + xorg = MIN(x1,x2); + yorg = MIN(y1,y2); + if (xorg<0) + xorg = 0; + if (yorg<0) + yorg = 0; + xsize = ABS(x2-x1); + ysize = ABS(y2-y1); + if (xorg+xsize > xmaxscreen) + xsize = xmaxscreen-xorg; + if (yorg+ysize > ymaxscreen) + ysize = ymaxscreen-yorg; + tif = TIFFOpen(name, "w"); + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) (xsize+1)); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) (ysize+1)); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, + photometric == PHOTOMETRIC_RGB ? 3 : 1); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, config); + TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); + switch (compression) { + case COMPRESSION_JPEG: + if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB) + photometric = PHOTOMETRIC_YCBCR; + TIFFSetField(tif, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + if (predictor != 0) + TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor); + break; + } + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric); + TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT); + rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + scrbuf = (u_long *)_TIFFmalloc((xsize+1)*(ysize+1)*sizeof (u_long)); + readdisplay(xorg, yorg, xorg+xsize, yorg+ysize, scrbuf, RD_FREEZE); + if (photometric == PHOTOMETRIC_RGB) { + if (config == PLANARCONFIG_SEPARATE) + svRGBSeparate(tif, scrbuf, xsize, ysize); + else + svRGBContig(tif, scrbuf, xsize, ysize); + } else + svGrey(tif, scrbuf, xsize, ysize); + (void) TIFFClose(tif); + _TIFFfree((char *)scrbuf); +} diff --git a/tools/thumbnail.c b/tools/thumbnail.c new file mode 100644 index 00000000..9305de7e --- /dev/null +++ b/tools/thumbnail.c @@ -0,0 +1,572 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/thumbnail.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1994-1997 Sam Leffler + * Copyright (c) 1994-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ +#include +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcasecmp(a,b) == 0) + +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif + +typedef enum { + EXP50, + EXP60, + EXP70, + EXP80, + EXP90, + EXP, + LINEAR +} Contrast; + +static uint32 tnw = 216; /* thumbnail width */ +static uint32 tnh = 274; /* thumbnail height */ +static Contrast contrast = LINEAR; /* current contrast */ +static uint8* thumbnail; + +static int cpIFD(TIFF*, TIFF*); +static int generateThumbnail(TIFF*, TIFF*); +static void initScale(); +static void usage(void); + +extern char* optarg; +extern int optind; + +int +main(int argc, char* argv[]) +{ + TIFF* in; + TIFF* out; + int c; + + while ((c = getopt(argc, argv, "w:h:c:")) != -1) { + switch (c) { + case 'w': tnw = strtoul(optarg, NULL, 0); break; + case 'h': tnh = strtoul(optarg, NULL, 0); break; + case 'c': contrast = streq(optarg, "exp50") ? EXP50 : + streq(optarg, "exp60") ? EXP60 : + streq(optarg, "exp70") ? EXP70 : + streq(optarg, "exp80") ? EXP80 : + streq(optarg, "exp90") ? EXP90 : + streq(optarg, "exp") ? EXP : + streq(optarg, "linear")? LINEAR : + EXP; + break; + default: usage(); + } + } + if (argc-optind != 2) + usage(); + thumbnail = (uint8*) _TIFFmalloc(tnw * tnh); + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-2); + in = TIFFOpen(argv[optind], "r"); + if (in != NULL) { + initScale(); + do { + if (!generateThumbnail(in, out)) + goto bad; + if (!cpIFD(in, out) || !TIFFWriteDirectory(out)) + goto bad; + } while (TIFFReadDirectory(in)); + (void) TIFFClose(in); + } + (void) TIFFClose(out); + return (0); +bad: + (void) TIFFClose(out); + return (1); +} + +#define CopyField1(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) +#define CopyField2(tag, v1, v2) \ + if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) +#define CopyField3(tag, v1, v2, v3) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) +#define CopyField4(tag, v1, v2, v3, v4) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4) + +static void +cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type) +{ + uint16 shortv, shortv2, *shortav; + float floatv, *floatav; + char *stringv; + uint32 longv; + + switch (type) { + case TIFF_SHORT: + if (count == 1) { + CopyField1(tag, shortv); + } else if (count == 2) { + CopyField2(tag, shortv, shortv2); + } else if (count == (uint16) -1) { + CopyField2(tag, shortv, shortav); + } + break; + case TIFF_LONG: + CopyField1(tag, longv); + break; + case TIFF_RATIONAL: + if (count == 1) { + CopyField1(tag, floatv); + } else if (count == (uint16) -1) { + CopyField1(tag, floatav); + } + break; + case TIFF_ASCII: + CopyField1(tag, stringv); + break; + } +} +#undef CopyField4 +#undef CopyField3 +#undef CopyField2 +#undef CopyField1 + +static struct cpTag { + uint16 tag; + uint16 count; + TIFFDataType type; +} tags[] = { + { TIFFTAG_IMAGEWIDTH, 1, TIFF_LONG }, + { TIFFTAG_IMAGELENGTH, 1, TIFF_LONG }, + { TIFFTAG_BITSPERSAMPLE, 1, TIFF_SHORT }, + { TIFFTAG_COMPRESSION, 1, TIFF_SHORT }, + { TIFFTAG_FILLORDER, 1, TIFF_SHORT }, + { TIFFTAG_SAMPLESPERPIXEL, 1, TIFF_SHORT }, + { TIFFTAG_ROWSPERSTRIP, 1, TIFF_LONG }, + { TIFFTAG_PLANARCONFIG, 1, TIFF_SHORT }, + { TIFFTAG_GROUP3OPTIONS, 1, TIFF_LONG }, + { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG }, + { TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT }, + { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT }, + { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII }, + { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII }, + { TIFFTAG_MAKE, 1, TIFF_ASCII }, + { TIFFTAG_MODEL, 1, TIFF_ASCII }, + { TIFFTAG_ORIENTATION, 1, TIFF_SHORT }, + { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT }, + { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT }, + { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_PAGENAME, 1, TIFF_ASCII }, + { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG }, + { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT }, + { TIFFTAG_PAGENUMBER, 2, TIFF_SHORT }, + { TIFFTAG_SOFTWARE, 1, TIFF_ASCII }, + { TIFFTAG_DATETIME, 1, TIFF_ASCII }, + { TIFFTAG_ARTIST, 1, TIFF_ASCII }, + { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII }, + { TIFFTAG_WHITEPOINT, 1, TIFF_RATIONAL }, + { TIFFTAG_PRIMARYCHROMATICITIES, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT }, + { TIFFTAG_BADFAXLINES, 1, TIFF_LONG }, + { TIFFTAG_CLEANFAXDATA, 1, TIFF_SHORT }, + { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG }, + { TIFFTAG_INKSET, 1, TIFF_SHORT }, + { TIFFTAG_INKNAMES, 1, TIFF_ASCII }, + { TIFFTAG_DOTRANGE, 2, TIFF_SHORT }, + { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII }, + { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT }, + { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT }, + { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT }, + { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT }, +}; +#define NTAGS (sizeof (tags) / sizeof (tags[0])) + +static void +cpTags(TIFF* in, TIFF* out) +{ + struct cpTag *p; + for (p = tags; p < &tags[NTAGS]; p++) + cpTag(in, out, p->tag, p->count, p->type); +} +#undef NTAGS + +static int +cpStrips(TIFF* in, TIFF* out) +{ + tsize_t bufsize = TIFFStripSize(in); + unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); + + if (buf) { + tstrip_t s, ns = TIFFNumberOfStrips(in); + uint32 *bytecounts; + + TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); + for (s = 0; s < ns; s++) { + if (bytecounts[s] > bufsize) { + buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); + if (!buf) + return (0); + bufsize = bytecounts[s]; + } + if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || + TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { + _TIFFfree(buf); + return (0); + } + } + _TIFFfree(buf); + return (1); + } + return (0); +} + +static int +cpTiles(TIFF* in, TIFF* out) +{ + tsize_t bufsize = TIFFTileSize(in); + unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); + + if (buf) { + ttile_t t, nt = TIFFNumberOfTiles(in); + uint32 *bytecounts; + + TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); + for (t = 0; t < nt; t++) { + if (bytecounts[t] > bufsize) { + buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); + if (!buf) + return (0); + bufsize = bytecounts[t]; + } + if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || + TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { + _TIFFfree(buf); + return (0); + } + } + _TIFFfree(buf); + return (1); + } + return (0); +} + +static int +cpIFD(TIFF* in, TIFF* out) +{ + cpTags(in, out); + if (TIFFIsTiled(in)) { + if (!cpTiles(in, out)) + return (0); + } else { + if (!cpStrips(in, out)) + return (0); + } + return (1); +} + +static uint16 photometric; /* current photometric of raster */ +static uint16 filterWidth; /* filter width in pixels */ +static uint16 stepSrcWidth; /* src image stepping width */ +static uint16 stepDstWidth; /* dest stepping width */ +static uint8* src0; /* horizontal bit stepping (start) */ +static uint8* src1; /* horizontal bit stepping (middle) */ +static uint8* src2; /* horizontal bit stepping (end) */ +static uint16* rowoff; /* row offset for stepping */ +static uint8 cmap[256]; /* colormap indexes */ +static uint8 bits[256]; /* count of bits set */ + +static void +setupBitsTables() +{ + int i; + for (i = 0; i < 256; i++) { + int n = 0; + if (i&0x01) n++; + if (i&0x02) n++; + if (i&0x04) n++; + if (i&0x08) n++; + if (i&0x10) n++; + if (i&0x20) n++; + if (i&0x40) n++; + if (i&0x80) n++; + bits[i] = n; + } +} + +static int clamp(float v, int low, int high) + { return (v < low ? low : v > high ? high : (int)v); } + +#ifndef M_E +#define M_E 2.7182818284590452354 +#endif + +static void +expFill(float pct[], uint32 p, uint32 n) +{ + uint32 i; + uint32 c = (p * n) / 100; + for (i = 1; i < c; i++) + pct[i] = 1-exp(i/((double)(n-1)))/ M_E; + for (; i < n; i++) + pct[i] = 0.; +} + +static void +setupCmap() +{ + float pct[256]; /* known to be large enough */ + uint32 i; + pct[0] = 1; /* force white */ + switch (contrast) { + case EXP50: expFill(pct, 50, 256); break; + case EXP60: expFill(pct, 60, 256); break; + case EXP70: expFill(pct, 70, 256); break; + case EXP80: expFill(pct, 80, 256); break; + case EXP90: expFill(pct, 90, 256); break; + case EXP: expFill(pct, 100, 256); break; + case LINEAR: + for (i = 1; i < 256; i++) + pct[i] = 1-((float)i)/(256-1); + break; + } + switch (photometric) { + case PHOTOMETRIC_MINISWHITE: + for (i = 0; i < 256; i++) + cmap[i] = clamp(255*pct[(256-1)-i], 0, 255); + break; + case PHOTOMETRIC_MINISBLACK: + for (i = 0; i < 256; i++) + cmap[i] = clamp(255*pct[i], 0, 255); + break; + } +} + +static void +initScale() +{ + src0 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw); + src1 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw); + src2 = (uint8*) _TIFFmalloc(sizeof (uint8) * tnw); + rowoff = (uint16*) _TIFFmalloc(sizeof (uint16) * tnw); + filterWidth = 0; + stepDstWidth = stepSrcWidth = 0; + setupBitsTables(); +} + +/* + * Calculate the horizontal accumulation parameteres + * according to the widths of the src and dst images. + */ +static void +setupStepTables(uint16 sw) +{ + if (stepSrcWidth != sw || stepDstWidth != tnw) { + int step = sw; + int limit = tnw; + int err = 0; + uint32 sx = 0; + uint32 x; + int fw; + uint8 b; + for (x = 0; x < tnw; x++) { + uint32 sx0 = sx; + err += step; + while (err >= limit) { + err -= limit; + sx++; + } + rowoff[x] = sx0 >> 3; + fw = sx - sx0; /* width */ + b = (fw < 8) ? 0xff<<(8-fw) : 0xff; + src0[x] = b >> (sx0&7); + fw -= 8 - (sx0&7); + if (fw < 0) + fw = 0; + src1[x] = fw >> 3; + fw -= (fw>>3)<<3; + src2[x] = 0xff << (8-fw); + } + stepSrcWidth = sw; + stepDstWidth = tnw; + } +} + +static void +setrow(uint8* row, int nrows, const uint8* rows[]) +{ + uint32 x; + uint32 area = nrows * filterWidth; + for (x = 0; x < tnw; x++) { + uint32 mask0 = src0[x]; + uint32 fw = src1[x]; + uint32 mask1 = src1[x]; + uint32 off = rowoff[x]; + uint32 acc = 0; + uint32 y, i; + for (y = 0; y < nrows; y++) { + const uint8* src = rows[y] + off; + acc += bits[*src++ & mask0]; + switch (fw) { + default: + for (i = fw; i > 8; i--) + acc += bits[*src++]; + /* fall thru... */ + case 8: acc += bits[*src++]; + case 7: acc += bits[*src++]; + case 6: acc += bits[*src++]; + case 5: acc += bits[*src++]; + case 4: acc += bits[*src++]; + case 3: acc += bits[*src++]; + case 2: acc += bits[*src++]; + case 1: acc += bits[*src++]; + case 0: break; + } + acc += bits[*src & mask1]; + } + *row++ = cmap[(255*acc)/area]; + } +} + +/* + * Install the specified image. The + * image is resized to fit the display page using + * a box filter. The resultant pixels are mapped + * with a user-selectable contrast curve. + */ +static void +setImage1(const uint8* br, uint32 rw, uint32 rh) +{ + int step = rh; + int limit = tnh; + int err = 0; + int bpr = howmany(rw,8); + uint32 sy = 0; + uint8* row = thumbnail; + uint32 dy; + for (dy = 0; dy < tnh; dy++) { + const uint8* rows[256]; + int nrows = 1; + rows[0] = br + bpr*sy; + err += step; + while (err >= limit) { + err -= limit; + sy++; + if (err >= limit) + rows[nrows++] = br + bpr*sy; + } + setrow(row, nrows, rows); + row += tnw; + } +} + +static void +setImage(const uint8* br, uint32 rw, uint32 rh) +{ + filterWidth = (uint16) ceil((double) rw / (double) tnw); + setupStepTables(rw); + setImage1(br, rw, rh); +} + +static int +generateThumbnail(TIFF* in, TIFF* out) +{ + unsigned char* raster; + unsigned char* rp; + uint32 sw, sh, rps; + uint16 bps, spp; + tsize_t rowsize, rastersize; + tstrip_t s, ns = TIFFNumberOfStrips(in); + uint32 diroff[1]; + + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &sw); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &sh); + TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps); + TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp); + TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps); + if (spp != 1 || bps != 1) + return (0); + rowsize = TIFFScanlineSize(in); + rastersize = sh * rowsize; + raster = (unsigned char*)_TIFFmalloc(rastersize); + rp = raster; + for (s = 0; s < ns; s++) { + (void) TIFFReadEncodedStrip(in, s, rp, -1); + rp += rps * rowsize; + } + TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric); + setupCmap(); + setImage(raster, sw, sh); + + TIFFSetField(out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE); + TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) tnw); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) tnh); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, (uint16) 8); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, (uint16) 1); + TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_LZW); + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + cpTag(in, out, TIFFTAG_SOFTWARE, (uint16) -1, TIFF_ASCII); + cpTag(in, out, TIFFTAG_IMAGEDESCRIPTION, (uint16) -1, TIFF_ASCII); + cpTag(in, out, TIFFTAG_DATETIME, (uint16) -1, TIFF_ASCII); + cpTag(in, out, TIFFTAG_HOSTCOMPUTER, (uint16) -1, TIFF_ASCII); + diroff[0] = 0; + TIFFSetField(out, TIFFTAG_SUBIFD, 1, diroff); + return (TIFFWriteEncodedStrip(out, 0, thumbnail, tnw*tnh) != -1 && + TIFFWriteDirectory(out) != -1); +} + +char* stuff[] = { +"usage: thumbnail [options] input.tif output.tif", +"where options are:", +" -h # specify thumbnail image height (default is 274)", +" -w # specify thumbnail image width (default is 216)", +"", +" -c linear use linear contrast curve", +" -c exp50 use 50% exponential contrast curve", +" -c exp60 use 60% exponential contrast curve", +" -c exp70 use 70% exponential contrast curve", +" -c exp80 use 80% exponential contrast curve", +" -c exp90 use 90% exponential contrast curve", +" -c exp use pure exponential contrast curve", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/tiff2bw.c b/tools/tiff2bw.c new file mode 100644 index 00000000..6ad7a347 --- /dev/null +++ b/tools/tiff2bw.c @@ -0,0 +1,400 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiff2bw.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "tiffio.h" + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +/* x% weighting -> fraction of full color */ +#define PCT(x) (((x)*255)/100) +int RED = PCT(28); /* 28% */ +int GREEN = PCT(59); /* 59% */ +int BLUE = PCT(11); /* 11% */ + +static void usage(void); +static int processCompressOptions(char*); + +static void +compresscontig(unsigned char* out, unsigned char* rgb, uint32 n) +{ + register int v, red = RED, green = GREEN, blue = BLUE; + + while (n-- > 0) { + v = red*(*rgb++); + v += green*(*rgb++); + v += blue*(*rgb++); + *out++ = v>>8; + } +} + +static void +compresssep(unsigned char* out, + unsigned char* r, unsigned char* g, unsigned char* b, uint32 n) +{ + register uint32 red = RED, green = GREEN, blue = BLUE; + + while (n-- > 0) + *out++ = (red*(*r++) + green*(*g++) + blue*(*b++)) >> 8; +} + +static int +checkcmap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b) +{ + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + TIFFWarning(TIFFFileName(tif), "Assuming 8-bit colormap"); + return (8); +} + +static void +compresspalette(unsigned char* out, unsigned char* data, uint32 n, uint16* rmap, uint16* gmap, uint16* bmap) +{ + register int v, red = RED, green = GREEN, blue = BLUE; + + while (n-- > 0) { + unsigned int ix = *data++; + v = red*rmap[ix]; + v += green*gmap[ix]; + v += blue*bmap[ix]; + *out++ = v>>8; + } +} + +static uint16 compression = (uint16) -1; +static uint16 predictor = 0; +static int jpegcolormode = JPEGCOLORMODE_RGB; +static int quality = 75; /* JPEG quality */ + +static void cpTags(TIFF* in, TIFF* out); + +int +main(int argc, char* argv[]) +{ + uint32 rowsperstrip = (uint32) -1; + TIFF *in, *out; + uint32 w, h; + uint16 samplesperpixel; + uint16 bitspersample; + uint16 config; + uint16 photometric; + uint16* red; + uint16* green; + uint16* blue; + tsize_t rowsize; + register uint32 row; + register tsample_t s; + unsigned char *inbuf, *outbuf; + char thing[1024]; + int c; + extern int optind; + extern char *optarg; + + while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1) + switch (c) { + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case 'R': + RED = PCT(atoi(optarg)); + break; + case 'G': + GREEN = PCT(atoi(optarg)); + break; + case 'B': + BLUE = PCT(atoi(optarg)); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind < 2) + usage(); + in = TIFFOpen(argv[optind], "r"); + if (in == NULL) + return (-1); + photometric = 0; + TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric); + if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE ) { + fprintf(stderr, + "%s: Bad photometric; can only handle RGB and Palette images.\n", + argv[optind]); + return (-1); + } + TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (samplesperpixel != 1 && samplesperpixel != 3) { + fprintf(stderr, "%s: Bad samples/pixel %u.\n", + argv[optind], samplesperpixel); + return (-1); + } + TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + if (bitspersample != 8) { + fprintf(stderr, + " %s: Sorry, only handle 8-bit samples.\n", argv[optind]); + return (-1); + } + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h); + TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); + + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-1); + cpTags(in, out); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + if (compression != (uint16) -1) { + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + switch (compression) { + case COMPRESSION_JPEG: + TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + } + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + sprintf(thing, "B&W version of %s", argv[optind]); + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); + TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw"); + outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out)); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + +#define pack(a,b) ((a)<<8 | (b)) + switch (pack(photometric, config)) { + case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG): + case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE): + TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue); + /* + * Convert 16-bit colormap to 8-bit (unless it looks + * like an old-style 8-bit colormap). + */ + if (checkcmap(in, 1<= 0; i--) { + red[i] = CVT(red[i]); + green[i] = CVT(green[i]); + blue[i] = CVT(blue[i]); + } +#undef CVT + } + inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + for (row = 0; row < h; row++) { + if (TIFFReadScanline(in, inbuf, row, 0) < 0) + break; + compresspalette(outbuf, inbuf, w, red, green, blue); + if (TIFFWriteScanline(out, outbuf, row, 0) < 0) + break; + } + break; + case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG): + inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + for (row = 0; row < h; row++) { + if (TIFFReadScanline(in, inbuf, row, 0) < 0) + break; + compresscontig(outbuf, inbuf, w); + if (TIFFWriteScanline(out, outbuf, row, 0) < 0) + break; + } + break; + case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE): + rowsize = TIFFScanlineSize(in); + inbuf = (unsigned char *)_TIFFmalloc(3*rowsize); + for (row = 0; row < h; row++) { + for (s = 0; s < 3; s++) + if (TIFFReadScanline(in, + inbuf+s*rowsize, row, s) < 0) + return (-1); + compresssep(outbuf, + inbuf, inbuf+rowsize, inbuf+2*rowsize, w); + if (TIFFWriteScanline(out, outbuf, row, 0) < 0) + break; + } + break; + } +#undef pack + TIFFClose(out); + return (0); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "jpeg", 4)) { + char* cp = strchr(opt, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + compression = COMPRESSION_JPEG; + } else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +#define CopyField1(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) +#define CopyField2(tag, v1, v2) \ + if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) +#define CopyField3(tag, v1, v2, v3) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) +#define CopyField4(tag, v1, v2, v3, v4) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4) + +static void +cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type) +{ + uint16 shortv, shortv2, *shortav; + float floatv, *floatav; + char *stringv; + uint32 longv; + + switch (type) { + case TIFF_SHORT: + if (count == 1) { + CopyField1(tag, shortv); + } else if (count == 2) { + CopyField2(tag, shortv, shortv2); + } else if (count == (uint16) -1) { + CopyField2(tag, shortv, shortav); + } + break; + case TIFF_LONG: + CopyField1(tag, longv); + break; + case TIFF_RATIONAL: + if (count == 1) { + CopyField1(tag, floatv); + } else if (count == (uint16) -1) { + CopyField1(tag, floatav); + } + break; + case TIFF_ASCII: + CopyField1(tag, stringv); + break; + } +} +#undef CopyField4 +#undef CopyField3 +#undef CopyField2 +#undef CopyField1 + +static struct cpTag { + uint16 tag; + uint16 count; + TIFFDataType type; +} tags[] = { + { TIFFTAG_IMAGEWIDTH, 1, TIFF_LONG }, + { TIFFTAG_IMAGELENGTH, 1, TIFF_LONG }, + { TIFFTAG_FILLORDER, 1, TIFF_SHORT }, + { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII }, + { TIFFTAG_MAKE, 1, TIFF_ASCII }, + { TIFFTAG_MODEL, 1, TIFF_ASCII }, + { TIFFTAG_ORIENTATION, 1, TIFF_SHORT }, + { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_PAGENAME, 1, TIFF_ASCII }, + { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT }, + { TIFFTAG_PAGENUMBER, 2, TIFF_SHORT }, + { TIFFTAG_ARTIST, 1, TIFF_ASCII }, + { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII }, +}; +#define NTAGS (sizeof (tags) / sizeof (tags[0])) + +static void +cpTags(TIFF* in, TIFF* out) +{ + struct cpTag *p; + for (p = tags; p < &tags[NTAGS]; p++) + cpTag(in, out, p->tag, p->count, p->type); +} +#undef NTAGS + +char* stuff[] = { +"usage: tiff2bw [options] input.tif output.tif", +"where options are:", +" -R % use #% from red channel", +" -G % use #% from green channel", +" -B % use #% from blue channel", +"", +" -r # make each strip have no more than # rows", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c packbits compress output with packbits encoding", +" -c g3[:opts] compress output with CCITT Group 3 encoding", +" -c g4 compress output with CCITT Group 4 encoding", +" -c none use no compression algorithm on output", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/tiff2ps.c b/tools/tiff2ps.c new file mode 100644 index 00000000..e2526877 --- /dev/null +++ b/tools/tiff2ps.c @@ -0,0 +1,1408 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiff2ps.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include /* for atof */ +#include +#include + +#include "tiffio.h" + +/* + * NB: this code assumes uint32 works with printf's %l[ud]. + */ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +int ascii85 = FALSE; /* use ASCII85 encoding */ +int interpolate = TRUE; /* interpolate level2 image */ +int level2 = FALSE; /* generate PostScript level 2 */ +int printAll = FALSE; /* print all images in file */ +int generateEPSF = TRUE; /* generate Encapsulated PostScript */ +int PSduplex = FALSE; /* enable duplex printing */ +int PStumble = FALSE; /* enable top edge binding */ +int PSavoiddeadzone = TRUE; /* enable avoiding printer deadzone */ +char *filename; /* input filename */ + +/* + * ASCII85 Encoding Support. + */ +unsigned char ascii85buf[10]; +int ascii85count; +int ascii85breaklen; + +int TIFF2PS(FILE*, TIFF*, float, float); +void PSpage(FILE*, TIFF*, uint32, uint32); +void PSColorContigPreamble(FILE*, uint32, uint32, int); +void PSColorSeparatePreamble(FILE*, uint32, uint32, int); +void PSDataColorContig(FILE*, TIFF*, uint32, uint32, int); +void PSDataColorSeparate(FILE*, TIFF*, uint32, uint32, int); +void PSDataPalette(FILE*, TIFF*, uint32, uint32); +void PSDataBW(FILE*, TIFF*, uint32, uint32); +void PSRawDataBW(FILE*, TIFF*, uint32, uint32); +void Ascii85Init(void); +void Ascii85Put(unsigned char code, FILE* fd); +void Ascii85Flush(FILE* fd); +void PSHead(FILE*, TIFF*, uint32, uint32, float, float, float, float); +void PSTail(FILE*, int); + +static void usage(int); + +int +main(int argc, char* argv[]) +{ + int dirnum = -1, c, np = 0; + float pageWidth = 0; + float pageHeight = 0; + uint32 diroff = 0; + extern char *optarg; + extern int optind; + FILE* output = stdout; + + while ((c = getopt(argc, argv, "h:w:d:o:O:aezps128DT")) != -1) + switch (c) { + case 'd': + dirnum = atoi(optarg); + break; + case 'D': + PSduplex = TRUE; + break; + case 'T': + PStumble = TRUE; + break; + case 'e': + generateEPSF = TRUE; + break; + case 'h': + pageHeight = atof(optarg); + break; + case 'o': + diroff = (uint32) strtoul(optarg, NULL, 0); + break; + case 'O': /* XXX too bad -o is already taken */ + output = fopen(optarg, "w"); + if (output == NULL) { + fprintf(stderr, + "%s: %s: Cannot open output file.\n", + argv[0], optarg); + exit(-2); + } + break; + case 'a': + printAll = TRUE; + /* fall thru... */ + case 'p': + generateEPSF = FALSE; + break; + case 's': + printAll = FALSE; + break; + case 'w': + pageWidth = atof(optarg); + break; + case 'z': + PSavoiddeadzone = FALSE; + break; + case '1': + level2 = FALSE; + ascii85 = FALSE; + break; + case '2': + level2 = TRUE; + ascii85 = TRUE; /* default to yes */ + break; + case '8': + ascii85 = FALSE; + break; + case '?': + usage(-1); + } + for (; argc - optind > 0; optind++) { + TIFF* tif = TIFFOpen(filename = argv[optind], "r"); + if (tif != NULL) { + if (dirnum != -1 && !TIFFSetDirectory(tif, dirnum)) + return (-1); + else if (diroff != 0 && + !TIFFSetSubDirectory(tif, diroff)) + return (-1); + np = TIFF2PS(output, tif, pageWidth, pageHeight); + TIFFClose(tif); + } + } + if (np) + PSTail(output, np); + else + usage(-1); + if (output != stdout) + fclose(output); + return (0); +} + +static uint16 samplesperpixel; +static uint16 bitspersample; +static uint16 planarconfiguration; +static uint16 photometric; +static uint16 compression; +static uint16 extrasamples; +static int alpha; + +static int +checkImage(TIFF* tif) +{ + switch (photometric) { + case PHOTOMETRIC_YCBCR: + if (compression == COMPRESSION_JPEG && + planarconfiguration == PLANARCONFIG_CONTIG) { + /* can rely on libjpeg to convert to RGB */ + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, + JPEGCOLORMODE_RGB); + photometric = PHOTOMETRIC_RGB; + } else { + if (level2) + break; + TIFFError(filename, "Can not handle image with %s", + "PhotometricInterpretation=YCbCr"); + return (0); + } + /* fall thru... */ + case PHOTOMETRIC_RGB: + if (alpha && bitspersample != 8) { + TIFFError(filename, + "Can not handle %d-bit/sample RGB image with alpha", + bitspersample); + return (0); + } + /* fall thru... */ + case PHOTOMETRIC_SEPARATED: + case PHOTOMETRIC_PALETTE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + break; + case PHOTOMETRIC_LOGL: + case PHOTOMETRIC_LOGLUV: + if (compression != COMPRESSION_SGILOG && + compression != COMPRESSION_SGILOG24) { + TIFFError(filename, + "Can not handle %s data with compression other than SGILog", + (photometric == PHOTOMETRIC_LOGL) ? + "LogL" : "LogLuv" + ); + return (0); + } + /* rely on library to convert to RGB/greyscale */ + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + photometric = (photometric == PHOTOMETRIC_LOGL) ? + PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB; + bitspersample = 8; + break; + case PHOTOMETRIC_CIELAB: + /* fall thru... */ + default: + TIFFError(filename, + "Can not handle image with PhotometricInterpretation=%d", + photometric); + return (0); + } + switch (bitspersample) { + case 1: case 2: + case 4: case 8: + break; + default: + TIFFError(filename, "Can not handle %d-bit/sample image", + bitspersample); + return (0); + } + if (planarconfiguration == PLANARCONFIG_SEPARATE && extrasamples > 0) + TIFFWarning(filename, "Ignoring extra samples"); + return (1); +} + +#define PS_UNIT_SIZE 72.0 +#define PSUNITS(npix,res) ((npix) * (PS_UNIT_SIZE / (res))) + +static char RGBcolorimage[] = "\ +/bwproc {\n\ + rgbproc\n\ + dup length 3 idiv string 0 3 0\n\ + 5 -1 roll {\n\ + add 2 1 roll 1 sub dup 0 eq {\n\ + pop 3 idiv\n\ + 3 -1 roll\n\ + dup 4 -1 roll\n\ + dup 3 1 roll\n\ + 5 -1 roll put\n\ + 1 add 3 0\n\ + } { 2 1 roll } ifelse\n\ + } forall\n\ + pop pop pop\n\ +} def\n\ +/colorimage where {pop} {\n\ + /colorimage {pop pop /rgbproc exch def {bwproc} image} bind def\n\ +} ifelse\n\ +"; + +/* + * Adobe Photoshop requires a comment line of the form: + * + * %ImageData:

+ * <1 for binary|2 for hex> "data start" + * + * It is claimed to be part of some future revision of the EPS spec. + */ +static void +PhotoshopBanner(FILE* fd, uint32 w, uint32 h, int bs, int nc, char* startline) +{ + fprintf(fd, "%%ImageData: %ld %ld %d %d 0 %d 2 \"", + (long) w, (long) h, bitspersample, nc, bs); + fprintf(fd, startline, nc); + fprintf(fd, "\"\n"); +} + +static void +setupPageState(TIFF* tif, uint32* pw, uint32* ph, float* pprw, float* pprh) +{ + uint16 res_unit; + float xres, yres; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, pw); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ph); + TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &res_unit); + /* + * Calculate printable area. + */ + if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)) + xres = PS_UNIT_SIZE; + if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)) + yres = PS_UNIT_SIZE; + switch (res_unit) { + case RESUNIT_CENTIMETER: + xres *= 2.54, yres *= 2.54; + break; + case RESUNIT_NONE: + xres *= PS_UNIT_SIZE, yres *= PS_UNIT_SIZE; + break; + } + *pprh = PSUNITS(*ph, yres); + *pprw = PSUNITS(*pw, xres); +} + +static int +isCCITTCompression(TIFF* tif) +{ + uint16 compress; + TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); + return (compress == COMPRESSION_CCITTFAX3 || + compress == COMPRESSION_CCITTFAX4 || + compress == COMPRESSION_CCITTRLE || + compress == COMPRESSION_CCITTRLEW); +} + +static tsize_t tf_bytesperrow; +static tsize_t ps_bytesperrow; +static tsize_t tf_rowsperstrip; +static tsize_t tf_numberstrips; +static char *hex = "0123456789abcdef"; + + +/* returns the sequence number of the page processed */ +int +TIFF2PS(FILE* fd, TIFF* tif, float pw, float ph) +{ + uint32 w, h; + float ox, oy, prw, prh; + float scale; + uint32 subfiletype; + uint16* sampleinfo; + static int npages = 0; + + if (!TIFFGetField(tif, TIFFTAG_XPOSITION, &ox)) + ox = 0; + if (!TIFFGetField(tif, TIFFTAG_YPOSITION, &oy)) + oy = 0; + setupPageState(tif, &w, &h, &prw, &prh); + + do { + tf_numberstrips = TIFFNumberOfStrips(tif); + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, + &tf_rowsperstrip); + setupPageState(tif, &w, &h, &prw, &prh); + if (!npages) + PSHead(fd, tif, w, h, prw, prh, ox, oy); + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, + &bitspersample); + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, + &samplesperpixel); + TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, + &planarconfiguration); + TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, + &extrasamples, &sampleinfo); + alpha = (extrasamples == 1 && + sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { + switch (samplesperpixel - extrasamples) { + case 1: + if (isCCITTCompression(tif)) + photometric = PHOTOMETRIC_MINISWHITE; + else + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + photometric = PHOTOMETRIC_RGB; + break; + } + } + if (checkImage(tif)) { + tf_bytesperrow = TIFFScanlineSize(tif); + npages++; + fprintf(fd, "%%%%Page: %d %d\n", npages, npages); + fprintf(fd, "gsave\n"); + fprintf(fd, "100 dict begin\n"); + if (pw != 0 && ph != 0) { + /* NB: maintain image aspect ratio */ + scale = (pw*PS_UNIT_SIZE/prw) < (ph*PS_UNIT_SIZE/prh) ? + (pw*PS_UNIT_SIZE/prw) : + (ph*PS_UNIT_SIZE/prh); + if (scale > 1.0) + scale = 1.0; + fprintf(fd, "0 %f translate\n", ph*PS_UNIT_SIZE-prh*scale); + fprintf(fd, "%f %f scale\n", prw*scale, prh*scale); + } else + fprintf(fd, "%f %f scale\n", prw, prh); + PSpage(fd, tif, w, h); + fprintf(fd, "end\n"); + fprintf(fd, "grestore\n"); + fprintf(fd, "showpage\n"); + } + if (generateEPSF) + break; + TIFFGetFieldDefaulted(tif, TIFFTAG_SUBFILETYPE, &subfiletype); + } while (((subfiletype & FILETYPE_PAGE) || printAll) && + TIFFReadDirectory(tif)); + + return(npages); +} + + +static char DuplexPreamble[] = "\ +%%BeginFeature: *Duplex True\n\ +systemdict begin\n\ + /languagelevel where { pop languagelevel } { 1 } ifelse\n\ + 2 ge { 1 dict dup /Duplex true put setpagedevice }\n\ + { statusdict /setduplex known { statusdict begin setduplex true end } if\n\ + } ifelse\n\ +end\n\ +%%EndFeature\n\ +"; + +static char TumblePreamble[] = "\ +%%BeginFeature: *Tumble True\n\ +systemdict begin\n\ + /languagelevel where { pop languagelevel } { 1 } ifelse\n\ + 2 ge { 1 dict dup /Tumble true put setpagedevice }\n\ + { statusdict /settumble known { statusdict begin settumble true end } if\n\ + } ifelse\n\ +end\n\ +%%EndFeature\n\ +"; + +static char AvoidDeadZonePreamble[] = "\ +gsave newpath clippath pathbbox grestore\n\ + 4 2 roll 2 copy translate\n\ + exch 3 1 roll sub 3 1 roll sub exch\n\ + currentpagedevice /PageSize get aload pop\n\ + exch 3 1 roll div 3 1 roll div abs exch abs\n\ + 2 copy gt { exch } if pop\n\ + dup 1 lt { dup scale } { pop } ifelse\n\ +"; + +void +PSHead(FILE *fd, TIFF *tif, uint32 w, uint32 h, float pw, float ph, + float ox, float oy) +{ + time_t t; + + (void) tif; (void) w; (void) h; + t = time(0); + fprintf(fd, "%%!PS-Adobe-3.0%s\n", generateEPSF ? " EPSF-3.0" : ""); + fprintf(fd, "%%%%Creator: tiff2ps\n"); + fprintf(fd, "%%%%Title: %s\n", filename); + fprintf(fd, "%%%%CreationDate: %s", ctime(&t)); + fprintf(fd, "%%%%DocumentData: Clean7Bit\n"); + fprintf(fd, "%%%%Origin: %ld %ld\n", (long) ox, (long) oy); + /* NB: should use PageBoundingBox */ + fprintf(fd, "%%%%BoundingBox: 0 0 %ld %ld\n", + (long) ceil(pw), (long) ceil(ph)); + fprintf(fd, "%%%%LanguageLevel: %d\n", level2 ? 2 : 1); + fprintf(fd, "%%%%Pages: (atend)\n"); + fprintf(fd, "%%%%EndComments\n"); + fprintf(fd, "%%%%BeginSetup\n"); + if (PSduplex) + fprintf(fd, "%s", DuplexPreamble); + if (PStumble) + fprintf(fd, "%s", TumblePreamble); + if (PSavoiddeadzone && level2) + fprintf(fd, "%s", AvoidDeadZonePreamble); + fprintf(fd, "%%%%EndSetup\n"); +} + +void +PSTail(FILE *fd, int npages) +{ + fprintf(fd, "%%%%Trailer\n"); + fprintf(fd, "%%%%Pages: %d\n", npages); + fprintf(fd, "%%%%EOF\n"); +} + +static int +checkcmap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b) +{ + (void) tif; + while (n-- > 0) + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); + TIFFWarning(filename, "Assuming 8-bit colormap"); + return (8); +} + +static void +PS_Lvl2colorspace(FILE* fd, TIFF* tif) +{ + uint16 *rmap, *gmap, *bmap; + int i, num_colors; + + /* + * Set up PostScript Level 2 colorspace according to + * section 4.8 in the PostScript refenence manual. + */ + fputs("% PostScript Level 2 only.\n", fd); + if (photometric != PHOTOMETRIC_PALETTE) { + if (photometric == PHOTOMETRIC_YCBCR) { + /* MORE CODE HERE */ + } + fprintf(fd, "/Device%s", + samplesperpixel > 2 ? "RGB" : "Gray"); + fputs(" setcolorspace\n", fd); + return; + } + + /* + * Set up an indexed/palette colorspace + */ + num_colors = (1 << bitspersample); + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) { + TIFFError(filename, + "Palette image w/o \"Colormap\" tag"); + return; + } + if (checkcmap(tif, num_colors, rmap, gmap, bmap) == 16) { + /* + * Convert colormap to 8-bits values. + */ +#define CVT(x) (((x) * 255) / ((1L<<16)-1)) + for (i = 0; i < num_colors; i++) { + rmap[i] = CVT(rmap[i]); + gmap[i] = CVT(gmap[i]); + bmap[i] = CVT(bmap[i]); + } +#undef CVT + } + fprintf(fd, "[ /Indexed /DeviceRGB %d", num_colors - 1); + if (ascii85) { + Ascii85Init(); + fputs("\n<~", fd); + ascii85breaklen -= 2; + } else + fputs(" <", fd); + for (i = 0; i < num_colors; i++) { + if (ascii85) { + Ascii85Put(rmap[i], fd); + Ascii85Put(gmap[i], fd); + Ascii85Put(bmap[i], fd); + } else { + fputs((i % 8) ? " " : "\n ", fd); + fprintf(fd, "%02x%02x%02x", + rmap[i], gmap[i], bmap[i]); + } + } + if (ascii85) + Ascii85Flush(fd); + else + fputs(">\n", fd); + fputs("] setcolorspace\n", fd); +} + +static int +PS_Lvl2ImageDict(FILE* fd, TIFF* tif, uint32 w, uint32 h) +{ + int use_rawdata; + uint32 tile_width, tile_height; + uint16 predictor, minsamplevalue, maxsamplevalue; + int repeat_count; + char im_h[64], im_x[64], im_y[64]; + + (void)strcpy(im_x, "0"); + (void)sprintf(im_y, "%lu", (long) h); + (void)sprintf(im_h, "%lu", (long) h); + tile_width = w; + tile_height = h; + if (TIFFIsTiled(tif)) { + repeat_count = TIFFNumberOfTiles(tif); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height); + if (tile_width > w || tile_height > h || + (w % tile_width) != 0 || (h % tile_height != 0)) { + /* + * The tiles does not fit image width and height. + * Set up a clip rectangle for the image unit square. + */ + fputs("0 0 1 1 rectclip\n", fd); + } + if (tile_width < w) { + fputs("/im_x 0 def\n", fd); + (void)strcpy(im_x, "im_x neg"); + } + if (tile_height < h) { + fputs("/im_y 0 def\n", fd); + (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h); + } + } else { + repeat_count = tf_numberstrips; + tile_height = tf_rowsperstrip; + if (tile_height > h) + tile_height = h; + if (repeat_count > 1) { + fputs("/im_y 0 def\n", fd); + fprintf(fd, "/im_h %lu def\n", + (unsigned long) tile_height); + (void)strcpy(im_h, "im_h"); + (void)sprintf(im_y, "%lu im_y sub", (unsigned long) h); + } + } + + /* + * Output start of exec block + */ + fputs("{ % exec\n", fd); + + if (repeat_count > 1) + fprintf(fd, "%d { %% repeat\n", repeat_count); + + /* + * Output filter options and image dictionary. + */ + if (ascii85) + fputs(" /im_stream currentfile /ASCII85Decode filter def\n", + fd); + fputs(" <<\n", fd); + fputs(" /ImageType 1\n", fd); + fprintf(fd, " /Width %lu\n", (unsigned long) tile_width); + fprintf(fd, " /Height %lu\n", (unsigned long) tile_height); + if (planarconfiguration == PLANARCONFIG_SEPARATE && samplesperpixel > 1) + fputs(" /MultipleDataSources true\n", fd); + fprintf(fd, " /ImageMatrix [ %lu 0 0 %ld %s %s ]\n", + (unsigned long) w, - (long)h, im_x, im_y); + fprintf(fd, " /BitsPerComponent %d\n", bitspersample); + fprintf(fd, " /Interpolate %s\n", interpolate ? "true" : "false"); + + switch (samplesperpixel) { + case 1: + switch (photometric) { + case PHOTOMETRIC_MINISBLACK: + fputs(" /Decode [0 1]\n", fd); + break; + case PHOTOMETRIC_MINISWHITE: + switch (compression) { + case COMPRESSION_CCITTRLE: + case COMPRESSION_CCITTRLEW: + case COMPRESSION_CCITTFAX3: + case COMPRESSION_CCITTFAX4: + /* + * Manage inverting with /Blackis1 flag + * since there migth be uncompressed parts + */ + fputs(" /Decode [0 1]\n", fd); + break; + default: + /* + * ERROR... + */ + fputs(" /Decode [1 0]\n", fd); + break; + } + break; + case PHOTOMETRIC_PALETTE: + TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, + &minsamplevalue); + TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, + &maxsamplevalue); + fprintf(fd, " /Decode [%u %u]\n", + minsamplevalue, maxsamplevalue); + break; + default: + /* + * ERROR ? + */ + fputs(" /Decode [0 1]\n", fd); + break; + } + break; + case 3: + switch (photometric) { + case PHOTOMETRIC_RGB: + fputs(" /Decode [0 1 0 1 0 1]\n", fd); + break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + default: + /* + * ERROR?? + */ + fputs(" /Decode [0 1 0 1 0 1]\n", fd); + break; + } + break; + case 4: + /* + * ERROR?? + */ + fputs(" /Decode [0 1 0 1 0 1 0 1]\n", fd); + break; + } + fputs(" /DataSource", fd); + if (planarconfiguration == PLANARCONFIG_SEPARATE && + samplesperpixel > 1) + fputs(" [", fd); + if (ascii85) + fputs(" im_stream", fd); + else + fputs(" currentfile /ASCIIHexDecode filter", fd); + + use_rawdata = TRUE; + switch (compression) { + case COMPRESSION_NONE: /* 1: uncompressed */ + break; + case COMPRESSION_CCITTRLE: /* 2: CCITT modified Huffman RLE */ + case COMPRESSION_CCITTRLEW: /* 32771: #1 w/ word alignment */ + case COMPRESSION_CCITTFAX3: /* 3: CCITT Group 3 fax encoding */ + case COMPRESSION_CCITTFAX4: /* 4: CCITT Group 4 fax encoding */ + fputs("\n\t<<\n", fd); + if (compression == COMPRESSION_CCITTFAX3) { + uint32 g3_options; + + fputs("\t /EndOfLine true\n", fd); + fputs("\t /EndOfBlock false\n", fd); + if (!TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS, + &g3_options)) + g3_options = 0; + if (g3_options & GROUP3OPT_2DENCODING) + fprintf(fd, "\t /K %s\n", im_h); + if (g3_options & GROUP3OPT_UNCOMPRESSED) + fputs("\t /Uncompressed true\n", fd); + if (g3_options & GROUP3OPT_FILLBITS) + fputs("\t /EncodedByteAlign true\n", fd); + } + if (compression == COMPRESSION_CCITTFAX4) { + uint32 g4_options; + + fputs("\t /K -1\n", fd); + TIFFGetFieldDefaulted(tif, TIFFTAG_GROUP4OPTIONS, + &g4_options); + if (g4_options & GROUP4OPT_UNCOMPRESSED) + fputs("\t /Uncompressed true\n", fd); + } + if (!(tile_width == w && w == 1728U)) + fprintf(fd, "\t /Columns %lu\n", + (unsigned long) tile_width); + fprintf(fd, "\t /Rows %s\n", im_h); + if (compression == COMPRESSION_CCITTRLE || + compression == COMPRESSION_CCITTRLEW) { + fputs("\t /EncodedByteAlign true\n", fd); + fputs("\t /EndOfBlock false\n", fd); + } + if (photometric == PHOTOMETRIC_MINISBLACK) + fputs("\t /BlackIs1 true\n", fd); + fprintf(fd, "\t>> /CCITTFaxDecode filter"); + break; + case COMPRESSION_LZW: /* 5: Lempel-Ziv & Welch */ + TIFFGetFieldDefaulted(tif, TIFFTAG_PREDICTOR, &predictor); + if (predictor == 2) { + fputs("\n\t<<\n", fd); + fprintf(fd, "\t /Predictor %u\n", predictor); + fprintf(fd, "\t /Columns %lu\n", + (unsigned long) tile_width); + fprintf(fd, "\t /Colors %u\n", samplesperpixel); + fprintf(fd, "\t /BitsPerComponent %u\n", + bitspersample); + fputs("\t>>", fd); + } + fputs(" /LZWDecode filter", fd); + break; + case COMPRESSION_PACKBITS: /* 32773: Macintosh RLE */ + fputs(" /RunLengthDecode filter", fd); + use_rawdata = TRUE; + break; + case COMPRESSION_OJPEG: /* 6: !6.0 JPEG */ + case COMPRESSION_JPEG: /* 7: %JPEG DCT compression */ +#ifdef notdef + /* + * Code not tested yet + */ + fputs(" /DCTDecode filter", fd); + use_rawdata = TRUE; +#else + use_rawdata = FALSE; +#endif + break; + case COMPRESSION_NEXT: /* 32766: NeXT 2-bit RLE */ + case COMPRESSION_THUNDERSCAN: /* 32809: ThunderScan RLE */ + case COMPRESSION_PIXARFILM: /* 32908: Pixar companded 10bit LZW */ + case COMPRESSION_DEFLATE: /* 32946: Deflate compression */ + case COMPRESSION_JBIG: /* 34661: ISO JBIG */ + use_rawdata = FALSE; + break; + case COMPRESSION_SGILOG: /* 34676: SGI LogL or LogLuv */ + case COMPRESSION_SGILOG24: /* 34677: SGI 24-bit LogLuv */ + use_rawdata = FALSE; + break; + default: + /* + * ERROR... + */ + use_rawdata = FALSE; + break; + } + if (planarconfiguration == PLANARCONFIG_SEPARATE && + samplesperpixel > 1) { + uint16 i; + + /* + * NOTE: This code does not work yet... + */ + for (i = 1; i < samplesperpixel; i++) + fputs(" dup", fd); + fputs(" ]", fd); + } + fputs("\n >> image\n", fd); + if (ascii85) + fputs(" im_stream flushfile\n", fd); + if (repeat_count > 1) { + if (tile_width < w) { + fprintf(fd, " /im_x im_x %lu add def\n", + (unsigned long) tile_width); + if (tile_height < h) { + fprintf(fd, " im_x %lu ge {\n", + (unsigned long) w); + fputs(" /im_x 0 def\n", fd); + fprintf(fd, " /im_y im_y %lu add def\n", + (unsigned long) tile_height); + fputs(" } if\n", fd); + } + } + if (tile_height < h) { + if (tile_width >= w) { + fprintf(fd, " /im_y im_y %lu add def\n", + (unsigned long) tile_height); + if (!TIFFIsTiled(tif)) { + fprintf(fd, " /im_h %lu im_y sub", + (unsigned long) h); + fprintf(fd, " dup %lu gt { pop", + (unsigned long) tile_height); + fprintf(fd, " %lu } if def\n", + (unsigned long) tile_height); + } + } + } + fputs("} repeat\n", fd); + } + /* + * End of exec function + */ + fputs("}\n", fd); + + return(use_rawdata); +} + +int +PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h) +{ + uint16 fillorder; + int use_rawdata, tiled_image, breaklen; + uint32 chunk_no, num_chunks, *bc; + unsigned char *buf_data, *cp; + tsize_t chunk_size, byte_count; + + PS_Lvl2colorspace(fd, tif); + use_rawdata = PS_Lvl2ImageDict(fd, tif, w, h); + + fputs("%%BeginData:\n", fd); + fputs("exec\n", fd); + + tiled_image = TIFFIsTiled(tif); + if (tiled_image) { + num_chunks = TIFFNumberOfTiles(tif); + TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &bc); + } else { + num_chunks = TIFFNumberOfStrips(tif); + TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc); + } + + if (use_rawdata) { + chunk_size = bc[0]; + for (chunk_no = 1; chunk_no < num_chunks; chunk_no++) + if (bc[chunk_no] > chunk_size) + chunk_size = bc[chunk_no]; + } else { + if (tiled_image) + chunk_size = TIFFTileSize(tif); + else + chunk_size = TIFFStripSize(tif); + } + buf_data = (unsigned char *)_TIFFmalloc(chunk_size); + if (!buf_data) { + TIFFError(filename, "Can't alloc %u bytes for %s.", + chunk_size, tiled_image ? "tiles" : "strips"); + return(FALSE); + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder); + for (chunk_no = 0; chunk_no < num_chunks; chunk_no++) { + if (ascii85) + Ascii85Init(); + else + breaklen = 36; + if (use_rawdata) { + if (tiled_image) + byte_count = TIFFReadRawTile(tif, chunk_no, + buf_data, chunk_size); + else + byte_count = TIFFReadRawStrip(tif, chunk_no, + buf_data, chunk_size); + if (fillorder == FILLORDER_LSB2MSB) + TIFFReverseBits(buf_data, byte_count); + } else { + if (tiled_image) + byte_count = TIFFReadEncodedTile(tif, + chunk_no, buf_data, + chunk_size); + else + byte_count = TIFFReadEncodedStrip(tif, + chunk_no, buf_data, + chunk_size); + } + if (byte_count < 0) { + TIFFError(filename, "Can't read %s %d.", + tiled_image ? "tile" : "strip", chunk_no); + if (ascii85) + Ascii85Put('\0', fd); + } + for (cp = buf_data; byte_count > 0; byte_count--) { + if (ascii85) + Ascii85Put(*cp++, fd); + else { + if (--breaklen <= 0) { + putc('\n', fd); + breaklen = 36; + } + putc(hex[((*cp)>>4)&0xf], fd); + putc(hex[(*cp)&0xf], fd); + cp++; + } + } + if (ascii85) + Ascii85Flush(fd); + else + putc('\n', fd); + } + _TIFFfree(buf_data); + fputs("%%EndData\n", fd); + return(TRUE); +} + +void +PSpage(FILE* fd, TIFF* tif, uint32 w, uint32 h) +{ + if (level2 && PS_Lvl2page(fd, tif, w, h)) + return; + ps_bytesperrow = tf_bytesperrow; + switch (photometric) { + case PHOTOMETRIC_RGB: + if (planarconfiguration == PLANARCONFIG_CONTIG) { + fprintf(fd, "%s", RGBcolorimage); + PSColorContigPreamble(fd, w, h, 3); + PSDataColorContig(fd, tif, w, h, 3); + } else { + PSColorSeparatePreamble(fd, w, h, 3); + PSDataColorSeparate(fd, tif, w, h, 3); + } + break; + case PHOTOMETRIC_SEPARATED: + /* XXX should emit CMYKcolorimage */ + if (planarconfiguration == PLANARCONFIG_CONTIG) { + PSColorContigPreamble(fd, w, h, 4); + PSDataColorContig(fd, tif, w, h, 4); + } else { + PSColorSeparatePreamble(fd, w, h, 4); + PSDataColorSeparate(fd, tif, w, h, 4); + } + break; + case PHOTOMETRIC_PALETTE: + fprintf(fd, "%s", RGBcolorimage); + PhotoshopBanner(fd, w, h, 1, 3, "false 3 colorimage"); + fprintf(fd, "/scanLine %ld string def\n", + (long) ps_bytesperrow); + fprintf(fd, "%lu %lu 8\n", + (unsigned long) w, (unsigned long) h); + fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", + (unsigned long) w, (unsigned long) h, (unsigned long) h); + fprintf(fd, "{currentfile scanLine readhexstring pop} bind\n"); + fprintf(fd, "false 3 colorimage\n"); + PSDataPalette(fd, tif, w, h); + break; + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + PhotoshopBanner(fd, w, h, 1, 1, "image"); + fprintf(fd, "/scanLine %ld string def\n", + (long) ps_bytesperrow); + fprintf(fd, "%lu %lu %d\n", + (unsigned long) w, (unsigned long) h, bitspersample); + fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", + (unsigned long) w, (unsigned long) h, (unsigned long) h); + fprintf(fd, + "{currentfile scanLine readhexstring pop} bind\n"); + fprintf(fd, "image\n"); + PSDataBW(fd, tif, w, h); + break; + } + putc('\n', fd); +} + +void +PSColorContigPreamble(FILE* fd, uint32 w, uint32 h, int nc) +{ + ps_bytesperrow = nc * (tf_bytesperrow / samplesperpixel); + PhotoshopBanner(fd, w, h, 1, nc, "false %d colorimage"); + fprintf(fd, "/line %ld string def\n", (long) ps_bytesperrow); + fprintf(fd, "%lu %lu %d\n", + (unsigned long) w, (unsigned long) h, bitspersample); + fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", + (unsigned long) w, (unsigned long) h, (unsigned long) h); + fprintf(fd, "{currentfile line readhexstring pop} bind\n"); + fprintf(fd, "false %d colorimage\n", nc); +} + +void +PSColorSeparatePreamble(FILE* fd, uint32 w, uint32 h, int nc) +{ + int i; + + PhotoshopBanner(fd, w, h, ps_bytesperrow, nc, "true %d colorimage"); + for (i = 0; i < nc; i++) + fprintf(fd, "/line%d %ld string def\n", + i, (long) ps_bytesperrow); + fprintf(fd, "%lu %lu %d\n", + (unsigned long) w, (unsigned long) h, bitspersample); + fprintf(fd, "[%lu 0 0 -%lu 0 %lu] \n", + (unsigned long) w, (unsigned long) h, (unsigned long) h); + for (i = 0; i < nc; i++) + fprintf(fd, "{currentfile line%d readhexstring pop}bind\n", i); + fprintf(fd, "true %d colorimage\n", nc); +} + +#define MAXLINE 36 +#define DOBREAK(len, howmany, fd) \ + if (((len) -= (howmany)) <= 0) { \ + putc('\n', fd); \ + (len) = MAXLINE-(howmany); \ + } +#define PUTHEX(c,fd) putc(hex[((c)>>4)&0xf],fd); putc(hex[(c)&0xf],fd) + +void +PSDataColorContig(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) +{ + uint32 row; + int breaklen = MAXLINE, cc, es = samplesperpixel - nc; + unsigned char *tf_buf; + unsigned char *cp, c; + + (void) w; + tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); + if (tf_buf == NULL) { + TIFFError(filename, "No space for scanline buffer"); + return; + } + for (row = 0; row < h; row++) { + if (TIFFReadScanline(tif, tf_buf, row, 0) < 0) + break; + cp = tf_buf; + if (alpha) { + int adjust; + cc = 0; + for (; cc < tf_bytesperrow; cc += samplesperpixel) { + DOBREAK(breaklen, nc, fd); + /* + * For images with alpha, matte against + * a white background; i.e. + * Cback * (1 - Aimage) + * where Cback = 1. + */ + adjust = 255 - cp[nc]; + switch (nc) { + case 4: c = *cp++ + adjust; PUTHEX(c,fd); + case 3: c = *cp++ + adjust; PUTHEX(c,fd); + case 2: c = *cp++ + adjust; PUTHEX(c,fd); + case 1: c = *cp++ + adjust; PUTHEX(c,fd); + } + cp += es; + } + } else { + cc = 0; + for (; cc < tf_bytesperrow; cc += samplesperpixel) { + DOBREAK(breaklen, nc, fd); + switch (nc) { + case 4: c = *cp++; PUTHEX(c,fd); + case 3: c = *cp++; PUTHEX(c,fd); + case 2: c = *cp++; PUTHEX(c,fd); + case 1: c = *cp++; PUTHEX(c,fd); + } + cp += es; + } + } + } + _TIFFfree((char *) tf_buf); +} + +void +PSDataColorSeparate(FILE* fd, TIFF* tif, uint32 w, uint32 h, int nc) +{ + uint32 row; + int breaklen = MAXLINE, cc, s, maxs; + unsigned char *tf_buf; + unsigned char *cp, c; + + (void) w; + tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); + if (tf_buf == NULL) { + TIFFError(filename, "No space for scanline buffer"); + return; + } + maxs = (samplesperpixel > nc ? nc : samplesperpixel); + for (row = 0; row < h; row++) { + for (s = 0; s < maxs; s++) { + if (TIFFReadScanline(tif, tf_buf, row, s) < 0) + break; + for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) { + DOBREAK(breaklen, 1, fd); + c = *cp++; + PUTHEX(c,fd); + } + } + } + _TIFFfree((char *) tf_buf); +} + +#define PUTRGBHEX(c,fd) \ + PUTHEX(rmap[c],fd); PUTHEX(gmap[c],fd); PUTHEX(bmap[c],fd) + +void +PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h) +{ + uint16 *rmap, *gmap, *bmap; + uint32 row; + int breaklen = MAXLINE, cc, nc; + unsigned char *tf_buf; + unsigned char *cp, c; + + (void) w; + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) { + TIFFError(filename, "Palette image w/o \"Colormap\" tag"); + return; + } + switch (bitspersample) { + case 8: case 4: case 2: case 1: + break; + default: + TIFFError(filename, "Depth %d not supported", bitspersample); + return; + } + nc = 3 * (8 / bitspersample); + tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow); + if (tf_buf == NULL) { + TIFFError(filename, "No space for scanline buffer"); + return; + } + if (checkcmap(tif, 1<= 0; i--) { + rmap[i] = CVT(rmap[i]); + gmap[i] = CVT(gmap[i]); + bmap[i] = CVT(bmap[i]); + } +#undef CVT + } + for (row = 0; row < h; row++) { + if (TIFFReadScanline(tif, tf_buf, row, 0) < 0) + break; + for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) { + DOBREAK(breaklen, nc, fd); + switch (bitspersample) { + case 8: + c = *cp++; PUTRGBHEX(c, fd); + break; + case 4: + c = *cp++; PUTRGBHEX(c&0xf, fd); + c >>= 4; PUTRGBHEX(c, fd); + break; + case 2: + c = *cp++; PUTRGBHEX(c&0x3, fd); + c >>= 2; PUTRGBHEX(c&0x3, fd); + c >>= 2; PUTRGBHEX(c&0x3, fd); + c >>= 2; PUTRGBHEX(c, fd); + break; + case 1: + c = *cp++; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c&0x1, fd); + c >>= 1; PUTRGBHEX(c, fd); + break; + } + } + } + _TIFFfree((char *) tf_buf); +} + +void +PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) +{ + int breaklen = MAXLINE; + unsigned char* tf_buf; + unsigned char* cp; + tsize_t stripsize = TIFFStripSize(tif); + tstrip_t s; + + (void) w; (void) h; + tf_buf = (unsigned char *) _TIFFmalloc(stripsize); + if (tf_buf == NULL) { + TIFFError(filename, "No space for scanline buffer"); + return; + } + if (ascii85) + Ascii85Init(); + for (s = 0; s < TIFFNumberOfStrips(tif); s++) { + int cc = TIFFReadEncodedStrip(tif, s, tf_buf, stripsize); + if (cc < 0) { + TIFFError(filename, "Can't read strip"); + break; + } + cp = tf_buf; + if (photometric == PHOTOMETRIC_MINISWHITE) { + for (cp += cc; --cp >= tf_buf;) + *cp = ~*cp; + cp++; + } + if (ascii85) { + while (cc-- > 0) + Ascii85Put(*cp++, fd); + } else { + while (cc-- > 0) { + unsigned char c = *cp++; + DOBREAK(breaklen, 1, fd); + PUTHEX(c, fd); + } + } + } + if (ascii85) + Ascii85Flush(fd); + else if (level2) + fputs(">\n", fd); + _TIFFfree(tf_buf); +} + +void +PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h) +{ + uint32 *bc; + uint32 bufsize; + int breaklen = MAXLINE, cc; + uint16 fillorder; + unsigned char *tf_buf; + unsigned char *cp, c; + tstrip_t s; + + (void) w; (void) h; + TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder); + TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc); + bufsize = bc[0]; + tf_buf = (unsigned char*) _TIFFmalloc(bufsize); + if (tf_buf == NULL) { + TIFFError(filename, "No space for strip buffer"); + return; + } + for (s = 0; s < tf_numberstrips; s++) { + if (bc[s] > bufsize) { + tf_buf = (unsigned char *) _TIFFrealloc(tf_buf, bc[s]); + if (tf_buf == NULL) { + TIFFError(filename, + "No space for strip buffer"); + return; + } + bufsize = bc[s]; + } + cc = TIFFReadRawStrip(tif, s, tf_buf, bc[s]); + if (cc < 0) { + TIFFError(filename, "Can't read strip"); + break; + } + if (fillorder == FILLORDER_LSB2MSB) + TIFFReverseBits(tf_buf, cc); + if (!ascii85) { + for (cp = tf_buf; cc > 0; cc--) { + DOBREAK(breaklen, 1, fd); + c = *cp++; + PUTHEX(c, fd); + } + fputs(">\n", fd); + breaklen = MAXLINE; + } else { + Ascii85Init(); + for (cp = tf_buf; cc > 0; cc--) + Ascii85Put(*cp++, fd); + Ascii85Flush(fd); + } + } + _TIFFfree((char *) tf_buf); +} + +void +Ascii85Init(void) +{ + ascii85breaklen = 2*MAXLINE; + ascii85count = 0; +} + +static char* +Ascii85Encode(unsigned char* raw) +{ + static char encoded[6]; + uint32 word; + + word = (((raw[0]<<8)+raw[1])<<16) + (raw[2]<<8) + raw[3]; + if (word != 0L) { + uint32 q; + uint16 w1; + + q = word / (85L*85*85*85); /* actually only a byte */ + encoded[0] = q + '!'; + + word -= q * (85L*85*85*85); q = word / (85L*85*85); + encoded[1] = q + '!'; + + word -= q * (85L*85*85); q = word / (85*85); + encoded[2] = q + '!'; + + w1 = (uint16) (word - q*(85L*85)); + encoded[3] = (w1 / 85) + '!'; + encoded[4] = (w1 % 85) + '!'; + encoded[5] = '\0'; + } else + encoded[0] = 'z', encoded[1] = '\0'; + return (encoded); +} + +void +Ascii85Put(unsigned char code, FILE* fd) +{ + ascii85buf[ascii85count++] = code; + if (ascii85count >= 4) { + unsigned char* p; + int n; + + for (n = ascii85count, p = ascii85buf; n >= 4; n -= 4, p += 4) { + char* cp; + for (cp = Ascii85Encode(p); *cp; cp++) { + putc(*cp, fd); + if (--ascii85breaklen == 0) { + putc('\n', fd); + ascii85breaklen = 2*MAXLINE; + } + } + } + _TIFFmemcpy(ascii85buf, p, n); + ascii85count = n; + } +} + +void +Ascii85Flush(FILE* fd) +{ + if (ascii85count > 0) { + char* res; + _TIFFmemset(&ascii85buf[ascii85count], 0, 3); + res = Ascii85Encode(ascii85buf); + fwrite(res[0] == 'z' ? "!!!!" : res, ascii85count + 1, 1, fd); + } + fputs("~>\n", fd); +} + +char* stuff[] = { +"usage: tiff2ps [options] input.tif ...", +"where options are:", +" -1 generate PostScript Level I (default)", +" -2 generate PostScript Level II", +" -8 disable use of ASCII85 encoding with PostScript Level II", +" -d # convert directory number #", +" -D enable duplex printing (two pages per sheet of paper)", +" -e generate Encapsulated PostScript (EPS)", +" -h # assume printed page height is # inches (default 11)", +" -o # convert directory at file offset #", +" -O file write PostScript to file instead of standard output", +" -a convert all directories in file (default is first)", +" -p generate regular PostScript", +" -s generate PostScript for a single image", +" -T print pages for top edge binding", +" -w # assume printed page width is # inches (default 8.5)", +" -z enable printing in the deadzone (only for PostScript Level II)", +NULL +}; + +static void +usage(int code) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(code); +} diff --git a/tools/tiffcmp.c b/tools/tiffcmp.c new file mode 100644 index 00000000..3fceaaa1 --- /dev/null +++ b/tools/tiffcmp.c @@ -0,0 +1,483 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffcmp.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "tiffio.h" + +static int stopondiff = 1; +static int stoponfirsttag = 1; +static uint16 bitspersample = 1; +static uint16 samplesperpixel = 1; +static uint32 imagewidth; +static uint32 imagelength; + +static int tiffcmp(TIFF*, TIFF*); +static int cmptags(TIFF*, TIFF*); +static void ContigCompare(int, uint32, unsigned char*, unsigned char*, int); +static void PrintDiff(uint32, int, uint32, int, int); +static void SeparateCompare(int, int, uint32, unsigned char*, unsigned char*); +static void eof(const char*, uint32, int); + +static void +usage(void) +{ + fprintf(stderr, "Usage: tiffcmp [-l] [-t] [-z] file1 file2\n"); + exit(-3); +} + +int +main(int argc, char* argv[]) +{ + TIFF *tif1, *tif2; + int c, dirnum; + extern int optind; + + while ((c = getopt(argc, argv, "ltz")) != -1) + switch (c) { + case 'l': + stopondiff = 0; + break; + case 'z': + stopondiff += 100; + break; + case 't': + stoponfirsttag = 0; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind < 2) + usage(); + tif1 = TIFFOpen(argv[optind], "r"); + if (tif1 == NULL) + return (-1); + tif2 = TIFFOpen(argv[optind+1], "r"); + if (tif2 == NULL) + return (-2); + dirnum = 0; + while (tiffcmp(tif1, tif2)) { + if (!TIFFReadDirectory(tif1)) { + if (!TIFFReadDirectory(tif2)) + break; + printf("No more directories for %s\n", + TIFFFileName(tif1)); + return (1); + } else if (!TIFFReadDirectory(tif2)) { + printf("No more directories for %s\n", + TIFFFileName(tif2)); + return (1); + } + printf("Directory %d:\n", ++dirnum); + } + return (0); +} + +#define checkEOF(tif, row, sample) { \ + eof(TIFFFileName(tif), row, sample); \ + goto bad; \ +} + +static int CheckShortTag(TIFF*, TIFF*, int, char*); +static int CheckShort2Tag(TIFF*, TIFF*, int, char*); +static int CheckShortArrayTag(TIFF*, TIFF*, int, char*); +static int CheckLongTag(TIFF*, TIFF*, int, char*); +static int CheckFloatTag(TIFF*, TIFF*, int, char*); +static int CheckStringTag(TIFF*, TIFF*, int, char*); + +static int +tiffcmp(TIFF* tif1, TIFF* tif2) +{ + uint16 config1, config2; + tsize_t size1; + uint32 s, row; + unsigned char *buf1, *buf2; + + if (!CheckShortTag(tif1, tif2, TIFFTAG_BITSPERSAMPLE, "BitsPerSample")) + return (0); + if (!CheckShortTag(tif1, tif2, TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel")) + return (0); + if (!CheckLongTag(tif1, tif2, TIFFTAG_IMAGEWIDTH, "ImageWidth")) + return (0); + if (!cmptags(tif1, tif2)) + return (1); + (void) TIFFGetField(tif1, TIFFTAG_BITSPERSAMPLE, &bitspersample); + (void) TIFFGetField(tif1, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + (void) TIFFGetField(tif1, TIFFTAG_IMAGEWIDTH, &imagewidth); + (void) TIFFGetField(tif1, TIFFTAG_IMAGELENGTH, &imagelength); + (void) TIFFGetField(tif1, TIFFTAG_PLANARCONFIG, &config1); + (void) TIFFGetField(tif2, TIFFTAG_PLANARCONFIG, &config2); + buf1 = (unsigned char *)_TIFFmalloc(size1 = TIFFScanlineSize(tif1)); + buf2 = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif2)); + if (buf1 == NULL || buf2 == NULL) { + fprintf(stderr, "No space for scanline buffers\n"); + exit(-1); + } + if (config1 != config2 && bitspersample != 8 && samplesperpixel > 1) { + fprintf(stderr, +"Can't handle different planar configuration w/ different bits/sample\n"); + goto bad; + } +#define pack(a,b) ((a)<<8)|(b) + switch (pack(config1, config2)) { + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG): + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(tif2, buf2, row, 0) < 0) + checkEOF(tif2, row, -1) + for (s = 0; s < samplesperpixel; s++) { + if (TIFFReadScanline(tif1, buf1, row, s) < 0) + checkEOF(tif1, row, s) + SeparateCompare(1, s, row, buf2, buf1); + } + } + break; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE): + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(tif1, buf1, row, 0) < 0) + checkEOF(tif1, row, -1) + for (s = 0; s < samplesperpixel; s++) { + if (TIFFReadScanline(tif2, buf2, row, s) < 0) + checkEOF(tif2, row, s) + SeparateCompare(0, s, row, buf1, buf2); + } + } + break; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE): + for (s = 0; s < samplesperpixel; s++) + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(tif1, buf1, row, s) < 0) + checkEOF(tif1, row, s) + if (TIFFReadScanline(tif2, buf2, row, s) < 0) + checkEOF(tif2, row, s) + ContigCompare(s, row, buf1, buf2, size1); + } + break; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG): + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(tif1, buf1, row, 0) < 0) + checkEOF(tif1, row, -1) + if (TIFFReadScanline(tif2, buf2, row, 0) < 0) + checkEOF(tif2, row, -1) + ContigCompare(-1, row, buf1, buf2, size1); + } + break; + } + if (buf1) _TIFFfree(buf1); + if (buf2) _TIFFfree(buf2); + return (1); +bad: + if (stopondiff) + exit(1); + if (buf1) _TIFFfree(buf1); + if (buf2) _TIFFfree(buf2); + return (0); +} + +#define CmpShortField(tag, name) \ + if (!CheckShortTag(tif1, tif2, tag, name) && stoponfirsttag) return (0) +#define CmpShortField2(tag, name) \ + if (!CheckShort2Tag(tif1, tif2, tag, name) && stoponfirsttag) return (0) +#define CmpLongField(tag, name) \ + if (!CheckLongTag(tif1, tif2, tag, name) && stoponfirsttag) return (0) +#define CmpFloatField(tag, name) \ + if (!CheckFloatTag(tif1, tif2, tag, name) && stoponfirsttag) return (0) +#define CmpStringField(tag, name) \ + if (!CheckStringTag(tif1, tif2, tag, name) && stoponfirsttag) return (0) +#define CmpShortArrayField(tag, name) \ + if (!CheckShortArrayTag(tif1, tif2, tag, name) && stoponfirsttag) return (0) + +static int +cmptags(TIFF* tif1, TIFF* tif2) +{ + CmpLongField(TIFFTAG_SUBFILETYPE, "SubFileType"); + CmpLongField(TIFFTAG_IMAGEWIDTH, "ImageWidth"); + CmpLongField(TIFFTAG_IMAGELENGTH, "ImageLength"); + CmpShortField(TIFFTAG_BITSPERSAMPLE, "BitsPerSample"); + CmpShortField(TIFFTAG_COMPRESSION, "Compression"); + CmpShortField(TIFFTAG_PREDICTOR, "Predictor"); + CmpShortField(TIFFTAG_PHOTOMETRIC, "PhotometricInterpretation"); + CmpShortField(TIFFTAG_THRESHHOLDING, "Thresholding"); + CmpShortField(TIFFTAG_FILLORDER, "FillOrder"); + CmpShortField(TIFFTAG_ORIENTATION, "Orientation"); + CmpShortField(TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel"); + CmpShortField(TIFFTAG_MINSAMPLEVALUE, "MinSampleValue"); + CmpShortField(TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue"); + CmpFloatField(TIFFTAG_XRESOLUTION, "XResolution"); + CmpFloatField(TIFFTAG_YRESOLUTION, "YResolution"); + CmpLongField(TIFFTAG_GROUP3OPTIONS, "Group3Options"); + CmpLongField(TIFFTAG_GROUP4OPTIONS, "Group4Options"); + CmpShortField(TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit"); + CmpShortField(TIFFTAG_PLANARCONFIG, "PlanarConfiguration"); + CmpLongField(TIFFTAG_ROWSPERSTRIP, "RowsPerStrip"); + CmpFloatField(TIFFTAG_XPOSITION, "XPosition"); + CmpFloatField(TIFFTAG_YPOSITION, "YPosition"); + CmpShortField(TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit"); + CmpShortField(TIFFTAG_COLORRESPONSEUNIT, "ColorResponseUnit"); +#ifdef notdef + { uint16 *graycurve; + CmpField(TIFFTAG_GRAYRESPONSECURVE, graycurve); + } + { uint16 *red, *green, *blue; + CmpField3(TIFFTAG_COLORRESPONSECURVE, red, green, blue); + } + { uint16 *red, *green, *blue; + CmpField3(TIFFTAG_COLORMAP, red, green, blue); + } +#endif + CmpShortField2(TIFFTAG_PAGENUMBER, "PageNumber"); + CmpStringField(TIFFTAG_ARTIST, "Artist"); + CmpStringField(TIFFTAG_IMAGEDESCRIPTION,"ImageDescription"); + CmpStringField(TIFFTAG_MAKE, "Make"); + CmpStringField(TIFFTAG_MODEL, "Model"); + CmpStringField(TIFFTAG_SOFTWARE, "Software"); + CmpStringField(TIFFTAG_DATETIME, "DateTime"); + CmpStringField(TIFFTAG_HOSTCOMPUTER, "HostComputer"); + CmpStringField(TIFFTAG_PAGENAME, "PageName"); + CmpStringField(TIFFTAG_DOCUMENTNAME, "DocumentName"); + CmpShortField(TIFFTAG_MATTEING, "Matteing"); + CmpShortArrayField(TIFFTAG_EXTRASAMPLES,"ExtraSamples"); + return (1); +} + +static void +ContigCompare(int sample, uint32 row, unsigned char* p1, unsigned char* p2, int size) +{ + register uint32 pix; + register int ppb = 8/bitspersample; + + if (memcmp(p1, p2, size) == 0) + return; + switch (bitspersample) { + case 1: case 2: case 4: case 8: { + register unsigned char *pix1 = p1, *pix2 = p2; + + for (pix = 0; pix < imagewidth; pix1++, pix2++, pix += ppb) + if (*pix1 != *pix2) + PrintDiff(row, sample, pix, + *pix1, *pix2); + break; + } + case 16: { + register uint16 *pix1 = (uint16 *)p1, *pix2 = (uint16 *)p2; + + for (pix = 0; pix < imagewidth; pix1++, pix2++, pix++) + if (*pix1 != *pix2) + PrintDiff(row, sample, pix, + *pix1, *pix2); + break; + } + } +} + +static void +PrintDiff(uint32 row, int sample, uint32 pix, int w1, int w2) +{ + register int mask1, mask2, s, bps; + + if (sample < 0) + sample = 0; + bps = bitspersample; + switch (bps) { + case 1: + case 2: + case 4: + mask1 = ~((-1)<>= bps, s -= bps, pix++) { + if ((w1 & mask2) ^ (w2 & mask2)) { + printf( + "Scanline %lu, pixel %lu, sample %d: %01x %01x\n", + (long) row, (long) pix, + sample, (w1 >> s) & mask1, + (w2 >> s) & mask1 ); + if (--stopondiff == 0) + exit(1); + } + } + break; + case 8: + printf("Scanline %lu, pixel %lu, sample %d: %02x %02x\n", + (long) row, (long) pix, sample, w1, w2); + if (--stopondiff) + exit(1); + break; + case 16: + printf("Scanline %lu, pixel %lu, sample %d: %04x %04x\n", + (long) row, (long) pix, sample, w1, w2); + if (--stopondiff) + exit(1); + break; + } +} + +static void +SeparateCompare(int reversed, int sample, uint32 row, unsigned char* cp1, unsigned char* p2) +{ + uint32 npixels = imagewidth; + register int pixel; + + cp1 += sample; + for (pixel = 0; npixels-- > 0; pixel++, cp1 += samplesperpixel, p2++) + if (*cp1 != *p2) { + printf("Scanline %lu, pixel %lu, sample %ld: ", + (long) row, (long) pixel, (long) sample); + if (reversed) + printf("%02x %02x\n", *p2, *cp1); + else + printf("%02x %02x\n", *cp1, *p2); + if (--stopondiff) + exit(1); + } +} + +static int +checkTag(TIFF* tif1, TIFF* tif2, int tag, char* name, void* p1, void* p2) +{ + + if (TIFFGetField(tif1, tag, p1)) { + if (!TIFFGetField(tif2, tag, p2)) { + printf("%s tag appears only in %s\n", + name, TIFFFileName(tif1)); + return (0); + } + return (1); + } else if (TIFFGetField(tif2, tag, p2)) { + printf("%s tag appears only in %s\n", name, TIFFFileName(tif2)); + return (0); + } + return (-1); +} + +#define CHECK(cmp, fmt) { \ + switch (checkTag(tif1,tif2,tag,name,&v1,&v2)) { \ + case 1: if (cmp) \ + case -1: return (1); \ + printf(fmt, name, v1, v2); \ + } \ + return (0); \ +} + +static int +CheckShortTag(TIFF* tif1, TIFF* tif2, int tag, char* name) +{ + uint16 v1, v2; + CHECK(v1 == v2, "%s: %u %u\n"); +} + +static int +CheckShort2Tag(TIFF* tif1, TIFF* tif2, int tag, char* name) +{ + uint16 v11, v12, v21, v22; + + if (TIFFGetField(tif1, tag, &v11, &v12)) { + if (!TIFFGetField(tif2, tag, &v21, &v22)) { + printf("%s tag appears only in %s\n", + name, TIFFFileName(tif1)); + return (0); + } + if (v11 == v21 && v12 == v22) + return (1); + printf("%s: <%u,%u> <%u,%u>\n", name, v11, v12, v21, v22); + } else if (TIFFGetField(tif2, tag, &v21, &v22)) + printf("%s tag appears only in %s\n", name, TIFFFileName(tif2)); + else + return (1); + return (0); +} + +static int +CheckShortArrayTag(TIFF* tif1, TIFF* tif2, int tag, char* name) +{ + uint16 n1, *a1; + uint16 n2, *a2; + + if (TIFFGetField(tif1, tag, &n1, &a1)) { + if (!TIFFGetField(tif2, tag, &n2, &a2)) { + printf("%s tag appears only in %s\n", + name, TIFFFileName(tif1)); + return (0); + } + if (n1 == n2) { + char* sep; + uint16 i; + + if (memcmp(a1, a2, n1) == 0) + return (1); + printf("%s: value mismatch, <%u:", name, n1); + sep = ""; + for (i = 0; i < n1; i++) + printf("%s%u", sep, a1[i]), sep = ","; + printf("> and <%u: ", n2); + sep = ""; + for (i = 0; i < n2; i++) + printf("%s%u", sep, a2[i]), sep = ","; + printf(">\n"); + } else + printf("%s: %u items in %s, %u items in %s", name, + n1, TIFFFileName(tif1), + n2, TIFFFileName(tif2) + ); + } else if (TIFFGetField(tif2, tag, &n2, &a2)) + printf("%s tag appears only in %s\n", name, TIFFFileName(tif2)); + else + return (1); + return (0); +} + +static int +CheckLongTag(TIFF* tif1, TIFF* tif2, int tag, char* name) +{ + uint32 v1, v2; + CHECK(v1 == v2, "%s: %lu %lu\n"); +} + +static int +CheckFloatTag(TIFF* tif1, TIFF* tif2, int tag, char* name) +{ + float v1, v2; + CHECK(v1 == v2, "%s: %g %g\n"); +} + +static int +CheckStringTag(TIFF* tif1, TIFF* tif2, int tag, char* name) +{ + char *v1, *v2; + CHECK(strcmp(v1, v2) == 0, "%s: \"%s\" \"%s\"\n"); +} + +static void +eof(const char* name, uint32 row, int s) +{ + + printf("%s: EOF at scanline %lu", name, row); + if (s >= 0) + printf(", sample %d", s); + printf("\n"); +} diff --git a/tools/tiffcp.c b/tools/tiffcp.c new file mode 100644 index 00000000..a21f3aea --- /dev/null +++ b/tools/tiffcp.c @@ -0,0 +1,1266 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffcp.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include "tiffio.h" + +#if defined(VMS) +#define unlink delete +#endif + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +#define TRUE 1 +#define FALSE 0 + +static int outtiled = -1; +static uint32 tilewidth; +static uint32 tilelength; + +static uint16 config; +static uint16 compression; +static uint16 predictor; +static uint16 fillorder; +static uint32 rowsperstrip; +static uint32 g3opts; +static int ignore = FALSE; /* if true, ignore read errors */ +static uint32 defg3opts = (uint32) -1; +static int quality = 75; /* JPEG quality */ +static int jpegcolormode = JPEGCOLORMODE_RGB; +static uint16 defcompression = (uint16) -1; +static uint16 defpredictor = (uint16) -1; + +static int tiffcp(TIFF*, TIFF*); +static int processCompressOptions(char*); +static void usage(void); + +int +main(int argc, char* argv[]) +{ + uint16 defconfig = (uint16) -1; + uint16 deffillorder = 0; + uint32 deftilewidth = (uint32) -1; + uint32 deftilelength = (uint32) -1; + uint32 defrowsperstrip = (uint32) -1; + uint32 diroff = 0; + TIFF* in; + TIFF* out; + char mode[10]; + char* mp = mode; + int c; + extern int optind; + extern char* optarg; + + *mp++ = 'w'; + *mp = '\0'; + while ((c = getopt(argc, argv, "c:f:l:o:p:r:w:aistBLMC")) != -1) + switch (c) { + case 'a': /* append to output */ + mode[0] = 'a'; + break; + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'f': /* fill order */ + if (streq(optarg, "lsb2msb")) + deffillorder = FILLORDER_LSB2MSB; + else if (streq(optarg, "msb2lsb")) + deffillorder = FILLORDER_MSB2LSB; + else + usage(); + break; + case 'i': /* ignore errors */ + ignore = TRUE; + break; + case 'l': /* tile length */ + outtiled = TRUE; + deftilelength = atoi(optarg); + break; + case 'o': /* initial directory offset */ + diroff = strtoul(optarg, NULL, 0); + break; + case 'p': /* planar configuration */ + if (streq(optarg, "separate")) + defconfig = PLANARCONFIG_SEPARATE; + else if (streq(optarg, "contig")) + defconfig = PLANARCONFIG_CONTIG; + else + usage(); + break; + case 'r': /* rows/strip */ + defrowsperstrip = atoi(optarg); + break; + case 's': /* generate stripped output */ + outtiled = FALSE; + break; + case 't': /* generate tiled output */ + outtiled = TRUE; + break; + case 'w': /* tile width */ + outtiled = TRUE; + deftilewidth = atoi(optarg); + break; + case 'B': + *mp++ = 'b'; *mp = '\0'; + break; + case 'L': + *mp++ = 'l'; *mp = '\0'; + break; + case 'M': + *mp++ = 'm'; *mp = '\0'; + break; + case 'C': + *mp++ = 'c'; *mp = '\0'; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind < 2) + usage(); + out = TIFFOpen(argv[argc-1], mode); + if (out == NULL) + return (-2); + mode[0] = 'r'; + for (; optind < argc-1 ; optind++) { + in = TIFFOpen(argv[optind], mode); + if (in == NULL) + return (-3); + if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) { + TIFFError(TIFFFileName(in), + "Error, setting subdirectory at %#x", diroff); + (void) TIFFClose(out); + return (1); + } + do { + config = defconfig; + compression = defcompression; + predictor = defpredictor; + fillorder = deffillorder; + rowsperstrip = defrowsperstrip; + tilewidth = deftilewidth; + tilelength = deftilelength; + g3opts = defg3opts; + if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) { + (void) TIFFClose(out); + return (1); + } + } while (TIFFReadDirectory(in)); + (void) TIFFClose(in); + } + (void) TIFFClose(out); + return (0); +} + +static void +processG3Options(char* cp) +{ + if (cp = strchr(cp, ':')) { + if (defg3opts == (uint32) -1) + defg3opts = 0; + do { + cp++; + if (strneq(cp, "1d", 2)) + defg3opts &= ~GROUP3OPT_2DENCODING; + else if (strneq(cp, "2d", 2)) + defg3opts |= GROUP3OPT_2DENCODING; + else if (strneq(cp, "fill", 4)) + defg3opts |= GROUP3OPT_FILLBITS; + else + usage(); + } while (cp = strchr(cp, ':')); + } +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) { + defcompression = COMPRESSION_NONE; + } else if (streq(opt, "packbits")) { + defcompression = COMPRESSION_PACKBITS; + } else if (strneq(opt, "jpeg", 4)) { + char* cp = strchr(opt, ':'); + if (cp && isdigit(cp[1])) + quality = atoi(cp+1); + if (cp && strchr(cp, 'r')) + jpegcolormode = JPEGCOLORMODE_RAW; + defcompression = COMPRESSION_JPEG; + } else if (strneq(opt, "g3", 2)) { + processG3Options(opt); + defcompression = COMPRESSION_CCITTFAX3; + } else if (streq(opt, "g4")) { + defcompression = COMPRESSION_CCITTFAX4; + } else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + defpredictor = atoi(cp+1); + defcompression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + defpredictor = atoi(cp+1); + defcompression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +char* stuff[] = { +"usage: tiffcp [options] input... output", +"where options are:", +" -a append to output instead of overwriting", +" -o offset set initial directory offset", +" -p contig pack samples contiguously (e.g. RGBRGB...)", +" -p separate store samples separately (e.g. RRR...GGG...BBB...)", +" -s write output in strips", +" -t write output in tiles", +" -i ignore read errors", +"", +" -r # make each strip have no more than # rows", +" -w # set output tile width (pixels)", +" -l # set output tile length (pixels)", +"", +" -f lsb2msb force lsb-to-msb FillOrder for output", +" -f msb2lsb force msb-to-lsb FillOrder for output", +"", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c jpeg[:opts]compress output with JPEG encoding", +" -c packbits compress output with packbits encoding", +" -c g3[:opts] compress output with CCITT Group 3 encoding", +" -c g4 compress output with CCITT Group 4 encoding", +" -c none use no compression algorithm on output", +"", +"Group 3 options:", +" 1d use default CCITT Group 3 1D-encoding", +" 2d use optional CCITT Group 3 2D-encoding", +" fill byte-align EOL codes", +"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs", +"", +"JPEG options:", +" # set compression quality level (0-100, default 75)", +" r output color image as RGB rather than YCbCr", +"For example, -c jpeg:r:50 to get JPEG-encoded RGB data with 50% comp. quality", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} + +static void +CheckAndCorrectColormap(TIFF* tif, int n, uint16* r, uint16* g, uint16* b) +{ + int i; + + for (i = 0; i < n; i++) + if (r[i] >= 256 || g[i] >= 256 || b[i] >= 256) + return; + TIFFWarning(TIFFFileName(tif), "Scaling 8-bit colormap"); +#define CVT(x) (((x) * ((1L<<16)-1)) / 255) + for (i = 0; i < n; i++) { + r[i] = CVT(r[i]); + g[i] = CVT(g[i]); + b[i] = CVT(b[i]); + } +#undef CVT +} + +#define CopyField(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) +#define CopyField2(tag, v1, v2) \ + if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) +#define CopyField3(tag, v1, v2, v3) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) +#define CopyField4(tag, v1, v2, v3, v4) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3, &v4)) TIFFSetField(out, tag, v1, v2, v3, v4) + +static void +cpTag(TIFF* in, TIFF* out, uint16 tag, uint16 count, TIFFDataType type) +{ + switch (type) { + case TIFF_SHORT: + if (count == 1) { + uint16 shortv; + CopyField(tag, shortv); + } else if (count == 2) { + uint16 shortv1, shortv2; + CopyField2(tag, shortv1, shortv2); + } else if (count == 4) { + uint16 *tr, *tg, *tb, *ta; + CopyField4(tag, tr, tg, tb, ta); + } else if (count == (uint16) -1) { + uint16 shortv1; + uint16* shortav; + CopyField2(tag, shortv1, shortav); + } + break; + case TIFF_LONG: + { uint32 longv; + CopyField(tag, longv); + } + break; + case TIFF_RATIONAL: + if (count == 1) { + float floatv; + CopyField(tag, floatv); + } else if (count == (uint16) -1) { + float* floatav; + CopyField(tag, floatav); + } + break; + case TIFF_ASCII: + { char* stringv; + CopyField(tag, stringv); + } + break; + case TIFF_DOUBLE: + if (count == 1) { + double doublev; + CopyField(tag, doublev); + } else if (count == (uint16) -1) { + double* doubleav; + CopyField(tag, doubleav); + } + break; + } +} + +static struct cpTag { + uint16 tag; + uint16 count; + TIFFDataType type; +} tags[] = { + { TIFFTAG_SUBFILETYPE, 1, TIFF_LONG }, + { TIFFTAG_THRESHHOLDING, 1, TIFF_SHORT }, + { TIFFTAG_DOCUMENTNAME, 1, TIFF_ASCII }, + { TIFFTAG_IMAGEDESCRIPTION, 1, TIFF_ASCII }, + { TIFFTAG_MAKE, 1, TIFF_ASCII }, + { TIFFTAG_MODEL, 1, TIFF_ASCII }, + { TIFFTAG_ORIENTATION, 1, TIFF_SHORT }, + { TIFFTAG_MINSAMPLEVALUE, 1, TIFF_SHORT }, + { TIFFTAG_MAXSAMPLEVALUE, 1, TIFF_SHORT }, + { TIFFTAG_XRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_YRESOLUTION, 1, TIFF_RATIONAL }, + { TIFFTAG_PAGENAME, 1, TIFF_ASCII }, + { TIFFTAG_XPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_YPOSITION, 1, TIFF_RATIONAL }, + { TIFFTAG_RESOLUTIONUNIT, 1, TIFF_SHORT }, + { TIFFTAG_PAGENUMBER, 2, TIFF_SHORT }, + { TIFFTAG_SOFTWARE, 1, TIFF_ASCII }, + { TIFFTAG_DATETIME, 1, TIFF_ASCII }, + { TIFFTAG_ARTIST, 1, TIFF_ASCII }, + { TIFFTAG_HOSTCOMPUTER, 1, TIFF_ASCII }, + { TIFFTAG_WHITEPOINT, 1, TIFF_RATIONAL }, + { TIFFTAG_PRIMARYCHROMATICITIES,(uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_HALFTONEHINTS, 2, TIFF_SHORT }, + { TIFFTAG_INKSET, 1, TIFF_SHORT }, + { TIFFTAG_INKNAMES, 1, TIFF_ASCII }, + { TIFFTAG_NUMBEROFINKS, 1, TIFF_SHORT }, + { TIFFTAG_DOTRANGE, 2, TIFF_SHORT }, + { TIFFTAG_TARGETPRINTER, 1, TIFF_ASCII }, + { TIFFTAG_SAMPLEFORMAT, 1, TIFF_SHORT }, + { TIFFTAG_YCBCRCOEFFICIENTS, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_YCBCRSUBSAMPLING, 2, TIFF_SHORT }, + { TIFFTAG_YCBCRPOSITIONING, 1, TIFF_SHORT }, + { TIFFTAG_REFERENCEBLACKWHITE, (uint16) -1,TIFF_RATIONAL }, + { TIFFTAG_EXTRASAMPLES, (uint16) -1, TIFF_SHORT }, + { TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE }, + { TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE }, + { TIFFTAG_STONITS, 1, TIFF_DOUBLE }, +}; +#define NTAGS (sizeof (tags) / sizeof (tags[0])) + +#define CopyTag(tag, count, type) cpTag(in, out, tag, count, type) + +typedef int (*copyFunc) + (TIFF* in, TIFF* out, uint32 l, uint32 w, uint16 samplesperpixel); +static copyFunc pickCopyFunc(TIFF*, TIFF*, uint16, uint16); + +static int +tiffcp(TIFF* in, TIFF* out) +{ + uint16 bitspersample, samplesperpixel; + copyFunc cf; + uint32 w, l; + struct cpTag* p; + + CopyField(TIFFTAG_IMAGEWIDTH, w); + CopyField(TIFFTAG_IMAGELENGTH, l); + CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample); + CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); + if (compression != (uint16)-1) + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + else + CopyField(TIFFTAG_COMPRESSION, compression); + if (compression == COMPRESSION_JPEG && jpegcolormode == JPEGCOLORMODE_RGB) + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); + else if (compression == COMPRESSION_SGILOG || compression == COMPRESSION_SGILOG24) + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, + samplesperpixel == 1 ? + PHOTOMETRIC_LOGL : PHOTOMETRIC_LOGLUV); + else + CopyTag(TIFFTAG_PHOTOMETRIC, 1, TIFF_SHORT); + if (fillorder != 0) + TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); + else + CopyTag(TIFFTAG_FILLORDER, 1, TIFF_SHORT); + /* + * Choose tiles/strip for the output image according to + * the command line arguments (-tiles, -strips) and the + * structure of the input image. + */ + if (outtiled == -1) + outtiled = TIFFIsTiled(in); + if (outtiled) { + /* + * Setup output file's tile width&height. If either + * is not specified, use either the value from the + * input image or, if nothing is defined, use the + * library default. + */ + if (tilewidth == (uint32) -1) + TIFFGetField(in, TIFFTAG_TILEWIDTH, &tilewidth); + if (tilelength == (uint32) -1) + TIFFGetField(in, TIFFTAG_TILELENGTH, &tilelength); + TIFFDefaultTileSize(out, &tilewidth, &tilelength); + TIFFSetField(out, TIFFTAG_TILEWIDTH, tilewidth); + TIFFSetField(out, TIFFTAG_TILELENGTH, tilelength); + } else { + /* + * RowsPerStrip is left unspecified: use either the + * value from the input image or, if nothing is defined, + * use the library default. + */ + if (rowsperstrip == (uint32) -1) + TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + } + if (config != (uint16) -1) + TIFFSetField(out, TIFFTAG_PLANARCONFIG, config); + else + CopyField(TIFFTAG_PLANARCONFIG, config); + if (samplesperpixel <= 4) + CopyTag(TIFFTAG_TRANSFERFUNCTION, 4, TIFF_SHORT); + CopyTag(TIFFTAG_COLORMAP, 4, TIFF_SHORT); +/* SMinSampleValue & SMaxSampleValue */ + switch (compression) { + case COMPRESSION_JPEG: + TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality); + TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != (uint16)-1) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + else + CopyField(TIFFTAG_PREDICTOR, predictor); + break; + case COMPRESSION_CCITTFAX3: + case COMPRESSION_CCITTFAX4: + if (compression == COMPRESSION_CCITTFAX3) { + if (g3opts != (uint32) -1) + TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, + g3opts); + else + CopyField(TIFFTAG_GROUP3OPTIONS, g3opts); + } else + CopyTag(TIFFTAG_GROUP4OPTIONS, 1, TIFF_LONG); + CopyTag(TIFFTAG_BADFAXLINES, 1, TIFF_LONG); + CopyTag(TIFFTAG_CLEANFAXDATA, 1, TIFF_LONG); + CopyTag(TIFFTAG_CONSECUTIVEBADFAXLINES, 1, TIFF_LONG); + CopyTag(TIFFTAG_FAXRECVPARAMS, 1, TIFF_LONG); + CopyTag(TIFFTAG_FAXRECVTIME, 1, TIFF_LONG); + CopyTag(TIFFTAG_FAXSUBADDRESS, 1, TIFF_ASCII); + break; + } + { uint32 len32; + void** data; + if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &len32, &data)) + TIFFSetField(out, TIFFTAG_ICCPROFILE, len32, data); + } + for (p = tags; p < &tags[NTAGS]; p++) + CopyTag(p->tag, p->count, p->type); + + cf = pickCopyFunc(in, out, bitspersample, samplesperpixel); + return (cf ? (*cf)(in, out, l, w, samplesperpixel) : FALSE); +} + +/* + * Copy Functions. + */ +#define DECLAREcpFunc(x) \ +static int x(TIFF* in, TIFF* out, \ + uint32 imagelength, uint32 imagewidth, tsample_t spp) + +#define DECLAREreadFunc(x) \ +static void x(TIFF* in, \ + uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp) +typedef void (*readFunc)(TIFF*, uint8*, uint32, uint32, tsample_t); + +#define DECLAREwriteFunc(x) \ +static int x(TIFF* out, \ + uint8* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp) +typedef int (*writeFunc)(TIFF*, uint8*, uint32, uint32, tsample_t); + +/* + * Contig -> contig by scanline for rows/strip change. + */ +DECLAREcpFunc(cpContig2ContigByRow) +{ + tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in)); + uint32 row; + + (void) imagewidth; (void) spp; + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(in, buf, row, 0) < 0 && !ignore) + goto done; + if (TIFFWriteScanline(out, buf, row, 0) < 0) + goto bad; + } +done: + _TIFFfree(buf); + return (TRUE); +bad: + _TIFFfree(buf); + return (FALSE); +} + +/* + * Strip -> strip for change in encoding. + */ +DECLAREcpFunc(cpDecodedStrips) +{ + tsize_t stripsize = TIFFStripSize(in); + tdata_t buf = _TIFFmalloc(stripsize); + + (void) imagewidth; (void) spp; + if (buf) { + tstrip_t s, ns = TIFFNumberOfStrips(in); + uint32 row = 0; + for (s = 0; s < ns; s++) { + tsize_t cc = (row + rowsperstrip > imagelength) ? + TIFFVStripSize(in, imagelength - row) : stripsize; + if (TIFFReadEncodedStrip(in, s, buf, cc) < 0 && !ignore) + break; + if (TIFFWriteEncodedStrip(out, s, buf, cc) < 0) { + _TIFFfree(buf); + return (FALSE); + } + row += rowsperstrip; + } + _TIFFfree(buf); + return (TRUE); + } + return (FALSE); +} + +/* + * Separate -> separate by row for rows/strip change. + */ +DECLAREcpFunc(cpSeparate2SeparateByRow) +{ + tdata_t buf = _TIFFmalloc(TIFFScanlineSize(in)); + uint32 row; + tsample_t s; + + (void) imagewidth; + for (s = 0; s < spp; s++) { + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(in, buf, row, s) < 0 && !ignore) + goto done; + if (TIFFWriteScanline(out, buf, row, s) < 0) + goto bad; + } + } +done: + _TIFFfree(buf); + return (TRUE); +bad: + _TIFFfree(buf); + return (FALSE); +} + +/* + * Contig -> separate by row. + */ +DECLAREcpFunc(cpContig2SeparateByRow) +{ + tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in)); + tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out)); + register uint8 *inp, *outp; + register uint32 n; + uint32 row; + tsample_t s; + + /* unpack channels */ + for (s = 0; s < spp; s++) { + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(in, inbuf, row, 0) < 0 && !ignore) + goto done; + inp = ((uint8*)inbuf) + s; + outp = (uint8*)outbuf; + for (n = imagewidth; n-- > 0;) { + *outp++ = *inp; + inp += spp; + } + if (TIFFWriteScanline(out, outbuf, row, s) < 0) + goto bad; + } + } +done: + if (inbuf) _TIFFfree(inbuf); + if (outbuf) _TIFFfree(outbuf); + return (TRUE); +bad: + if (inbuf) _TIFFfree(inbuf); + if (outbuf) _TIFFfree(outbuf); + return (FALSE); +} + +/* + * Separate -> contig by row. + */ +DECLAREcpFunc(cpSeparate2ContigByRow) +{ + tdata_t inbuf = _TIFFmalloc(TIFFScanlineSize(in)); + tdata_t outbuf = _TIFFmalloc(TIFFScanlineSize(out)); + register uint8 *inp, *outp; + register uint32 n; + uint32 row; + tsample_t s; + + for (row = 0; row < imagelength; row++) { + /* merge channels */ + for (s = 0; s < spp; s++) { + if (TIFFReadScanline(in, inbuf, row, s) < 0 && !ignore) + goto done; + inp = (uint8*)inbuf; + outp = ((uint8*)outbuf) + s; + for (n = imagewidth; n-- > 0;) { + *outp = *inp++; + outp += spp; + } + } + if (TIFFWriteScanline(out, outbuf, row, 0) < 0) + goto bad; + } +done: + if (inbuf) _TIFFfree(inbuf); + if (outbuf) _TIFFfree(outbuf); + return (TRUE); +bad: + if (inbuf) _TIFFfree(inbuf); + if (outbuf) _TIFFfree(outbuf); + return (FALSE); +} + +static void +cpStripToTile(uint8* out, uint8* in, + uint32 rows, uint32 cols, int outskew, int inskew) +{ + while (rows-- > 0) { + uint32 j = cols; + while (j-- > 0) + *out++ = *in++; + out += outskew; + in += inskew; + } +} + +static void +cpContigBufToSeparateBuf(uint8* out, uint8* in, + uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp) +{ + while (rows-- > 0) { + uint32 j = cols; + while (j-- > 0) + *out++ = *in, in += spp; + out += outskew; + in += inskew; + } +} + +static void +cpSeparateBufToContigBuf(uint8* out, uint8* in, + uint32 rows, uint32 cols, int outskew, int inskew, tsample_t spp) +{ + while (rows-- > 0) { + uint32 j = cols; + while (j-- > 0) + *out = *in++, out += spp; + out += outskew; + in += inskew; + } +} + +static int +cpImage(TIFF* in, TIFF* out, readFunc fin, writeFunc fout, + uint32 imagelength, uint32 imagewidth, tsample_t spp) +{ + int status = FALSE; + tdata_t buf = _TIFFmalloc(TIFFRasterScanlineSize(in) * imagelength); + if (buf) { + (*fin)(in, (uint8*)buf, imagelength, imagewidth, spp); + status = (fout)(out, (uint8*)buf, imagelength, imagewidth, spp); + _TIFFfree(buf); + } + return (status); +} + +DECLAREreadFunc(readContigStripsIntoBuffer) +{ + tsize_t scanlinesize = TIFFScanlineSize(in); + uint8* bufp = buf; + uint32 row; + + (void) imagewidth; (void) spp; + for (row = 0; row < imagelength; row++) { + if (TIFFReadScanline(in, (tdata_t) bufp, row, 0) < 0 && !ignore) + break; + bufp += scanlinesize; + } +} + +DECLAREreadFunc(readSeparateStripsIntoBuffer) +{ + tsize_t scanlinesize = TIFFScanlineSize(in); + tdata_t scanline = _TIFFmalloc(scanlinesize); + + (void) imagewidth; + if (scanline) { + uint8* bufp = (uint8*) buf; + uint32 row; + tsample_t s; + + for (row = 0; row < imagelength; row++) { + /* merge channels */ + for (s = 0; s < spp; s++) { + uint8* bp = bufp + s; + tsize_t n = scanlinesize; + + if (TIFFReadScanline(in, scanline, row, s) < 0 && !ignore) + goto done; + while (n-- > 0) + *bp = *bufp++, bp += spp; + } + bufp += scanlinesize; + } +done: + _TIFFfree(scanline); + } +} + +DECLAREreadFunc(readContigTilesIntoBuffer) +{ + tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in)); + uint32 imagew = TIFFScanlineSize(in); + uint32 tilew = TIFFTileRowSize(in); + int iskew = imagew - tilew; + uint8* bufp = (uint8*) buf; + uint32 tw, tl; + uint32 row; + + (void) spp; + if (tilebuf == 0) + return; + (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw); + (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl); + for (row = 0; row < imagelength; row += tl) { + uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl; + uint32 colb = 0; + uint32 col; + + for (col = 0; col < imagewidth; col += tw) { + if (TIFFReadTile(in, tilebuf, col, row, 0, 0) < 0 && + !ignore) + goto done; + if (colb + tilew > imagew) { + uint32 width = imagew - colb; + uint32 oskew = tilew - width; + cpStripToTile(bufp + colb, + tilebuf, nrow, width, + oskew + iskew, oskew); + } else + cpStripToTile(bufp + colb, + tilebuf, nrow, tilew, + iskew, 0); + colb += tilew; + } + bufp += imagew * nrow; + } +done: + _TIFFfree(tilebuf); +} + +DECLAREreadFunc(readSeparateTilesIntoBuffer) +{ + uint32 imagew = TIFFScanlineSize(in); + uint32 tilew = TIFFTileRowSize(in); + int iskew = imagew - tilew; + tdata_t tilebuf = _TIFFmalloc(TIFFTileSize(in)); + uint8* bufp = (uint8*) buf; + uint32 tw, tl; + uint32 row; + + if (tilebuf == 0) + return; + (void) TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw); + (void) TIFFGetField(in, TIFFTAG_TILELENGTH, &tl); + for (row = 0; row < imagelength; row += tl) { + uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl; + uint32 colb = 0; + uint32 col; + + for (col = 0; col < imagewidth; col += tw) { + tsample_t s; + + for (s = 0; s < spp; s++) { + if (TIFFReadTile(in, tilebuf, col, row, 0, s) < 0 && !ignore) + goto done; + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + if (colb + tilew > imagew) { + uint32 width = imagew - colb; + int oskew = tilew - width; + cpSeparateBufToContigBuf(bufp+colb+s, + tilebuf, nrow, width, + oskew + iskew, oskew, spp); + } else + cpSeparateBufToContigBuf(bufp+colb+s, + tilebuf, nrow, tw, + iskew, 0, spp); + } + colb += tilew; + } + bufp += imagew * nrow; + } +done: + _TIFFfree(tilebuf); +} + +DECLAREwriteFunc(writeBufferToContigStrips) +{ + uint32 row, rowsperstrip; + tstrip_t strip = 0; + + (void) imagewidth; (void) spp; + (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + for (row = 0; row < imagelength; row += rowsperstrip) { + uint32 nrows = (row+rowsperstrip > imagelength) ? + imagelength-row : rowsperstrip; + tsize_t stripsize = TIFFVStripSize(out, nrows); + if (TIFFWriteEncodedStrip(out, strip++, buf, stripsize) < 0) + return (FALSE); + row += rowsperstrip, buf += stripsize; + } + return (TRUE); +} + +DECLAREwriteFunc(writeBufferToSeparateStrips) +{ + uint32 rowsize = imagewidth * spp; + uint32 rowsperstrip; + tdata_t obuf = _TIFFmalloc(TIFFStripSize(out)); + tstrip_t strip = 0; + tsample_t s; + + if (obuf == NULL) + return (0); + (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + for (s = 0; s < spp; s++) { + uint32 row; + for (row = 0; row < imagelength; row += rowsperstrip) { + uint32 nrows = (row+rowsperstrip > imagelength) ? + imagelength-row : rowsperstrip; + tsize_t stripsize = TIFFVStripSize(out, nrows); + + cpContigBufToSeparateBuf( + obuf, (uint8*) buf + row*rowsize + s, + nrows, imagewidth, 0, 0, spp); + if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0) { + _TIFFfree(obuf); + return (FALSE); + } + } + } + _TIFFfree(obuf); + return (TRUE); + +} + +DECLAREwriteFunc(writeBufferToContigTiles) +{ + uint32 imagew = TIFFScanlineSize(out); + uint32 tilew = TIFFTileRowSize(out); + int iskew = imagew - tilew; + tdata_t obuf = _TIFFmalloc(TIFFTileSize(out)); + uint8* bufp = (uint8*) buf; + uint32 tl, tw; + uint32 row; + + (void) spp; + if (obuf == NULL) + return (FALSE); + (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl); + (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw); + for (row = 0; row < imagelength; row += tilelength) { + uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl; + uint32 colb = 0; + uint32 col; + + for (col = 0; col < imagewidth; col += tw) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + if (colb + tilew > imagew) { + uint32 width = imagew - colb; + int oskew = tilew - width; + cpStripToTile(obuf, bufp + colb, nrow, width, + oskew, oskew + iskew); + } else + cpStripToTile(obuf, bufp + colb, nrow, tilew, + 0, iskew); + if (TIFFWriteTile(out, obuf, col, row, 0, 0) < 0) { + _TIFFfree(obuf); + return (FALSE); + } + colb += tilew; + } + bufp += nrow * imagew; + } + _TIFFfree(obuf); + return (TRUE); +} + +DECLAREwriteFunc(writeBufferToSeparateTiles) +{ + uint32 imagew = TIFFScanlineSize(out); + tsize_t tilew = TIFFTileRowSize(out); + uint32 iimagew = TIFFRasterScanlineSize(out); + int iskew = iimagew - tilew*spp; + tdata_t obuf = _TIFFmalloc(TIFFTileSize(out)); + uint8* bufp = (uint8*) buf; + uint32 tl, tw; + uint32 row; + + if (obuf == NULL) + return (FALSE); + (void) TIFFGetField(out, TIFFTAG_TILELENGTH, &tl); + (void) TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw); + for (row = 0; row < imagelength; row += tl) { + uint32 nrow = (row+tl > imagelength) ? imagelength-row : tl; + uint32 colb = 0; + uint32 col; + + for (col = 0; col < imagewidth; col += tw) { + tsample_t s; + for (s = 0; s < spp; s++) { + /* + * Tile is clipped horizontally. Calculate + * visible portion and skewing factors. + */ + if (colb + tilew > imagew) { + uint32 width = imagew - colb; + int oskew = tilew - width; + + cpContigBufToSeparateBuf(obuf, + bufp + (colb*spp) + s, + nrow, width, + oskew, (oskew*spp)+iskew, spp); + } else + cpContigBufToSeparateBuf(obuf, + bufp + (colb*spp) + s, + nrow, tilewidth, + 0, iskew, spp); + if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) { + _TIFFfree(obuf); + return (FALSE); + } + } + colb += tilew; + } + bufp += nrow * iimagew; + } + _TIFFfree(obuf); + return (TRUE); +} + +/* + * Contig strips -> contig tiles. + */ +DECLAREcpFunc(cpContigStrips2ContigTiles) +{ + return cpImage(in, out, + readContigStripsIntoBuffer, + writeBufferToContigTiles, + imagelength, imagewidth, spp); +} + +/* + * Contig strips -> separate tiles. + */ +DECLAREcpFunc(cpContigStrips2SeparateTiles) +{ + return cpImage(in, out, + readContigStripsIntoBuffer, + writeBufferToSeparateTiles, + imagelength, imagewidth, spp); +} + +/* + * Separate strips -> contig tiles. + */ +DECLAREcpFunc(cpSeparateStrips2ContigTiles) +{ + return cpImage(in, out, + readSeparateStripsIntoBuffer, + writeBufferToContigTiles, + imagelength, imagewidth, spp); +} + +/* + * Separate strips -> separate tiles. + */ +DECLAREcpFunc(cpSeparateStrips2SeparateTiles) +{ + return cpImage(in, out, + readSeparateStripsIntoBuffer, + writeBufferToSeparateTiles, + imagelength, imagewidth, spp); +} + +/* + * Contig strips -> contig tiles. + */ +DECLAREcpFunc(cpContigTiles2ContigTiles) +{ + return cpImage(in, out, + readContigTilesIntoBuffer, + writeBufferToContigTiles, + imagelength, imagewidth, spp); +} + +/* + * Contig tiles -> separate tiles. + */ +DECLAREcpFunc(cpContigTiles2SeparateTiles) +{ + return cpImage(in, out, + readContigTilesIntoBuffer, + writeBufferToSeparateTiles, + imagelength, imagewidth, spp); +} + +/* + * Separate tiles -> contig tiles. + */ +DECLAREcpFunc(cpSeparateTiles2ContigTiles) +{ + return cpImage(in, out, + readSeparateTilesIntoBuffer, + writeBufferToContigTiles, + imagelength, imagewidth, spp); +} + +/* + * Separate tiles -> separate tiles (tile dimension change). + */ +DECLAREcpFunc(cpSeparateTiles2SeparateTiles) +{ + return cpImage(in, out, + readSeparateTilesIntoBuffer, + writeBufferToSeparateTiles, + imagelength, imagewidth, spp); +} + +/* + * Contig tiles -> contig tiles (tile dimension change). + */ +DECLAREcpFunc(cpContigTiles2ContigStrips) +{ + return cpImage(in, out, + readContigTilesIntoBuffer, + writeBufferToContigStrips, + imagelength, imagewidth, spp); +} + +/* + * Contig tiles -> separate strips. + */ +DECLAREcpFunc(cpContigTiles2SeparateStrips) +{ + return cpImage(in, out, + readContigTilesIntoBuffer, + writeBufferToSeparateStrips, + imagelength, imagewidth, spp); +} + +/* + * Separate tiles -> contig strips. + */ +DECLAREcpFunc(cpSeparateTiles2ContigStrips) +{ + return cpImage(in, out, + readSeparateTilesIntoBuffer, + writeBufferToContigStrips, + imagelength, imagewidth, spp); +} + +/* + * Separate tiles -> separate strips. + */ +DECLAREcpFunc(cpSeparateTiles2SeparateStrips) +{ + return cpImage(in, out, + readSeparateTilesIntoBuffer, + writeBufferToSeparateStrips, + imagelength, imagewidth, spp); +} + +/* + * Select the appropriate copy function to use. + */ +static copyFunc +pickCopyFunc(TIFF* in, TIFF* out, uint16 bitspersample, uint16 samplesperpixel) +{ + uint16 shortv; + uint32 w, l, tw, tl; + int bychunk; + + (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv); + if (shortv != config && bitspersample != 8 && samplesperpixel > 1) { + fprintf(stderr, +"%s: Can not handle different planar configuration w/ bits/sample != 8\n", + TIFFFileName(in)); + return (NULL); + } + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &l); + if (TIFFIsTiled(out)) { + if (!TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw)) + tw = w; + if (!TIFFGetField(in, TIFFTAG_TILELENGTH, &tl)) + tl = l; + bychunk = (tw == tilewidth && tl == tilelength); + } else if (TIFFIsTiled(in)) { + TIFFGetField(in, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(in, TIFFTAG_TILELENGTH, &tl); + bychunk = (tw == w && tl == rowsperstrip); + } else { + uint32 irps = (uint32) -1L; + TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &irps); + bychunk = (rowsperstrip == irps); + } +#define T 1 +#define F 0 +#define pack(a,b,c,d,e) ((long)(((a)<<11)|((b)<<3)|((c)<<2)|((d)<<1)|(e))) + switch(pack(shortv,config,TIFFIsTiled(in),TIFFIsTiled(out),bychunk)) { +/* Strips -> Tiles */ + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,T,T): + return cpContigStrips2ContigTiles; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,T,T): + return cpContigStrips2SeparateTiles; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,T,T): + return cpSeparateStrips2ContigTiles; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,T,T): + return cpSeparateStrips2SeparateTiles; +/* Tiles -> Tiles */ + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,T,T): + return cpContigTiles2ContigTiles; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,T,T): + return cpContigTiles2SeparateTiles; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,T,T): + return cpSeparateTiles2ContigTiles; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,T,T): + return cpSeparateTiles2SeparateTiles; +/* Tiles -> Strips */ + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, T,F,T): + return cpContigTiles2ContigStrips; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, T,F,T): + return cpContigTiles2SeparateStrips; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, T,F,T): + return cpSeparateTiles2ContigStrips; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, T,F,T): + return cpSeparateTiles2SeparateStrips; +/* Strips -> Strips */ + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,F): + return cpContig2ContigByRow; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG, F,F,T): + return cpDecodedStrips; + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,F): + case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE, F,F,T): + return cpContig2SeparateByRow; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG, F,F,T): + return cpSeparate2ContigByRow; + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,F): + case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE, F,F,T): + return cpSeparate2SeparateByRow; + } +#undef pack +#undef F +#undef T + fprintf(stderr, "tiffcp: %s: Don't know how to copy/convert image.\n", + TIFFFileName(in)); + return (NULL); +} diff --git a/tools/tiffdither.c b/tools/tiffdither.c new file mode 100644 index 00000000..8770ecc9 --- /dev/null +++ b/tools/tiffdither.c @@ -0,0 +1,313 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffdither.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +#define CopyField(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) + +uint32 imagewidth; +uint32 imagelength; +int threshold = 128; + +static void usage(void); + +/* + * Floyd-Steinberg error propragation with threshold. + * This code is stolen from tiffmedian. + */ +static void +fsdither(TIFF* in, TIFF* out) +{ + unsigned char *outline, *inputline, *inptr; + short *thisline, *nextline, *tmpptr; + register unsigned char *outptr; + register short *thisptr, *nextptr; + register uint32 i, j; + uint32 imax, jmax; + int lastline, lastpixel; + int bit; + tsize_t outlinesize; + + imax = imagelength - 1; + jmax = imagewidth - 1; + inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + thisline = (short *)_TIFFmalloc(imagewidth * sizeof (short)); + nextline = (short *)_TIFFmalloc(imagewidth * sizeof (short)); + outlinesize = TIFFScanlineSize(out); + outline = (unsigned char *) _TIFFmalloc(outlinesize); + + /* + * Get first line + */ + if (TIFFReadScanline(in, inputline, 0, 0) <= 0) + return; + inptr = inputline; + nextptr = nextline; + for (j = 0; j < imagewidth; ++j) + *nextptr++ = *inptr++; + for (i = 1; i < imagelength; ++i) { + tmpptr = thisline; + thisline = nextline; + nextline = tmpptr; + lastline = (i == imax); + if (TIFFReadScanline(in, inputline, i, 0) <= 0) + break; + inptr = inputline; + nextptr = nextline; + for (j = 0; j < imagewidth; ++j) + *nextptr++ = *inptr++; + thisptr = thisline; + nextptr = nextline; + _TIFFmemset(outptr = outline, 0, outlinesize); + bit = 0x80; + for (j = 0; j < imagewidth; ++j) { + register int v; + + lastpixel = (j == jmax); + v = *thisptr++; + if (v < 0) + v = 0; + else if (v > 255) + v = 255; + if (v > threshold) { + *outptr |= bit; + v -= 255; + } + bit >>= 1; + if (bit == 0) { + outptr++; + bit = 0x80; + } + if (!lastpixel) + thisptr[0] += v * 7 / 16; + if (!lastline) { + if (j != 0) + nextptr[-1] += v * 3 / 16; + *nextptr++ += v * 5 / 16; + if (!lastpixel) + nextptr[0] += v / 16; + } + } + if (TIFFWriteScanline(out, outline, i-1, 0) < 0) + break; + } + _TIFFfree(inputline); + _TIFFfree(thisline); + _TIFFfree(nextline); + _TIFFfree(outline); +} + +static uint16 compression = COMPRESSION_LZW; +static uint16 predictor = 0; +static uint32 group3options = 0; + +static void +processG3Options(char* cp) +{ + if (cp = strchr(cp, ':')) { + do { + cp++; + if (strneq(cp, "1d", 2)) + group3options &= ~GROUP3OPT_2DENCODING; + else if (strneq(cp, "2d", 2)) + group3options |= GROUP3OPT_2DENCODING; + else if (strneq(cp, "fill", 4)) + group3options |= GROUP3OPT_FILLBITS; + else + usage(); + } while (cp = strchr(cp, ':')); + } +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "g3", 2)) { + processG3Options(opt); + compression = COMPRESSION_CCITTFAX3; + } else if (streq(opt, "g4")) + compression = COMPRESSION_CCITTFAX4; + else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +int +main(int argc, char* argv[]) +{ + TIFF *in, *out; + uint16 samplesperpixel, bitspersample = 1, shortv; + float floatv; + char thing[1024]; + uint32 rowsperstrip = (uint32) -1; + int onestrip = 0; + uint16 fillorder = 0; + int c; + extern int optind; + extern char *optarg; + + while ((c = getopt(argc, argv, "c:f:r:t:")) != -1) + switch (c) { + case 'c': /* compression scheme */ + if (!processCompressOptions(optarg)) + usage(); + break; + case 'f': /* fill order */ + if (streq(optarg, "lsb2msb")) + fillorder = FILLORDER_LSB2MSB; + else if (streq(optarg, "msb2lsb")) + fillorder = FILLORDER_MSB2LSB; + else + usage(); + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + onestrip = 0; + break; + case 't': + threshold = atoi(optarg); + if (threshold < 0) + threshold = 0; + else if (threshold > 255) + threshold = 255; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind < 2) + usage(); + in = TIFFOpen(argv[optind], "r"); + if (in == NULL) + return (-1); + TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (samplesperpixel != 1) { + fprintf(stderr, "%s: Not a b&w image.\n", argv[0]); + return (-1); + } + TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + if (bitspersample != 8) { + fprintf(stderr, + " %s: Sorry, only handle 8-bit samples.\n", argv[0]); + return (-1); + } + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-1); + CopyField(TIFFTAG_IMAGEWIDTH, imagewidth); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength); + TIFFSetField(out, TIFFTAG_IMAGELENGTH, imagelength-1); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); + TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + TIFFSetField(out, TIFFTAG_FILLORDER, fillorder); + sprintf(thing, "Dithered B&W version of %s", argv[optind]); + TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing); + CopyField(TIFFTAG_ORIENTATION, shortv); + CopyField(TIFFTAG_XRESOLUTION, floatv); + CopyField(TIFFTAG_YRESOLUTION, floatv); + CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); + if (onestrip) + rowsperstrip = imagelength-1; + else + rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); + switch (compression) { + case COMPRESSION_CCITTFAX3: + TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options); + break; + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + fsdither(in, out); + TIFFClose(in); + TIFFClose(out); + return (0); +} + +char* stuff[] = { +"usage: tiffdither [options] input.tif output.tif", +"where options are:", +" -r # make each strip have no more than # rows", +" -f lsb2msb force lsb-to-msb FillOrder for output", +" -f msb2lsb force msb-to-lsb FillOrder for output", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c packbits compress output with packbits encoding", +" -c g3[:opts] compress output with CCITT Group 3 encoding", +" -c g4 compress output with CCITT Group 4 encoding", +" -c none use no compression algorithm on output", +"", +"Group 3 options:", +" 1d use default CCITT Group 3 1D-encoding", +" 2d use optional CCITT Group 3 2D-encoding", +" fill byte-align EOL codes", +"For example, -c g3:2d:fill to get G3-2D-encoded data with byte-aligned EOLs", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} diff --git a/tools/tiffdump.c b/tools/tiffdump.c new file mode 100644 index 00000000..47bd302b --- /dev/null +++ b/tools/tiffdump.c @@ -0,0 +1,755 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffdump.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#if defined(VMS) +#include +#include +#elif defined(_WINDOWS) +#include +#define off_t toff_t +#include "tiffio.h" +#include +#elif defined(applec) +#define open _open_ /* to avoid conflicts */ +#include +#undef open +int open(const char*, int, int); +typedef unsigned int off_t; +#else /* !VMS && !_WINDOWS && !applec */ +#ifdef unix +#include +#endif +#include +#include +#endif + +#if defined(MSDOS) +#include +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#include "tiffio.h" + +char* appname; +char* curfile; +int swabflag; +int bigendian; +int typeshift[13]; /* data type shift counts */ +long typemask[13]; /* data type masks */ +int maxitems = 24; /* maximum indirect data items to print */ + +char* bytefmt = "%s%#02x"; /* BYTE */ +char* sbytefmt = "%s%d"; /* SBYTE */ +char* shortfmt = "%s%u"; /* SHORT */ +char* sshortfmt = "%s%d"; /* SSHORT */ +char* longfmt = "%s%lu"; /* LONG */ +char* slongfmt = "%s%ld"; /* SLONG */ +char* rationalfmt = "%s%g"; /* RATIONAL */ +char* srationalfmt = "%s%g"; /* SRATIONAL */ +char* floatfmt = "%s%g"; /* FLOAT */ +char* doublefmt = "%s%g"; /* DOUBLE */ + +static void dump(int, uint32); +extern int optind; +extern char* optarg; + +void +usage() +{ + fprintf(stderr, "usage: %s [-h] [-o offset] file.tif ...\n", appname); + exit(-1); +} + +int +main(int argc, char* argv[]) +{ + int one = 1, fd; + int multiplefiles = (argc > 1); + int c; + uint32 diroff = (uint32) 0; + bigendian = (*(char *)&one == 0); + + appname = argv[0]; + while ((c = getopt(argc, argv, "m:o:h")) != -1) { + switch (c) { + case 'h': /* print values in hex */ + shortfmt = "%s%#x"; + sshortfmt = "%s%#x"; + longfmt = "%s%#lx"; + slongfmt = "%s%#lx"; + break; + case 'o': + diroff = (uint32) strtoul(optarg, NULL, 0); + break; + case 'm': + maxitems = strtoul(optarg, NULL, 0); + break; + default: + usage(); + } + } + if (optind >= argc) + usage(); + for (; optind < argc; optind++) { + fd = open(argv[optind], O_RDONLY|O_BINARY, 0); + if (fd < 0) { + perror(argv[0]); + return (-1); + } + if (multiplefiles) + printf("%s:\n", argv[optind]); + curfile = argv[optind]; + swabflag = 0; + dump(fd, diroff); + close(fd); + } + return (0); +} + +static TIFFHeader hdr; + +#define ord(e) ((int)e) + +/* + * Initialize shift & mask tables and byte + * swapping state according to the file + * byte order. + */ +static void +InitByteOrder(int magic) +{ + typemask[0] = 0; + typemask[ord(TIFF_BYTE)] = 0xff; + typemask[ord(TIFF_SBYTE)] = 0xff; + typemask[ord(TIFF_UNDEFINED)] = 0xff; + typemask[ord(TIFF_SHORT)] = 0xffff; + typemask[ord(TIFF_SSHORT)] = 0xffff; + typemask[ord(TIFF_LONG)] = 0xffffffff; + typemask[ord(TIFF_SLONG)] = 0xffffffff; + typemask[ord(TIFF_RATIONAL)] = 0xffffffff; + typemask[ord(TIFF_SRATIONAL)] = 0xffffffff; + typemask[ord(TIFF_FLOAT)] = 0xffffffff; + typemask[ord(TIFF_DOUBLE)] = 0xffffffff; + typeshift[0] = 0; + typeshift[ord(TIFF_LONG)] = 0; + typeshift[ord(TIFF_SLONG)] = 0; + typeshift[ord(TIFF_RATIONAL)] = 0; + typeshift[ord(TIFF_SRATIONAL)] = 0; + typeshift[ord(TIFF_FLOAT)] = 0; + typeshift[ord(TIFF_DOUBLE)] = 0; + if (magic == TIFF_BIGENDIAN) { + typeshift[ord(TIFF_BYTE)] = 24; + typeshift[ord(TIFF_SBYTE)] = 24; + typeshift[ord(TIFF_SHORT)] = 16; + typeshift[ord(TIFF_SSHORT)] = 16; + swabflag = !bigendian; + } else { + typeshift[ord(TIFF_BYTE)] = 0; + typeshift[ord(TIFF_SBYTE)] = 0; + typeshift[ord(TIFF_SHORT)] = 0; + typeshift[ord(TIFF_SSHORT)] = 0; + swabflag = bigendian; + } +} + +static uint32 ReadDirectory(int, unsigned, uint32); +static void ReadError(char*); +static void Error(const char*, ...); +static void Fatal(const char*, ...); + +static void +dump(int fd, uint32 diroff) +{ + unsigned i; + + lseek(fd, (off_t) 0, 0); + if (read(fd, (char*) &hdr, sizeof (hdr)) != sizeof (hdr)) + ReadError("TIFF header"); + /* + * Setup the byte order handling. + */ + if (hdr.tiff_magic != TIFF_BIGENDIAN && hdr.tiff_magic != TIFF_LITTLEENDIAN) + Fatal("Not a TIFF file, bad magic number %u (%#x)", + hdr.tiff_magic, hdr.tiff_magic); + InitByteOrder(hdr.tiff_magic); + /* + * Swap header if required. + */ + if (swabflag) { + TIFFSwabShort(&hdr.tiff_version); + TIFFSwabLong(&hdr.tiff_diroff); + } + /* + * Now check version (if needed, it's been byte-swapped). + * Note that this isn't actually a version number, it's a + * magic number that doesn't change (stupid). + */ + if (hdr.tiff_version != TIFF_VERSION) + Fatal("Not a TIFF file, bad version number %u (%#x)", + hdr.tiff_version, hdr.tiff_version); + printf("Magic: %#x <%s-endian> Version: %#x\n", + hdr.tiff_magic, + hdr.tiff_magic == TIFF_BIGENDIAN ? "big" : "little", + hdr.tiff_version); + if (diroff == 0) + diroff = hdr.tiff_diroff; + for (i = 0; diroff != 0; i++) { + if (i > 0) + putchar('\n'); + diroff = ReadDirectory(fd, i, diroff); + } +} + +static int datawidth[] = { + 0, /* nothing */ + 1, /* TIFF_BYTE */ + 1, /* TIFF_ASCII */ + 2, /* TIFF_SHORT */ + 4, /* TIFF_LONG */ + 8, /* TIFF_RATIONAL */ + 1, /* TIFF_SBYTE */ + 1, /* TIFF_UNDEFINED */ + 2, /* TIFF_SSHORT */ + 4, /* TIFF_SLONG */ + 8, /* TIFF_SRATIONAL */ + 4, /* TIFF_FLOAT */ + 8, /* TIFF_DOUBLE */ +}; +#define NWIDTHS (sizeof (datawidth) / sizeof (datawidth[0])) +static int TIFFFetchData(int, TIFFDirEntry*, void*); +static void PrintTag(FILE*, uint16); +static void PrintType(FILE*, uint16); +static void PrintData(FILE*, uint16, uint32, unsigned char*); +static void PrintByte(FILE*, const char*, TIFFDirEntry*); +static void PrintShort(FILE*, const char*, TIFFDirEntry*); +static void PrintLong(FILE*, const char*, TIFFDirEntry*); + +/* + * Read the next TIFF directory from a file + * and convert it to the internal format. + * We read directories sequentially. + */ +static uint32 +ReadDirectory(int fd, unsigned ix, uint32 off) +{ + register TIFFDirEntry *dp; + register int n; + TIFFDirEntry *dir = 0; + uint16 dircount; + int space; + uint32 nextdiroff = 0; + + if (off == 0) /* no more directories */ + goto done; + if (lseek(fd, (off_t) off, 0) != off) { + Fatal("Seek error accessing TIFF directory"); + goto done; + } + if (read(fd, (char*) &dircount, sizeof (uint16)) != sizeof (uint16)) { + ReadError("directory count"); + goto done; + } + if (swabflag) + TIFFSwabShort(&dircount); + dir = (TIFFDirEntry *)_TIFFmalloc(dircount * sizeof (TIFFDirEntry)); + if (dir == NULL) { + Fatal("No space for TIFF directory"); + goto done; + } + n = read(fd, (char*) dir, dircount*sizeof (*dp)); + if (n != dircount*sizeof (*dp)) { + n /= sizeof (*dp); + Error( + "Could only read %u of %u entries in directory at offset %#lx", + n, dircount, (unsigned long) off); + dircount = n; + } + if (read(fd, (char*) &nextdiroff, sizeof (uint32)) != sizeof (uint32)) + nextdiroff = 0; + if (swabflag) + TIFFSwabLong(&nextdiroff); + printf("Directory %u: offset %lu (%#lx) next %lu (%#lx)\n", ix, + (unsigned long) off, (unsigned long) off, + (unsigned long) nextdiroff, (unsigned long) nextdiroff); + for (dp = dir, n = dircount; n > 0; n--, dp++) { + if (swabflag) { + TIFFSwabArrayOfShort(&dp->tdir_tag, 2); + TIFFSwabArrayOfLong(&dp->tdir_count, 2); + } + PrintTag(stdout, dp->tdir_tag); + putchar(' '); + PrintType(stdout, dp->tdir_type); + putchar(' '); + printf("%lu<", (unsigned long) dp->tdir_count); + if (dp->tdir_type >= NWIDTHS) { + printf(">\n"); + continue; + } + space = dp->tdir_count * datawidth[dp->tdir_type]; + if (space <= 4) { + switch (dp->tdir_type) { + case TIFF_FLOAT: + case TIFF_UNDEFINED: + case TIFF_ASCII: { + unsigned char data[4]; + _TIFFmemcpy(data, &dp->tdir_offset, 4); + if (swabflag) + TIFFSwabLong((uint32*) data); + PrintData(stdout, + dp->tdir_type, dp->tdir_count, data); + break; + } + case TIFF_BYTE: + PrintByte(stdout, bytefmt, dp); + break; + case TIFF_SBYTE: + PrintByte(stdout, sbytefmt, dp); + break; + case TIFF_SHORT: + PrintShort(stdout, shortfmt, dp); + break; + case TIFF_SSHORT: + PrintShort(stdout, sshortfmt, dp); + break; + case TIFF_LONG: + PrintLong(stdout, longfmt, dp); + break; + case TIFF_SLONG: + PrintLong(stdout, slongfmt, dp); + break; + } + } else { + unsigned char *data = (unsigned char *)_TIFFmalloc(space); + if (data) { + if (TIFFFetchData(fd, dp, data)) + if (dp->tdir_count > maxitems) { + PrintData(stdout, dp->tdir_type, + maxitems, data); + printf(" ..."); + } else + PrintData(stdout, dp->tdir_type, + dp->tdir_count, data); + _TIFFfree(data); + } else + Error("No space for data for tag %u", + dp->tdir_tag); + } + printf(">\n"); + } +done: + if (dir) + _TIFFfree((char *)dir); + return (nextdiroff); +} + +static struct tagname { + uint16 tag; + char* name; +} tagnames[] = { + { TIFFTAG_SUBFILETYPE, "SubFileType" }, + { TIFFTAG_OSUBFILETYPE, "OldSubFileType" }, + { TIFFTAG_IMAGEWIDTH, "ImageWidth" }, + { TIFFTAG_IMAGELENGTH, "ImageLength" }, + { TIFFTAG_BITSPERSAMPLE, "BitsPerSample" }, + { TIFFTAG_COMPRESSION, "Compression" }, + { TIFFTAG_PHOTOMETRIC, "Photometric" }, + { TIFFTAG_THRESHHOLDING, "Threshholding" }, + { TIFFTAG_CELLWIDTH, "CellWidth" }, + { TIFFTAG_CELLLENGTH, "CellLength" }, + { TIFFTAG_FILLORDER, "FillOrder" }, + { TIFFTAG_DOCUMENTNAME, "DocumentName" }, + { TIFFTAG_IMAGEDESCRIPTION, "ImageDescription" }, + { TIFFTAG_MAKE, "Make" }, + { TIFFTAG_MODEL, "Model" }, + { TIFFTAG_STRIPOFFSETS, "StripOffsets" }, + { TIFFTAG_ORIENTATION, "Orientation" }, + { TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel" }, + { TIFFTAG_ROWSPERSTRIP, "RowsPerStrip" }, + { TIFFTAG_STRIPBYTECOUNTS, "StripByteCounts" }, + { TIFFTAG_MINSAMPLEVALUE, "MinSampleValue" }, + { TIFFTAG_MAXSAMPLEVALUE, "MaxSampleValue" }, + { TIFFTAG_XRESOLUTION, "XResolution" }, + { TIFFTAG_YRESOLUTION, "YResolution" }, + { TIFFTAG_PLANARCONFIG, "PlanarConfig" }, + { TIFFTAG_PAGENAME, "PageName" }, + { TIFFTAG_XPOSITION, "XPosition" }, + { TIFFTAG_YPOSITION, "YPosition" }, + { TIFFTAG_FREEOFFSETS, "FreeOffsets" }, + { TIFFTAG_FREEBYTECOUNTS, "FreeByteCounts" }, + { TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit" }, + { TIFFTAG_GRAYRESPONSECURVE,"GrayResponseCurve" }, + { TIFFTAG_GROUP3OPTIONS, "Group3Options" }, + { TIFFTAG_GROUP4OPTIONS, "Group4Options" }, + { TIFFTAG_RESOLUTIONUNIT, "ResolutionUnit" }, + { TIFFTAG_PAGENUMBER, "PageNumber" }, + { TIFFTAG_COLORRESPONSEUNIT,"ColorResponseUnit" }, + { TIFFTAG_TRANSFERFUNCTION, "TransferFunction" }, + { TIFFTAG_SOFTWARE, "Software" }, + { TIFFTAG_DATETIME, "DateTime" }, + { TIFFTAG_ARTIST, "Artist" }, + { TIFFTAG_HOSTCOMPUTER, "HostComputer" }, + { TIFFTAG_PREDICTOR, "Predictor" }, + { TIFFTAG_WHITEPOINT, "Whitepoint" }, + { TIFFTAG_PRIMARYCHROMATICITIES,"PrimaryChromaticities" }, + { TIFFTAG_COLORMAP, "Colormap" }, + { TIFFTAG_HALFTONEHINTS, "HalftoneHints" }, + { TIFFTAG_TILEWIDTH, "TileWidth" }, + { TIFFTAG_TILELENGTH, "TileLength" }, + { TIFFTAG_TILEOFFSETS, "TileOffsets" }, + { TIFFTAG_TILEBYTECOUNTS, "TileByteCounts" }, + { TIFFTAG_BADFAXLINES, "BadFaxLines" }, + { TIFFTAG_CLEANFAXDATA, "CleanFaxData" }, + { TIFFTAG_CONSECUTIVEBADFAXLINES, "ConsecutiveBadFaxLines" }, + { TIFFTAG_SUBIFD, "SubIFD" }, + { TIFFTAG_INKSET, "InkSet" }, + { TIFFTAG_INKNAMES, "InkNames" }, + { TIFFTAG_NUMBEROFINKS, "NumberOfInks" }, + { TIFFTAG_DOTRANGE, "DotRange" }, + { TIFFTAG_TARGETPRINTER, "TargetPrinter" }, + { TIFFTAG_EXTRASAMPLES, "ExtraSamples" }, + { TIFFTAG_SAMPLEFORMAT, "SampleFormat" }, + { TIFFTAG_SMINSAMPLEVALUE, "SMinSampleValue" }, + { TIFFTAG_SMAXSAMPLEVALUE, "SMaxSampleValue" }, + { TIFFTAG_JPEGPROC, "JPEGProcessingMode" }, + { TIFFTAG_JPEGIFOFFSET, "JPEGInterchangeFormat" }, + { TIFFTAG_JPEGIFBYTECOUNT, "JPEGInterchangeFormatLength" }, + { TIFFTAG_JPEGRESTARTINTERVAL,"JPEGRestartInterval" }, + { TIFFTAG_JPEGLOSSLESSPREDICTORS,"JPEGLosslessPredictors" }, + { TIFFTAG_JPEGPOINTTRANSFORM,"JPEGPointTransform" }, + { TIFFTAG_JPEGQTABLES, "JPEGQTables" }, + { TIFFTAG_JPEGDCTABLES, "JPEGDCTables" }, + { TIFFTAG_JPEGACTABLES, "JPEGACTables" }, + { TIFFTAG_YCBCRCOEFFICIENTS,"YCbCrCoefficients" }, + { TIFFTAG_YCBCRSUBSAMPLING, "YCbCrSubsampling" }, + { TIFFTAG_YCBCRPOSITIONING, "YCbCrPositioning" }, + { TIFFTAG_REFERENCEBLACKWHITE, "ReferenceBlackWhite" }, + { TIFFTAG_REFPTS, "IgReferencePoints (Island Graphics)" }, + { TIFFTAG_REGIONTACKPOINT, "IgRegionTackPoint (Island Graphics)" }, + { TIFFTAG_REGIONWARPCORNERS,"IgRegionWarpCorners (Island Graphics)" }, + { TIFFTAG_REGIONAFFINE, "IgRegionAffine (Island Graphics)" }, + { TIFFTAG_MATTEING, "OBSOLETE Matteing (Silicon Graphics)" }, + { TIFFTAG_DATATYPE, "OBSOLETE DataType (Silicon Graphics)" }, + { TIFFTAG_IMAGEDEPTH, "ImageDepth (Silicon Graphics)" }, + { TIFFTAG_TILEDEPTH, "TileDepth (Silicon Graphics)" }, + { 32768, "OLD BOGUS Matteing tag" }, + { TIFFTAG_COPYRIGHT, "Copyright" }, + { TIFFTAG_ICCPROFILE, "ICC Profile" }, + { TIFFTAG_JBIGOPTIONS, "JBIG Options" }, + { TIFFTAG_STONITS, "StoNits" }, +}; +#define NTAGS (sizeof (tagnames) / sizeof (tagnames[0])) + +static void +PrintTag(FILE* fd, uint16 tag) +{ + register struct tagname *tp; + + for (tp = tagnames; tp < &tagnames[NTAGS]; tp++) + if (tp->tag == tag) { + fprintf(fd, "%s (%u)", tp->name, tag); + return; + } + fprintf(fd, "%u (%#x)", tag, tag); +} + +static void +PrintType(FILE* fd, uint16 type) +{ + static char *typenames[] = { + "0", + "BYTE", + "ASCII", + "SHORT", + "LONG", + "RATIONAL", + "SBYTE", + "UNDEFINED", + "SSHORT", + "SLONG", + "SRATIONAL", + "FLOAT", + "DOUBLE" + }; +#define NTYPES (sizeof (typenames) / sizeof (typenames[0])) + + if (type < NTYPES) + fprintf(fd, "%s (%u)", typenames[type], type); + else + fprintf(fd, "%u (%#x)", type, type); +} +#undef NTYPES + +static void +PrintByte(FILE* fd, const char* fmt, TIFFDirEntry* dp) +{ + char* sep = ""; + + if (hdr.tiff_magic != TIFF_LITTLEENDIAN) { + switch ((int)dp->tdir_count) { + case 4: fprintf(fd, fmt, sep, dp->tdir_offset&0xff); + sep = " "; + case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff); + sep = " "; + case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff); + sep = " "; + case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>24); + } + } else { + switch ((int)dp->tdir_count) { + case 4: fprintf(fd, fmt, sep, dp->tdir_offset>>24); + sep = " "; + case 3: fprintf(fd, fmt, sep, (dp->tdir_offset>>16)&0xff); + sep = " "; + case 2: fprintf(fd, fmt, sep, (dp->tdir_offset>>8)&0xff); + sep = " "; + case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xff); + } + } +} + +static void +PrintShort(FILE* fd, const char* fmt, TIFFDirEntry* dp) +{ + char *sep = ""; + + if (hdr.tiff_magic != TIFF_LITTLEENDIAN) { + switch (dp->tdir_count) { + case 2: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff); + sep = " "; + case 1: fprintf(fd, fmt, sep, dp->tdir_offset>>16); + } + } else { + switch (dp->tdir_count) { + case 2: fprintf(fd, fmt, sep, dp->tdir_offset>>16); + sep = " "; + case 1: fprintf(fd, fmt, sep, dp->tdir_offset&0xffff); + } + } +} + +static void +PrintLong(FILE* fd, const char* fmt, TIFFDirEntry* dp) +{ + fprintf(fd, fmt, "", (long) dp->tdir_offset); +} + +#include + +static void +PrintASCII(FILE* fd, uint32 cc, const unsigned char* cp) +{ + for (; cc > 0; cc--, cp++) { + const char* tp; + + if (isprint(*cp)) { + fputc(*cp, fd); + continue; + } + for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) + if (*tp++ == *cp) + break; + if (*tp) + fprintf(fd, "\\%c", *tp); + else if (*cp) + fprintf(fd, "\\%03o", *cp); + else + fprintf(fd, "\\0"); + } +} + +static void +PrintData(FILE* fd, uint16 type, uint32 count, unsigned char* data) +{ + char* sep = ""; + + switch (type) { + case TIFF_BYTE: + while (count-- > 0) + fprintf(fd, bytefmt, sep, *data++), sep = " "; + break; + case TIFF_SBYTE: + while (count-- > 0) + fprintf(fd, sbytefmt, sep, *(char *)data++), sep = " "; + break; + case TIFF_UNDEFINED: + while (count-- > 0) + fprintf(fd, bytefmt, sep, *data++), sep = " "; + break; + case TIFF_ASCII: + PrintASCII(fd, count, data); + break; + case TIFF_SHORT: { + register uint16 *wp = (uint16*)data; + while (count-- > 0) + fprintf(fd, shortfmt, sep, *wp++), sep = " "; + break; + } + case TIFF_SSHORT: { + register int16 *wp = (int16*)data; + while (count-- > 0) + fprintf(fd, sshortfmt, sep, *wp++), sep = " "; + break; + } + case TIFF_LONG: { + register uint32 *lp = (uint32*)data; + while (count-- > 0) { + fprintf(fd, longfmt, sep, (unsigned long) *lp++); + sep = " "; + } + break; + } + case TIFF_SLONG: { + register int32 *lp = (int32*)data; + while (count-- > 0) + fprintf(fd, slongfmt, sep, (long) *lp++), sep = " "; + break; + } + case TIFF_RATIONAL: { + register uint32 *lp = (uint32*)data; + while (count-- > 0) { + if (lp[1] == 0) + fprintf(fd, "%sNan (%lu/%lu)", sep, + (unsigned long) lp[0], + (unsigned long) lp[1]); + else + fprintf(fd, rationalfmt, sep, + (double)lp[0] / (double)lp[1]); + sep = " "; + lp += 2; + } + break; + } + case TIFF_SRATIONAL: { + register int32 *lp = (int32*)data; + while (count-- > 0) { + if (lp[1] == 0) + fprintf(fd, "%sNan (%ld/%ld)", sep, + (long) lp[0], (long) lp[1]); + else + fprintf(fd, srationalfmt, sep, + (double)lp[0] / (double)lp[1]); + sep = " "; + lp += 2; + } + break; + } + case TIFF_FLOAT: { + register float *fp = (float *)data; + while (count-- > 0) + fprintf(fd, floatfmt, sep, *fp++), sep = " "; + break; + } + case TIFF_DOUBLE: { + register double *dp = (double *)data; + while (count-- > 0) + fprintf(fd, doublefmt, sep, *dp++), sep = " "; + break; + } + } +} + +/* + * Fetch a contiguous directory item. + */ +static int +TIFFFetchData(int fd, TIFFDirEntry* dir, void* cp) +{ + int cc, w; + + w = (dir->tdir_type < NWIDTHS ? datawidth[dir->tdir_type] : 0); + cc = dir->tdir_count * w; + if (lseek(fd, (off_t) dir->tdir_offset, 0) == dir->tdir_offset && + read(fd, cp, cc) == cc) { + if (swabflag) { + switch (dir->tdir_type) { + case TIFF_SHORT: + case TIFF_SSHORT: + TIFFSwabArrayOfShort((uint16*) cp, + dir->tdir_count); + break; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + TIFFSwabArrayOfLong((uint32*) cp, + dir->tdir_count); + break; + case TIFF_RATIONAL: + TIFFSwabArrayOfLong((uint32*) cp, + 2*dir->tdir_count); + break; + case TIFF_DOUBLE: + TIFFSwabArrayOfDouble((double*) cp, + dir->tdir_count); + break; + } + } + return (cc); + } + Error("Error while reading data for tag %u", dir->tdir_tag); + return (0); +} + +static void +ReadError(char* what) +{ + Fatal("Error while reading %s", what); +} + +#include + +static void +vError(FILE* fd, const char* fmt, va_list ap) +{ + fprintf(fd, "%s: ", curfile); + vfprintf(fd, fmt, ap); + fprintf(fd, ".\n"); +} + +static void +Error(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vError(stderr, fmt, ap); + va_end(ap); +} + +static void +Fatal(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vError(stderr, fmt, ap); + va_end(ap); + exit(-1); +} diff --git a/tools/tiffinfo.c b/tools/tiffinfo.c new file mode 100644 index 00000000..8936af25 --- /dev/null +++ b/tools/tiffinfo.c @@ -0,0 +1,429 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffinfo.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcmp(a,b) == 0) + +int showdata = 0; /* show data */ +int rawdata = 0; /* show raw/decoded data */ +int showwords = 0; /* show data as bytes/words */ +int readdata = 0; /* read data in file */ +int stoponerr = 1; /* stop on first read error */ + +static void usage(void); +static void tiffinfo(TIFF*, uint16, long); + +int +main(int argc, char* argv[]) +{ + int dirnum = -1, multiplefiles, c; + uint16 order = 0; + TIFF* tif; + extern int optind; + extern char* optarg; + long flags = 0; + uint32 diroff = 0; + int chopstrips = 0; /* disable strip chopping */ + + while ((c = getopt(argc, argv, "f:o:cdDSjlmrsvwz0123456789")) != -1) + switch (c) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + dirnum = atoi(&argv[optind-1][1]); + break; + case 'd': + showdata++; + /* fall thru... */ + case 'D': + readdata++; + break; + case 'c': + flags |= TIFFPRINT_COLORMAP | TIFFPRINT_CURVES; + break; + case 'f': /* fill order */ + if (streq(optarg, "lsb2msb")) + order = FILLORDER_LSB2MSB; + else if (streq(optarg, "msb2lsb")) + order = FILLORDER_MSB2LSB; + else + usage(); + break; + case 'i': + stoponerr = 0; + break; + case 'o': + diroff = strtoul(optarg, NULL, 0); + break; + case 'j': + flags |= TIFFPRINT_JPEGQTABLES | + TIFFPRINT_JPEGACTABLES | + TIFFPRINT_JPEGDCTABLES; + break; + case 'r': + rawdata = 1; + break; + case 's': + flags |= TIFFPRINT_STRIPS; + break; + case 'w': + showwords = 1; + break; + case 'z': + chopstrips = 1; + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (optind >= argc) + usage(); + multiplefiles = (argc - optind > 1); + for (; optind < argc; optind++) { + if (multiplefiles) + printf("%s:\n", argv[optind]); + tif = TIFFOpen(argv[optind], chopstrips ? "rC" : "rc"); + if (tif != NULL) { + if (dirnum != -1) { + if (TIFFSetDirectory(tif, dirnum)) + tiffinfo(tif, order, flags); + } else if (diroff != 0) { + if (TIFFSetSubDirectory(tif, diroff)) + tiffinfo(tif, order, flags); + } else { + do + tiffinfo(tif, order, flags); + while (TIFFReadDirectory(tif)); + } + TIFFClose(tif); + } + } + return (0); +} + +char* stuff[] = { +"usage: tiffinfo [options] input...", +"where options are:", +" -D read data", +" -i ignore read errors", +" -c display data for grey/color response curve or colormap", +" -d display raw/decoded image data", +" -f lsb2msb force lsb-to-msb FillOrder for input", +" -f msb2lsb force msb-to-lsb FillOrder for input", +" -j show JPEG tables", +" -o offset set initial directory offset", +" -r read/display raw image data instead of decoded data", +" -s display strip offsets and byte counts", +" -w display raw data in words rather than bytes", +" -z enable strip chopping", +" -# set initial directory (first directory is # 0)", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} + +static void +ShowStrip(tstrip_t strip, unsigned char* pp, uint32 nrow, tsize_t scanline) +{ + register tsize_t cc; + + printf("Strip %lu:\n", (unsigned long) strip); + while (nrow-- > 0) { + for (cc = 0; cc < scanline; cc++) { + printf(" %02x", *pp++); + if (((cc+1) % 24) == 0) + putchar('\n'); + } + putchar('\n'); + } +} + +void +TIFFReadContigStripData(TIFF* tif) +{ + unsigned char *buf; + tsize_t scanline = TIFFScanlineSize(tif); + + buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif)); + if (buf) { + uint32 row, h; + uint32 rowsperstrip = (uint32)-1; + + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + for (row = 0; row < h; row += rowsperstrip) { + uint32 nrow = (row+rowsperstrip > h ? + h-row : rowsperstrip); + tstrip_t strip = TIFFComputeStrip(tif, row, 0); + if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) { + if (stoponerr) + break; + } else if (showdata) + ShowStrip(strip, buf, nrow, scanline); + } + _TIFFfree(buf); + } +} + +void +TIFFReadSeparateStripData(TIFF* tif) +{ + unsigned char *buf; + tsize_t scanline = TIFFScanlineSize(tif); + + buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif)); + if (buf) { + uint32 row, h; + uint32 rowsperstrip = (uint32)-1; + tsample_t s, samplesperpixel; + + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + for (row = 0; row < h; row += rowsperstrip) { + for (s = 0; s < samplesperpixel; s++) { + uint32 nrow = (row+rowsperstrip > h ? + h-row : rowsperstrip); + tstrip_t strip = TIFFComputeStrip(tif, row, s); + if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) { + if (stoponerr) + break; + } else if (showdata) + ShowStrip(strip, buf, nrow, scanline); + } + } + _TIFFfree(buf); + } +} + +static void +ShowTile(uint32 row, uint32 col, tsample_t sample, + unsigned char* pp, uint32 nrow, uint32 rowsize) +{ + register tsize_t cc; + + printf("Tile (%lu,%lu", (unsigned long) row, (unsigned long) col); + if (sample != (tsample_t) -1) + printf(",%u", sample); + printf("):\n"); + while (nrow-- > 0) { + for (cc = 0; cc < rowsize; cc++) { + printf(" %02x", *pp++); + if (((cc+1) % 24) == 0) + putchar('\n'); + } + putchar('\n'); + } +} + +void +TIFFReadContigTileData(TIFF* tif) +{ + unsigned char *buf; + tsize_t rowsize = TIFFTileRowSize(tif); + + buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif)); + if (buf) { + uint32 tw, th, w, h; + uint32 row, col; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + for (row = 0; row < h; row += th) { + for (col = 0; col < w; col += tw) { + if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0) { + if (stoponerr) + break; + } else if (showdata) + ShowTile(row, col, (tsample_t) -1, buf, th, rowsize); + } + } + _TIFFfree(buf); + } +} + +void +TIFFReadSeparateTileData(TIFF* tif) +{ + unsigned char *buf; + tsize_t rowsize = TIFFTileRowSize(tif); + + buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif)); + if (buf) { + uint32 tw, th, w, h; + uint32 row, col; + tsample_t s, samplesperpixel; + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + for (row = 0; row < h; row += th) { + for (col = 0; col < w; col += tw) { + for (s = 0; s < samplesperpixel; s++) { + if (TIFFReadTile(tif, buf, col, row, 0, s) < 0) { + if (stoponerr) + break; + } else if (showdata) + ShowTile(row, col, s, buf, th, rowsize); + } + } + } + _TIFFfree(buf); + } +} + +void +TIFFReadData(TIFF* tif) +{ + uint16 config; + + TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config); + if (TIFFIsTiled(tif)) { + if (config == PLANARCONFIG_CONTIG) + TIFFReadContigTileData(tif); + else + TIFFReadSeparateTileData(tif); + } else { + if (config == PLANARCONFIG_CONTIG) + TIFFReadContigStripData(tif); + else + TIFFReadSeparateStripData(tif); + } +} + +static void +ShowRawBytes(unsigned char* pp, uint32 n) +{ + tsize_t i; + + for (i = 0; i < n; i++) { + printf(" %02x", *pp++); + if (((i+1) % 24) == 0) + printf("\n "); + } + putchar('\n'); +} + +static void +ShowRawWords(uint16* pp, uint32 n) +{ + tsize_t i; + + for (i = 0; i < n; i++) { + printf(" %04x", *pp++); + if (((i+1) % 15) == 0) + printf("\n "); + } + putchar('\n'); +} + +void +TIFFReadRawData(TIFF* tif, int bitrev) +{ + tstrip_t nstrips = TIFFNumberOfStrips(tif); + const char* what = TIFFIsTiled(tif) ? "Tile" : "Strip"; + uint32* stripbc; + + TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc); + if (nstrips > 0) { + tsize_t bufsize = stripbc[0]; + tdata_t buf = _TIFFmalloc(bufsize); + tstrip_t s; + + for (s = 0; s < nstrips; s++) { + if (stripbc[s] > bufsize) { + buf = _TIFFrealloc(buf, stripbc[s]); + bufsize = stripbc[s]; + } + if (buf == NULL) { + fprintf(stderr, + "Cannot allocate buffer to read strip %lu\n", + (unsigned long) s); + break; + } + if (TIFFReadRawStrip(tif, s, buf, stripbc[s]) < 0) { + fprintf(stderr, "Error reading strip %lu\n", + (unsigned long) s); + if (stoponerr) + break; + } else if (showdata) { + if (bitrev) { + TIFFReverseBits(buf, stripbc[s]); + printf("%s %lu: (bit reversed)\n ", + what, (unsigned long) s); + } else + printf("%s %lu:\n ", what, + (unsigned long) s); + if (showwords) + ShowRawWords((uint16*) buf, stripbc[s]>>1); + else + ShowRawBytes((unsigned char*) buf, stripbc[s]); + } + } + if (buf != NULL) + _TIFFfree(buf); + } +} + +static void +tiffinfo(TIFF* tif, uint16 order, long flags) +{ + TIFFPrintDirectory(tif, stdout, flags); + if (!readdata) + return; + if (rawdata) { + if (order) { + uint16 o; + TIFFGetFieldDefaulted(tif, + TIFFTAG_FILLORDER, &o); + TIFFReadRawData(tif, o != order); + } else + TIFFReadRawData(tif, 0); + } else { + if (order) + TIFFSetField(tif, TIFFTAG_FILLORDER, order); + TIFFReadData(tif); + } +} diff --git a/tools/tiffmedian.c b/tools/tiffmedian.c new file mode 100644 index 00000000..7898cc46 --- /dev/null +++ b/tools/tiffmedian.c @@ -0,0 +1,888 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffmedian.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Apply median cut on an image. + * + * tiffmedian [-c n] [-f] input output + * -C n - set colortable size. Default is 256. + * -f - use Floyd-Steinberg dithering. + * -c lzw - compress output with LZW + * -c none - use no compression on output + * -c packbits - use packbits compression on output + * -r n - create output with n rows/strip of data + * (by default the compression scheme and rows/strip are taken + * from the input file) + * + * Notes: + * + * [1] Floyd-Steinberg dither: + * I should point out that the actual fractions we used were, assuming + * you are at X, moving left to right: + * + * X 7/16 + * 3/16 5/16 1/16 + * + * Note that the error goes to four neighbors, not three. I think this + * will probably do better (at least for black and white) than the + * 3/8-3/8-1/4 distribution, at the cost of greater processing. I have + * seen the 3/8-3/8-1/4 distribution described as "our" algorithm before, + * but I have no idea who the credit really belongs to. + + * Also, I should add that if you do zig-zag scanning (see my immediately + * previous message), it is sufficient (but not quite as good) to send + * half the error one pixel ahead (e.g. to the right on lines you scan + * left to right), and half one pixel straight down. Again, this is for + * black and white; I've not tried it with color. + * -- + * Lou Steinberg + * + * [2] Color Image Quantization for Frame Buffer Display, Paul Heckbert, + * Siggraph '82 proceedings, pp. 297-307 + */ + +#include +#include +#include + +#include "tiffio.h" + +#define MAX_CMAP_SIZE 256 + +#define streq(a,b) (strcmp(a,b) == 0) +#define strneq(a,b,n) (strncmp(a,b,n) == 0) + +#define COLOR_DEPTH 8 +#define MAX_COLOR 256 + +#define B_DEPTH 5 /* # bits/pixel to use */ +#define B_LEN (1L< MAX_CMAP_SIZE) { + fprintf(stderr, + "-c: colormap too big, max %d\n", + MAX_CMAP_SIZE); + usage(); + } + break; + case 'f': /* dither */ + dither = 1; + break; + case 'r': /* rows/strip */ + rowsperstrip = atoi(optarg); + break; + case '?': + usage(); + /*NOTREACHED*/ + } + if (argc - optind != 2) + usage(); + in = TIFFOpen(argv[optind], "r"); + if (in == NULL) + return (-1); + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength); + TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (bitspersample != 8 && bitspersample != 16) { + fprintf(stderr, "%s: Image must have at least 8-bits/sample\n", + argv[optind]); + return (-3); + } + if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) || + photometric != PHOTOMETRIC_RGB || samplesperpixel < 3) { + fprintf(stderr, "%s: Image must have RGB data\n", argv[optind]); + return (-4); + } + TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); + if (config != PLANARCONFIG_CONTIG) { + fprintf(stderr, "%s: Can only handle contiguous data packing\n", + argv[optind]); + return (-5); + } + + /* + * STEP 1: create empty boxes + */ + usedboxes = NULL; + box_list = freeboxes = (Colorbox *)_TIFFmalloc(num_colors*sizeof (Colorbox)); + freeboxes[0].next = &freeboxes[1]; + freeboxes[0].prev = NULL; + for (i = 1; i < num_colors-1; ++i) { + freeboxes[i].next = &freeboxes[i+1]; + freeboxes[i].prev = &freeboxes[i-1]; + } + freeboxes[num_colors-1].next = NULL; + freeboxes[num_colors-1].prev = &freeboxes[num_colors-2]; + + /* + * STEP 2: get histogram, initialize first box + */ + ptr = freeboxes; + freeboxes = ptr->next; + if (freeboxes) + freeboxes->prev = NULL; + ptr->next = usedboxes; + usedboxes = ptr; + if (ptr->next) + ptr->next->prev = ptr; + get_histogram(in, ptr); + + /* + * STEP 3: continually subdivide boxes until no more free + * boxes remain or until all colors assigned. + */ + while (freeboxes != NULL) { + ptr = largest_box(); + if (ptr != NULL) + splitbox(ptr); + else + freeboxes = NULL; + } + + /* + * STEP 4: assign colors to all boxes + */ + for (i = 0, ptr = usedboxes; ptr != NULL; ++i, ptr = ptr->next) { + rm[i] = ((ptr->rmin + ptr->rmax) << COLOR_SHIFT) / 2; + gm[i] = ((ptr->gmin + ptr->gmax) << COLOR_SHIFT) / 2; + bm[i] = ((ptr->bmin + ptr->bmax) << COLOR_SHIFT) / 2; + } + + /* We're done with the boxes now */ + _TIFFfree(box_list); + freeboxes = usedboxes = NULL; + + /* + * STEP 5: scan histogram and map all values to closest color + */ + /* 5a: create cell list as described in Heckbert[2] */ + ColorCells = (C_cell **)_TIFFmalloc(C_LEN*C_LEN*C_LEN*sizeof (C_cell*)); + _TIFFmemset(ColorCells, 0, C_LEN*C_LEN*C_LEN*sizeof (C_cell*)); + /* 5b: create mapping from truncated pixel space to color + table entries */ + map_colortable(); + + /* + * STEP 6: scan image, match input values to table entries + */ + out = TIFFOpen(argv[optind+1], "w"); + if (out == NULL) + return (-2); + + CopyField(TIFFTAG_SUBFILETYPE, longv); + CopyField(TIFFTAG_IMAGEWIDTH, longv); + TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, (short)COLOR_DEPTH); + if (compression != (uint16)-1) { + TIFFSetField(out, TIFFTAG_COMPRESSION, compression); + switch (compression) { + case COMPRESSION_LZW: + case COMPRESSION_DEFLATE: + if (predictor != 0) + TIFFSetField(out, TIFFTAG_PREDICTOR, predictor); + break; + } + } else + CopyField(TIFFTAG_COMPRESSION, compression); + TIFFSetField(out, TIFFTAG_PHOTOMETRIC, (short)PHOTOMETRIC_PALETTE); + CopyField(TIFFTAG_ORIENTATION, shortv); + TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, (short)1); + CopyField(TIFFTAG_PLANARCONFIG, shortv); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, + TIFFDefaultStripSize(out, rowsperstrip)); + CopyField(TIFFTAG_MINSAMPLEVALUE, shortv); + CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv); + CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); + CopyField(TIFFTAG_XRESOLUTION, floatv); + CopyField(TIFFTAG_YRESOLUTION, floatv); + CopyField(TIFFTAG_XPOSITION, floatv); + CopyField(TIFFTAG_YPOSITION, floatv); + + if (dither) + quant_fsdither(in, out); + else + quant(in, out); + /* + * Scale colormap to TIFF-required 16-bit values. + */ +#define SCALE(x) (((x)*((1L<<16)-1))/255) + for (i = 0; i < MAX_CMAP_SIZE; ++i) { + rm[i] = SCALE(rm[i]); + gm[i] = SCALE(gm[i]); + bm[i] = SCALE(bm[i]); + } + TIFFSetField(out, TIFFTAG_COLORMAP, rm, gm, bm); + (void) TIFFClose(out); + return (0); +} + +static int +processCompressOptions(char* opt) +{ + if (streq(opt, "none")) + compression = COMPRESSION_NONE; + else if (streq(opt, "packbits")) + compression = COMPRESSION_PACKBITS; + else if (strneq(opt, "lzw", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_LZW; + } else if (strneq(opt, "zip", 3)) { + char* cp = strchr(opt, ':'); + if (cp) + predictor = atoi(cp+1); + compression = COMPRESSION_DEFLATE; + } else + return (0); + return (1); +} + +char* stuff[] = { +"usage: tiffmedian [options] input.tif output.tif", +"where options are:", +" -r # make each strip have no more than # rows", +" -C # create a colormap with # entries", +" -f use Floyd-Steinberg dithering", +" -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding", +" -c zip[:opts] compress output with deflate encoding", +" -c packbits compress output with packbits encoding", +" -c none use no compression algorithm on output", +"", +"LZW and deflate options:", +" # set predictor value", +"For example, -c lzw:2 to get LZW-encoded data with horizontal differencing", +NULL +}; + +static void +usage(void) +{ + char buf[BUFSIZ]; + int i; + + setbuf(stderr, buf); + for (i = 0; stuff[i] != NULL; i++) + fprintf(stderr, "%s\n", stuff[i]); + exit(-1); +} + +static void +get_histogram(TIFF* in, Colorbox* box) +{ + register unsigned char *inptr; + register int red, green, blue; + register uint32 j, i; + unsigned char *inputline; + + inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + if (inputline == NULL) { + fprintf(stderr, "No space for scanline buffer\n"); + exit(-1); + } + box->rmin = box->gmin = box->bmin = 999; + box->rmax = box->gmax = box->bmax = -1; + box->total = imagewidth * imagelength; + + { register int *ptr = &histogram[0][0][0]; + for (i = B_LEN*B_LEN*B_LEN; i-- > 0;) + *ptr++ = 0; + } + for (i = 0; i < imagelength; i++) { + if (TIFFReadScanline(in, inputline, i, 0) <= 0) + break; + inptr = inputline; + for (j = imagewidth; j-- > 0;) { + red = *inptr++ >> COLOR_SHIFT; + green = *inptr++ >> COLOR_SHIFT; + blue = *inptr++ >> COLOR_SHIFT; + if (red < box->rmin) + box->rmin = red; + if (red > box->rmax) + box->rmax = red; + if (green < box->gmin) + box->gmin = green; + if (green > box->gmax) + box->gmax = green; + if (blue < box->bmin) + box->bmin = blue; + if (blue > box->bmax) + box->bmax = blue; + histogram[red][green][blue]++; + } + } + _TIFFfree(inputline); +} + +static Colorbox * +largest_box(void) +{ + register Colorbox *p, *b; + register int size; + + b = NULL; + size = -1; + for (p = usedboxes; p != NULL; p = p->next) + if ((p->rmax > p->rmin || p->gmax > p->gmin || + p->bmax > p->bmin) && p->total > size) + size = (b = p)->total; + return (b); +} + +static void +splitbox(Colorbox* ptr) +{ + int hist2[B_LEN]; + int first, last; + register Colorbox *new; + register int *iptr, *histp; + register int i, j; + register int ir,ig,ib; + register int sum, sum1, sum2; + enum { RED, GREEN, BLUE } axis; + + /* + * See which axis is the largest, do a histogram along that + * axis. Split at median point. Contract both new boxes to + * fit points and return + */ + i = ptr->rmax - ptr->rmin; + if (i >= ptr->gmax - ptr->gmin && i >= ptr->bmax - ptr->bmin) + axis = RED; + else if (ptr->gmax - ptr->gmin >= ptr->bmax - ptr->bmin) + axis = GREEN; + else + axis = BLUE; + /* get histogram along longest axis */ + switch (axis) { + case RED: + histp = &hist2[ptr->rmin]; + for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { + *histp = 0; + for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { + iptr = &histogram[ir][ig][ptr->bmin]; + for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) + *histp += *iptr++; + } + histp++; + } + first = ptr->rmin; + last = ptr->rmax; + break; + case GREEN: + histp = &hist2[ptr->gmin]; + for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { + *histp = 0; + for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { + iptr = &histogram[ir][ig][ptr->bmin]; + for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) + *histp += *iptr++; + } + histp++; + } + first = ptr->gmin; + last = ptr->gmax; + break; + case BLUE: + histp = &hist2[ptr->bmin]; + for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) { + *histp = 0; + for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) { + iptr = &histogram[ir][ptr->gmin][ib]; + for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) { + *histp += *iptr; + iptr += B_LEN; + } + } + histp++; + } + first = ptr->bmin; + last = ptr->bmax; + break; + } + /* find median point */ + sum2 = ptr->total / 2; + histp = &hist2[first]; + sum = 0; + for (i = first; i <= last && (sum += *histp++) < sum2; ++i) + ; + if (i == first) + i++; + + /* Create new box, re-allocate points */ + new = freeboxes; + freeboxes = new->next; + if (freeboxes) + freeboxes->prev = NULL; + if (usedboxes) + usedboxes->prev = new; + new->next = usedboxes; + usedboxes = new; + + histp = &hist2[first]; + for (sum1 = 0, j = first; j < i; j++) + sum1 += *histp++; + for (sum2 = 0, j = i; j <= last; j++) + sum2 += *histp++; + new->total = sum1; + ptr->total = sum2; + + new->rmin = ptr->rmin; + new->rmax = ptr->rmax; + new->gmin = ptr->gmin; + new->gmax = ptr->gmax; + new->bmin = ptr->bmin; + new->bmax = ptr->bmax; + switch (axis) { + case RED: + new->rmax = i-1; + ptr->rmin = i; + break; + case GREEN: + new->gmax = i-1; + ptr->gmin = i; + break; + case BLUE: + new->bmax = i-1; + ptr->bmin = i; + break; + } + shrinkbox(new); + shrinkbox(ptr); +} + +static void +shrinkbox(Colorbox* box) +{ + register int *histp, ir, ig, ib; + + if (box->rmax > box->rmin) { + for (ir = box->rmin; ir <= box->rmax; ++ir) + for (ig = box->gmin; ig <= box->gmax; ++ig) { + histp = &histogram[ir][ig][box->bmin]; + for (ib = box->bmin; ib <= box->bmax; ++ib) + if (*histp++ != 0) { + box->rmin = ir; + goto have_rmin; + } + } + have_rmin: + if (box->rmax > box->rmin) + for (ir = box->rmax; ir >= box->rmin; --ir) + for (ig = box->gmin; ig <= box->gmax; ++ig) { + histp = &histogram[ir][ig][box->bmin]; + ib = box->bmin; + for (; ib <= box->bmax; ++ib) + if (*histp++ != 0) { + box->rmax = ir; + goto have_rmax; + } + } + } +have_rmax: + if (box->gmax > box->gmin) { + for (ig = box->gmin; ig <= box->gmax; ++ig) + for (ir = box->rmin; ir <= box->rmax; ++ir) { + histp = &histogram[ir][ig][box->bmin]; + for (ib = box->bmin; ib <= box->bmax; ++ib) + if (*histp++ != 0) { + box->gmin = ig; + goto have_gmin; + } + } + have_gmin: + if (box->gmax > box->gmin) + for (ig = box->gmax; ig >= box->gmin; --ig) + for (ir = box->rmin; ir <= box->rmax; ++ir) { + histp = &histogram[ir][ig][box->bmin]; + ib = box->bmin; + for (; ib <= box->bmax; ++ib) + if (*histp++ != 0) { + box->gmax = ig; + goto have_gmax; + } + } + } +have_gmax: + if (box->bmax > box->bmin) { + for (ib = box->bmin; ib <= box->bmax; ++ib) + for (ir = box->rmin; ir <= box->rmax; ++ir) { + histp = &histogram[ir][box->gmin][ib]; + for (ig = box->gmin; ig <= box->gmax; ++ig) { + if (*histp != 0) { + box->bmin = ib; + goto have_bmin; + } + histp += B_LEN; + } + } + have_bmin: + if (box->bmax > box->bmin) + for (ib = box->bmax; ib >= box->bmin; --ib) + for (ir = box->rmin; ir <= box->rmax; ++ir) { + histp = &histogram[ir][box->gmin][ib]; + ig = box->gmin; + for (; ig <= box->gmax; ++ig) { + if (*histp != 0) { + box->bmax = ib; + goto have_bmax; + } + histp += B_LEN; + } + } + } +have_bmax: + ; +} + +static C_cell * +create_colorcell(int red, int green, int blue) +{ + register int ir, ig, ib, i; + register C_cell *ptr; + int mindist, next_n; + register int tmp, dist, n; + + ir = red >> (COLOR_DEPTH-C_DEPTH); + ig = green >> (COLOR_DEPTH-C_DEPTH); + ib = blue >> (COLOR_DEPTH-C_DEPTH); + ptr = (C_cell *)_TIFFmalloc(sizeof (C_cell)); + *(ColorCells + ir*C_LEN*C_LEN + ig*C_LEN + ib) = ptr; + ptr->num_ents = 0; + + /* + * Step 1: find all colors inside this cell, while we're at + * it, find distance of centermost point to furthest corner + */ + mindist = 99999999; + for (i = 0; i < num_colors; ++i) { + if (rm[i]>>(COLOR_DEPTH-C_DEPTH) != ir || + gm[i]>>(COLOR_DEPTH-C_DEPTH) != ig || + bm[i]>>(COLOR_DEPTH-C_DEPTH) != ib) + continue; + ptr->entries[ptr->num_ents][0] = i; + ptr->entries[ptr->num_ents][1] = 0; + ++ptr->num_ents; + tmp = rm[i] - red; + if (tmp < (MAX_COLOR/C_LEN/2)) + tmp = MAX_COLOR/C_LEN-1 - tmp; + dist = tmp*tmp; + tmp = gm[i] - green; + if (tmp < (MAX_COLOR/C_LEN/2)) + tmp = MAX_COLOR/C_LEN-1 - tmp; + dist += tmp*tmp; + tmp = bm[i] - blue; + if (tmp < (MAX_COLOR/C_LEN/2)) + tmp = MAX_COLOR/C_LEN-1 - tmp; + dist += tmp*tmp; + if (dist < mindist) + mindist = dist; + } + + /* + * Step 3: find all points within that distance to cell. + */ + for (i = 0; i < num_colors; ++i) { + if (rm[i] >> (COLOR_DEPTH-C_DEPTH) == ir && + gm[i] >> (COLOR_DEPTH-C_DEPTH) == ig && + bm[i] >> (COLOR_DEPTH-C_DEPTH) == ib) + continue; + dist = 0; + if ((tmp = red - rm[i]) > 0 || + (tmp = rm[i] - (red + MAX_COLOR/C_LEN-1)) > 0 ) + dist += tmp*tmp; + if ((tmp = green - gm[i]) > 0 || + (tmp = gm[i] - (green + MAX_COLOR/C_LEN-1)) > 0 ) + dist += tmp*tmp; + if ((tmp = blue - bm[i]) > 0 || + (tmp = bm[i] - (blue + MAX_COLOR/C_LEN-1)) > 0 ) + dist += tmp*tmp; + if (dist < mindist) { + ptr->entries[ptr->num_ents][0] = i; + ptr->entries[ptr->num_ents][1] = dist; + ++ptr->num_ents; + } + } + + /* + * Sort color cells by distance, use cheap exchange sort + */ + for (n = ptr->num_ents - 1; n > 0; n = next_n) { + next_n = 0; + for (i = 0; i < n; ++i) + if (ptr->entries[i][1] > ptr->entries[i+1][1]) { + tmp = ptr->entries[i][0]; + ptr->entries[i][0] = ptr->entries[i+1][0]; + ptr->entries[i+1][0] = tmp; + tmp = ptr->entries[i][1]; + ptr->entries[i][1] = ptr->entries[i+1][1]; + ptr->entries[i+1][1] = tmp; + next_n = i; + } + } + return (ptr); +} + +static void +map_colortable(void) +{ + register int *histp = &histogram[0][0][0]; + register C_cell *cell; + register int j, tmp, d2, dist; + int ir, ig, ib, i; + + for (ir = 0; ir < B_LEN; ++ir) + for (ig = 0; ig < B_LEN; ++ig) + for (ib = 0; ib < B_LEN; ++ib, histp++) { + if (*histp == 0) { + *histp = -1; + continue; + } + cell = *(ColorCells + + (((ir>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) + + ((ig>>(B_DEPTH-C_DEPTH)) << C_DEPTH) + + (ib>>(B_DEPTH-C_DEPTH)))); + if (cell == NULL ) + cell = create_colorcell( + ir << COLOR_SHIFT, + ig << COLOR_SHIFT, + ib << COLOR_SHIFT); + dist = 9999999; + for (i = 0; i < cell->num_ents && + dist > cell->entries[i][1]; ++i) { + j = cell->entries[i][0]; + d2 = rm[j] - (ir << COLOR_SHIFT); + d2 *= d2; + tmp = gm[j] - (ig << COLOR_SHIFT); + d2 += tmp*tmp; + tmp = bm[j] - (ib << COLOR_SHIFT); + d2 += tmp*tmp; + if (d2 < dist) { + dist = d2; + *histp = j; + } + } + } +} + +/* + * straight quantization. Each pixel is mapped to the colors + * closest to it. Color values are rounded to the nearest color + * table entry. + */ +static void +quant(TIFF* in, TIFF* out) +{ + unsigned char *outline, *inputline; + register unsigned char *outptr, *inptr; + register uint32 i, j; + register int red, green, blue; + + inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + outline = (unsigned char *)_TIFFmalloc(imagewidth); + for (i = 0; i < imagelength; i++) { + if (TIFFReadScanline(in, inputline, i, 0) <= 0) + break; + inptr = inputline; + outptr = outline; + for (j = 0; j < imagewidth; j++) { + red = *inptr++ >> COLOR_SHIFT; + green = *inptr++ >> COLOR_SHIFT; + blue = *inptr++ >> COLOR_SHIFT; + *outptr++ = histogram[red][green][blue]; + } + if (TIFFWriteScanline(out, outline, i, 0) < 0) + break; + } + _TIFFfree(inputline); + _TIFFfree(outline); +} + +#define SWAP(type,a,b) { type p; p = a; a = b; b = p; } + +#define GetInputLine(tif, row, bad) \ + if (TIFFReadScanline(tif, inputline, row, 0) <= 0) \ + bad; \ + inptr = inputline; \ + nextptr = nextline; \ + for (j = 0; j < imagewidth; ++j) { \ + *nextptr++ = *inptr++; \ + *nextptr++ = *inptr++; \ + *nextptr++ = *inptr++; \ + } +#define GetComponent(raw, cshift, c) \ + cshift = raw; \ + if (cshift < 0) \ + cshift = 0; \ + else if (cshift >= MAX_COLOR) \ + cshift = MAX_COLOR-1; \ + c = cshift; \ + cshift >>= COLOR_SHIFT; + +static void +quant_fsdither(TIFF* in, TIFF* out) +{ + unsigned char *outline, *inputline, *inptr; + short *thisline, *nextline; + register unsigned char *outptr; + register short *thisptr, *nextptr; + register uint32 i, j; + uint32 imax, jmax; + int lastline, lastpixel; + + imax = imagelength - 1; + jmax = imagewidth - 1; + inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in)); + thisline = (short *)_TIFFmalloc(imagewidth * 3 * sizeof (short)); + nextline = (short *)_TIFFmalloc(imagewidth * 3 * sizeof (short)); + outline = (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out)); + + GetInputLine(in, 0, goto bad); /* get first line */ + for (i = 1; i <= imagelength; ++i) { + SWAP(short *, thisline, nextline); + lastline = (i >= imax); + if (i <= imax) + GetInputLine(in, i, break); + thisptr = thisline; + nextptr = nextline; + outptr = outline; + for (j = 0; j < imagewidth; ++j) { + int red, green, blue; + register int oval, r2, g2, b2; + + lastpixel = (j == jmax); + GetComponent(*thisptr++, r2, red); + GetComponent(*thisptr++, g2, green); + GetComponent(*thisptr++, b2, blue); + oval = histogram[r2][g2][b2]; + if (oval == -1) { + int ci; + register int cj, tmp, d2, dist; + register C_cell *cell; + + cell = *(ColorCells + + (((r2>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) + + ((g2>>(B_DEPTH-C_DEPTH)) << C_DEPTH ) + + (b2>>(B_DEPTH-C_DEPTH)))); + if (cell == NULL) + cell = create_colorcell(red, + green, blue); + dist = 9999999; + for (ci = 0; ci < cell->num_ents && dist > cell->entries[ci][1]; ++ci) { + cj = cell->entries[ci][0]; + d2 = (rm[cj] >> COLOR_SHIFT) - r2; + d2 *= d2; + tmp = (gm[cj] >> COLOR_SHIFT) - g2; + d2 += tmp*tmp; + tmp = (bm[cj] >> COLOR_SHIFT) - b2; + d2 += tmp*tmp; + if (d2 < dist) { + dist = d2; + oval = cj; + } + } + histogram[r2][g2][b2] = oval; + } + *outptr++ = oval; + red -= rm[oval]; + green -= gm[oval]; + blue -= bm[oval]; + if (!lastpixel) { + thisptr[0] += blue * 7 / 16; + thisptr[1] += green * 7 / 16; + thisptr[2] += red * 7 / 16; + } + if (!lastline) { + if (j != 0) { + nextptr[-3] += blue * 3 / 16; + nextptr[-2] += green * 3 / 16; + nextptr[-1] += red * 3 / 16; + } + nextptr[0] += blue * 5 / 16; + nextptr[1] += green * 5 / 16; + nextptr[2] += red * 5 / 16; + if (!lastpixel) { + nextptr[3] += blue / 16; + nextptr[4] += green / 16; + nextptr[5] += red / 16; + } + nextptr += 3; + } + } + if (TIFFWriteScanline(out, outline, i-1, 0) < 0) + break; + } +bad: + _TIFFfree(inputline); + _TIFFfree(thisline); + _TIFFfree(nextline); + _TIFFfree(outline); +} diff --git a/tools/tiffsplit.c b/tools/tiffsplit.c new file mode 100644 index 00000000..76cf396d --- /dev/null +++ b/tools/tiffsplit.c @@ -0,0 +1,226 @@ +/* $Header: /cvs/maptools/cvsroot/libtiff/tools/tiffsplit.c,v 1.1 1999-07-27 21:50:28 mike Exp $ */ + +/* + * Copyright (c) 1992-1997 Sam Leffler + * Copyright (c) 1992-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "tiffio.h" + +#define streq(a,b) (strcmp(a,b) == 0) +#define CopyField(tag, v) \ + if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v) +#define CopyField2(tag, v1, v2) \ + if (TIFFGetField(in, tag, &v1, &v2)) TIFFSetField(out, tag, v1, v2) +#define CopyField3(tag, v1, v2, v3) \ + if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3) + +static char fname[1024+1]; + +static int tiffcp(TIFF*, TIFF*); +static void newfilename(void); +static int cpStrips(TIFF*, TIFF*); +static int cpTiles(TIFF*, TIFF*); + +int +main(int argc, char* argv[]) +{ + TIFF *in, *out; + + if (argc < 2) { + fprintf(stderr, "usage: tiffsplit input.tif [prefix]\n"); + return (-3); + } + if (argc > 2) + strcpy(fname, argv[2]); + in = TIFFOpen(argv[1], "r"); + if (in != NULL) { + do { + char path[1024+1]; + newfilename(); + strcpy(path, fname); + strcat(path, ".tif"); + out = TIFFOpen(path, "w"); + if (out == NULL) + return (-2); + if (!tiffcp(in, out)) + return (-1); + TIFFClose(out); + } while (TIFFReadDirectory(in)); + (void) TIFFClose(in); + } + return (0); +} + +static void +newfilename(void) +{ + static int first = 1; + static long fnum; + static short defname; + static char *fpnt; + + if (first) { + if (fname[0]) { + fpnt = fname + strlen(fname); + defname = 0; + } else { + fname[0] = 'x'; + fpnt = fname + 1; + defname = 1; + } + first = 0; + } +#define MAXFILES 676 + if (fnum == MAXFILES) { + if (!defname || fname[0] == 'z') { + fprintf(stderr, "tiffsplit: too many files.\n"); + exit(1); + } + fname[0]++; + fnum = 0; + } + fpnt[0] = fnum / 26 + 'a'; + fpnt[1] = fnum % 26 + 'a'; + fnum++; +} + +static int +tiffcp(TIFF* in, TIFF* out) +{ + short bitspersample, samplesperpixel, shortv, *shortav; + uint32 w, l; + float floatv; + char *stringv; + uint32 longv; + + CopyField(TIFFTAG_SUBFILETYPE, longv); + CopyField(TIFFTAG_TILEWIDTH, w); + CopyField(TIFFTAG_TILELENGTH, l); + CopyField(TIFFTAG_IMAGEWIDTH, w); + CopyField(TIFFTAG_IMAGELENGTH, l); + CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample); + CopyField(TIFFTAG_COMPRESSION, shortv); + CopyField(TIFFTAG_PREDICTOR, shortv); + CopyField(TIFFTAG_PHOTOMETRIC, shortv); + CopyField(TIFFTAG_THRESHHOLDING, shortv); + CopyField(TIFFTAG_FILLORDER, shortv); + CopyField(TIFFTAG_ORIENTATION, shortv); + CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel); + CopyField(TIFFTAG_MINSAMPLEVALUE, shortv); + CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv); + CopyField(TIFFTAG_XRESOLUTION, floatv); + CopyField(TIFFTAG_YRESOLUTION, floatv); + CopyField(TIFFTAG_GROUP3OPTIONS, longv); + CopyField(TIFFTAG_GROUP4OPTIONS, longv); + CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); + CopyField(TIFFTAG_PLANARCONFIG, shortv); + CopyField(TIFFTAG_ROWSPERSTRIP, longv); + CopyField(TIFFTAG_XPOSITION, floatv); + CopyField(TIFFTAG_YPOSITION, floatv); + CopyField(TIFFTAG_IMAGEDEPTH, longv); + CopyField(TIFFTAG_TILEDEPTH, longv); + CopyField2(TIFFTAG_EXTRASAMPLES, shortv, shortav); + { uint16 *red, *green, *blue; + CopyField3(TIFFTAG_COLORMAP, red, green, blue); + } + { uint16 shortv2; + CopyField2(TIFFTAG_PAGENUMBER, shortv, shortv2); + } + CopyField(TIFFTAG_ARTIST, stringv); + CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv); + CopyField(TIFFTAG_MAKE, stringv); + CopyField(TIFFTAG_MODEL, stringv); + CopyField(TIFFTAG_SOFTWARE, stringv); + CopyField(TIFFTAG_DATETIME, stringv); + CopyField(TIFFTAG_HOSTCOMPUTER, stringv); + CopyField(TIFFTAG_PAGENAME, stringv); + CopyField(TIFFTAG_DOCUMENTNAME, stringv); + if (TIFFIsTiled(in)) + return (cpTiles(in, out)); + else + return (cpStrips(in, out)); +} + +static int +cpStrips(TIFF* in, TIFF* out) +{ + tsize_t bufsize = TIFFStripSize(in); + unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); + + if (buf) { + tstrip_t s, ns = TIFFNumberOfStrips(in); + uint32 *bytecounts; + + TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); + for (s = 0; s < ns; s++) { + if (bytecounts[s] > bufsize) { + buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); + if (!buf) + return (0); + bufsize = bytecounts[s]; + } + if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || + TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { + _TIFFfree(buf); + return (0); + } + } + _TIFFfree(buf); + return (1); + } + return (0); +} + +static int +cpTiles(TIFF* in, TIFF* out) +{ + tsize_t bufsize = TIFFTileSize(in); + unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); + + if (buf) { + ttile_t t, nt = TIFFNumberOfTiles(in); + uint32 *bytecounts; + + TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); + for (t = 0; t < nt; t++) { + if (bytecounts[t] > bufsize) { + buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); + if (!buf) + return (0); + bufsize = bytecounts[t]; + } + if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || + TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { + _TIFFfree(buf); + return (0); + } + } + _TIFFfree(buf); + return (1); + } + return (0); +} diff --git a/tools/ycbcr.c b/tools/ycbcr.c new file mode 100644 index 00000000..2fdfb0ce --- /dev/null +++ b/tools/ycbcr.c @@ -0,0 +1,161 @@ +float ycbcrCoeffs[3] = { .299, .587, .114 }; +/* default coding range is CCIR Rec 601-1 with no headroom/footroom */ +unsigned long refBlackWhite[6] = { 0, 255, 128, 255, 128, 255 }; + +#define LumaRed ycbcrCoeffs[0] +#define LumaGreen ycbcrCoeffs[1] +#define LumaBlue ycbcrCoeffs[2] + +long eRtotal = 0; +long eGtotal = 0; +long eBtotal = 0; +long preveRtotal = 0; +long preveGtotal = 0; +long preveBtotal = 0; +unsigned long AbseRtotal = 0; +unsigned long AbseGtotal = 0; +unsigned long AbseBtotal = 0; +unsigned long eCodes = 0; +unsigned long preveCodes = 0; +unsigned long eBits = 0; +unsigned long preveBits = 0; + +static void setupLumaTables(); +static int abs(int v) { return (v < 0 ? -v : v); } +static double pct(int v,double range) { return (v*100. / range); } +static void check(int R, int G, int B); + +float D1, D2; +float D3, D4; +float D5, D6; + +int +main(int argc, char* argv) +{ + int R, G, B; + + if (argc > 1) { + refBlackWhite[0] = 16; + refBlackWhite[1] = 235; + refBlackWhite[2] = 128; + refBlackWhite[3] = 240; + refBlackWhite[4] = 128; + refBlackWhite[5] = 240; + } + D3 = 2 - 2*LumaRed; + D4 = 2 - 2*LumaBlue; + D1 = 1. / D3; + D2 = 1. / D4; + D5 = D3*LumaRed / LumaGreen; + D6 = D4*LumaBlue / LumaGreen; + setupLumaTables(); + for (R = 0; R < 256; R++) { + for (G = 0; G < 256; G++) + for (B = 0; B < 256; B++) + check(R, G, B); + printf("[%3u] c %u/%u b %u/%u (R %u/%d/%u G %u/%d/%u B %u/%d/%u)\n" + , R + , eCodes - preveCodes, eCodes + , eBits - preveBits, eBits + , abs(AbseRtotal - preveRtotal), eRtotal , AbseRtotal + , abs(AbseGtotal - preveGtotal), eGtotal , AbseGtotal + , abs(AbseBtotal - preveBtotal), eBtotal , AbseBtotal + ); + preveRtotal = AbseRtotal; + preveGtotal = AbseGtotal; + preveBtotal = AbseBtotal; + preveCodes = eCodes; + preveBits = eBits; + } + printf("%u total codes\n", 256*256*256); + printf("total error: %u codes %u bits (R %d/%u G %d/%u B %d/%u)\n" + , eCodes + , eBits + , eRtotal , AbseRtotal + , eGtotal , AbseGtotal + , eBtotal , AbseBtotal + ); + return (0); +} + +float *lumaRed; +float *lumaGreen; +float *lumaBlue; + +static float* +setupLuma(float c) +{ + float *v = (float *)_TIFFmalloc(256 * sizeof (float)); + int i; + for (i = 0; i < 256; i++) + v[i] = c * i; + return (v); +} + +static void +setupLumaTables(void) +{ + lumaRed = setupLuma(LumaRed); + lumaGreen = setupLuma(LumaGreen); + lumaBlue = setupLuma(LumaBlue); +} + +static unsigned +V2Code(float f, unsigned long RB, unsigned long RW, int CR) +{ + unsigned int c = (unsigned int)((((f)*(RW-RB)/CR)+RB)+.5); + return (c > 255 ? 255 : c); +} + +#define Code2V(c, RB, RW, CR) ((((c)-(int)RB)*(float)CR)/(float)(RW-RB)) + +#define CLAMP(f,min,max) \ + (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5) + +static +void +check(int R, int G, int B) +{ + float Y, Cb, Cr; + int iY, iCb, iCr; + float rY, rCb, rCr; + float rR, rG, rB; + int eR, eG, eB; + + Y = lumaRed[R] + lumaGreen[G] + lumaBlue[B]; + Cb = (B - Y)*D2; + Cr = (R - Y)*D1; + iY = V2Code(Y, refBlackWhite[0], refBlackWhite[1], 255); + iCb = V2Code(Cb, refBlackWhite[2], refBlackWhite[3], 127); + iCr = V2Code(Cr, refBlackWhite[4], refBlackWhite[5], 127); + rCb = Code2V(iCb, refBlackWhite[2], refBlackWhite[3], 127); + rCr = Code2V(iCr, refBlackWhite[4], refBlackWhite[5], 127); + rY = Code2V(iY, refBlackWhite[0], refBlackWhite[1], 255); + rR = rY + rCr*D3; + rB = rY + rCb*D4; + rG = rY - rCb*D6 - rCr*D5; + eR = R - CLAMP(rR,0,255); + eG = G - CLAMP(rG,0,255); + eB = B - CLAMP(rB,0,255); + if (abs(eR) > 1 || abs(eG) > 1 || abs(eB) > 1) { + printf("R %u G %u B %u", R, G, B); + printf(" Y %g Cb %g Cr %g", Y, Cb, Cr); + printf(" iY %u iCb %u iCr %u", iY, iCb, iCr); + printf("\n -> Y %g Cb %g Cr %g", rY, rCb, rCr); + printf(" R %g (%u) G %g (%u) B %g (%u) E=[%d %d %d])\n" + , rR, CLAMP(rR,0,255) + , rG, CLAMP(rG,0,255) + , rB, CLAMP(rB,0,255) + , eR, eG, eB + ); + } + eRtotal += eR; + eGtotal += eG; + eBtotal += eB; + AbseRtotal += abs(eR); + AbseGtotal += abs(eG); + AbseBtotal += abs(eB); + if (eR | eG | eB) + eCodes++; + eBits += abs(eR) + abs(eG) + abs(eB); +}