summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Leffler <sam@engr.sgi.com>1995-07-19 01:54:06 +0100
committerRoger Leigh <rleigh@codelibre.net>2022-06-22 18:34:33 +0100
commit9448a913ed3e137176b45c9b304271e47a6da035 (patch)
tree653e07d6a153c7a82e2fba11c67cc59f1513465e
downloadlibtiff-git-9448a913ed3e137176b45c9b304271e47a6da035.tar.gz
v3.4beta018 releasev3.4beta018
-rw-r--r--COPYRIGHT21
-rw-r--r--Makefile.in424
-rw-r--r--README60
-rw-r--r--TODO10
-rw-r--r--VERSION1
-rwxr-xr-xconfig.guess473
-rw-r--r--config.site141
-rwxr-xr-xconfig.sub793
-rwxr-xr-xconfigure1510
-rw-r--r--contrib/dbs/Imakefile12
-rw-r--r--contrib/dbs/README7
-rw-r--r--contrib/dbs/tiff-bi.c85
-rw-r--r--contrib/dbs/tiff-grayscale.c141
-rw-r--r--contrib/dbs/tiff-palette.c277
-rw-r--r--contrib/dbs/tiff-rgb.c196
-rw-r--r--contrib/dbs/xtiff/Imakefile17
-rw-r--r--contrib/dbs/xtiff/README6
-rw-r--r--contrib/dbs/xtiff/patchlevel.h1
-rw-r--r--contrib/dbs/xtiff/xtiff.c1275
-rw-r--r--contrib/dbs/xtiff/xtifficon.h14
-rw-r--r--contrib/mac-mpw/BUILD.mpw47
-rw-r--r--contrib/mac-mpw/README20
-rw-r--r--contrib/mac-mpw/libtiff.make202
-rw-r--r--contrib/mac-mpw/mactrans.c56
-rw-r--r--contrib/mac-mpw/port.make53
-rw-r--r--contrib/mac-mpw/tools.make138
-rw-r--r--contrib/mac-mpw/top.make133
-rw-r--r--contrib/ras/ras2tif.c244
-rw-r--r--contrib/ras/tif2ras.c337
-rw-r--r--contrib/tags/Makefile.gcc56
-rw-r--r--contrib/tags/Makefile.mpw67
-rw-r--r--contrib/tags/README116
-rw-r--r--contrib/tags/listtif.c32
-rw-r--r--contrib/tags/maketif.c70
-rw-r--r--contrib/tags/xtif_dir.c343
-rw-r--r--contrib/tags/xtiffio.h52
-rw-r--r--contrib/tags/xtiffiop.h65
-rw-r--r--contrib/vms/libtiff/makevms.com189
-rw-r--r--contrib/vms/libtiff/tiff.opt1
-rwxr-xr-xcontrib/vms/libtiff/tiffshraxp.opt117
-rw-r--r--contrib/vms/libtiff/tiffshrvax.opt18
-rw-r--r--contrib/vms/libtiff/tiffvec.mar126
-rw-r--r--contrib/vms/tools/makevms.com134
-rwxr-xr-xdist/newalpha8
-rw-r--r--dist/newversion32
-rw-r--r--dist/tiff.alpha1
-rw-r--r--dist/tiff.spec73
-rw-r--r--dist/tiff.version1
-rw-r--r--html/Makefile.in96
-rw-r--r--html/bugs.html66
-rw-r--r--html/build.html901
-rw-r--r--html/contrib.html99
-rw-r--r--html/document.html60
-rw-r--r--html/images.html48
-rw-r--r--html/images/back.gifbin0 -> 1000 bytes
-rw-r--r--html/images/bali.jpgbin0 -> 26152 bytes
-rw-r--r--html/images/cat.gifbin0 -> 12477 bytes
-rw-r--r--html/images/cover.jpgbin0 -> 20189 bytes
-rw-r--r--html/images/cramps.gifbin0 -> 13137 bytes
-rw-r--r--html/images/dave.gifbin0 -> 8220 bytes
-rw-r--r--html/images/info.gifbin0 -> 131 bytes
-rw-r--r--html/images/jello.jpgbin0 -> 13744 bytes
-rw-r--r--html/images/jim.gifbin0 -> 14493 bytes
-rw-r--r--html/images/note.gifbin0 -> 264 bytes
-rw-r--r--html/images/oxford.gifbin0 -> 6069 bytes
-rw-r--r--html/images/quad.jpgbin0 -> 23904 bytes
-rw-r--r--html/images/ring.gifbin0 -> 4275 bytes
-rw-r--r--html/images/smallliz.jpgbin0 -> 16463 bytes
-rw-r--r--html/images/strike.gifbin0 -> 5610 bytes
-rw-r--r--html/images/warning.gifbin0 -> 287 bytes
-rw-r--r--html/index.html88
-rw-r--r--html/internals.html627
-rw-r--r--html/intro.html80
-rw-r--r--html/libtiff.html742
-rw-r--r--html/misc.html104
-rw-r--r--html/support.html671
-rw-r--r--html/tools.html188
-rw-r--r--html/v3.4beta007.html111
-rw-r--r--html/v3.4beta016.html121
-rw-r--r--html/v3.4beta018.html83
-rw-r--r--libtiff/Makefile.in281
-rw-r--r--libtiff/Makefile.lcc129
-rw-r--r--libtiff/Makefile.msc151
-rw-r--r--libtiff/mkg3states.c425
-rw-r--r--libtiff/mkspans.c72
-rw-r--r--libtiff/t4.h285
-rw-r--r--libtiff/tif_apple.c256
-rw-r--r--libtiff/tif_atari.c243
-rw-r--r--libtiff/tif_aux.c200
-rw-r--r--libtiff/tif_close.c51
-rw-r--r--libtiff/tif_codec.c95
-rw-r--r--libtiff/tif_compress.c205
-rw-r--r--libtiff/tif_dir.c981
-rw-r--r--libtiff/tif_dir.h220
-rw-r--r--libtiff/tif_dirinfo.c360
-rw-r--r--libtiff/tif_dirread.c1373
-rw-r--r--libtiff/tif_dirwrite.c972
-rw-r--r--libtiff/tif_dumpmode.c114
-rw-r--r--libtiff/tif_error.c49
-rw-r--r--libtiff/tif_fax3.c1462
-rw-r--r--libtiff/tif_fax3.h496
-rw-r--r--libtiff/tif_flush.c60
-rw-r--r--libtiff/tif_getimage.c1806
-rw-r--r--libtiff/tif_jpeg.c1480
-rw-r--r--libtiff/tif_lzw.c1018
-rw-r--r--libtiff/tif_msdos.c179
-rw-r--r--libtiff/tif_next.c142
-rw-r--r--libtiff/tif_open.c399
-rw-r--r--libtiff/tif_packbits.c262
-rw-r--r--libtiff/tif_predict.c468
-rw-r--r--libtiff/tif_predict.h61
-rw-r--r--libtiff/tif_print.c491
-rw-r--r--libtiff/tif_read.c600
-rw-r--r--libtiff/tif_strip.c190
-rw-r--r--libtiff/tif_swab.c217
-rw-r--r--libtiff/tif_thunder.c154
-rw-r--r--libtiff/tif_tile.c213
-rw-r--r--libtiff/tif_unix.c209
-rw-r--r--libtiff/tif_version.c34
-rw-r--r--libtiff/tif_vms.c583
-rw-r--r--libtiff/tif_warning.c49
-rw-r--r--libtiff/tif_win3.c225
-rw-r--r--libtiff/tif_write.c592
-rw-r--r--libtiff/tif_zip.c286
-rw-r--r--libtiff/tiff.h331
-rw-r--r--libtiff/tiffcomp.h149
-rw-r--r--libtiff/tiffconf.h127
-rw-r--r--libtiff/tiffio.h298
-rw-r--r--libtiff/tiffiop.h264
-rw-r--r--man/Makefile.in206
-rw-r--r--man/TIFFClose.3t51
-rw-r--r--man/TIFFError.3t69
-rw-r--r--man/TIFFFlush.3t64
-rw-r--r--man/TIFFGetField.3t196
-rw-r--r--man/TIFFOpen.3t189
-rw-r--r--man/TIFFPrintDirectory.3t71
-rw-r--r--man/TIFFReadDirectory.3t159
-rw-r--r--man/TIFFReadEncodedStrip.3t73
-rw-r--r--man/TIFFReadEncodedTile.3t76
-rw-r--r--man/TIFFReadRGBAImage.3t177
-rw-r--r--man/TIFFReadRawStrip.3t62
-rw-r--r--man/TIFFReadRawTile.3t64
-rw-r--r--man/TIFFReadScanline.3t98
-rw-r--r--man/TIFFReadTile.3t85
-rw-r--r--man/TIFFSetDirectory.3t65
-rw-r--r--man/TIFFSetField.3t184
-rw-r--r--man/TIFFWarning.3t70
-rw-r--r--man/TIFFWriteDirectory.3t104
-rw-r--r--man/TIFFWriteEncodedStrip.3t95
-rw-r--r--man/TIFFWriteEncodedTile.3t98
-rw-r--r--man/TIFFWriteRawStrip.3t83
-rw-r--r--man/TIFFWriteRawTile.3t83
-rw-r--r--man/TIFFWriteScanline.3t162
-rw-r--r--man/fax2ps.1158
-rw-r--r--man/fax2tiff.1205
-rw-r--r--man/gif2tiff.176
-rw-r--r--man/intro.3t359
-rw-r--r--man/pal2rgb.1106
-rw-r--r--man/ppm2tiff.194
-rw-r--r--man/query.3t114
-rw-r--r--man/ras2tiff.187
-rw-r--r--man/rgb2ycbcr.199
-rw-r--r--man/sgi2tiff.186
-rw-r--r--man/size.3t83
-rw-r--r--man/strip.3t57
-rw-r--r--man/swab.3t73
-rw-r--r--man/thumbnail.187
-rw-r--r--man/tiff2bw.185
-rw-r--r--man/tiff2ps.1169
-rw-r--r--man/tiffcmp.174
-rw-r--r--man/tiffcp.1199
-rw-r--r--man/tiffdither.1122
-rw-r--r--man/tiffdump.174
-rw-r--r--man/tiffgt.1143
-rw-r--r--man/tiffinfo.182
-rw-r--r--man/tiffmedian.1106
-rw-r--r--man/tiffsplit.166
-rw-r--r--man/tiffsv.1134
-rw-r--r--man/tile.3t91
-rw-r--r--port/Makefile.in69
-rw-r--r--port/getopt.c116
-rw-r--r--port/install.sh.in246
-rw-r--r--port/irix/so_locations4
-rw-r--r--port/strcasecmp.c99
-rw-r--r--port/strtoul.c107
-rw-r--r--tools/Makefile.in243
-rw-r--r--tools/Makefile.lcc132
-rw-r--r--tools/fax2ps.c409
-rw-r--r--tools/fax2tiff.c361
-rw-r--r--tools/gif2tiff.c517
-rw-r--r--tools/pal2rgb.c389
-rw-r--r--tools/ppm2tiff.c245
-rw-r--r--tools/ras2tiff.c267
-rw-r--r--tools/rasterfile.h41
-rw-r--r--tools/rgb2ycbcr.c342
-rw-r--r--tools/sgi2tiff.c291
-rw-r--r--tools/sgigt.c979
-rw-r--r--tools/sgisv.c314
-rw-r--r--tools/thumbnail.c575
-rw-r--r--tools/tiff2bw.c404
-rw-r--r--tools/tiff2ps.c935
-rw-r--r--tools/tiffcmp.c486
-rw-r--r--tools/tiffcp.c1230
-rw-r--r--tools/tiffdither.c317
-rw-r--r--tools/tiffdump.c725
-rw-r--r--tools/tiffinfo.c428
-rw-r--r--tools/tiffmedian.c891
-rw-r--r--tools/tiffsplit.c230
-rw-r--r--tools/ycbcr.c159
209 files changed, 48751 insertions, 0 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 00000000..78cb834e
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,21 @@
+Copyright (c) 1988-1995 Sam Leffler
+Copyright (c) 1991-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.
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 00000000..71867cf3
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,424 @@
+#! smake
+# $Header: /usr/people/sam/tiff/RCS/Makefile.in,v 1.25 1995/07/19 01:53:48 sam Exp $
+#
+# @WARNING@
+#
+# Tag Image File Format Library
+#
+# Copyright (c) 1988-1995 Sam Leffler
+# Copyright (c) 1991-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 = ${DEPTH}/@SRCDIR@
+
+#
+# VERSION: @VERSION@
+# DATE: @DATE@
+# TARGET: @TARGET@
+# CCOMPILER: @CCOMPILER@
+# CXXCOMPILER: @CXXCOMPILER@
+#
+@SETMAKE@
+SHELL = /bin/sh
+NULL =
+ECHO = echo
+
+all default:
+ @if [ "@PORT@" = yes ]; then \
+ ${ECHO} "= "port; cd port; ${MAKE}; \
+ fi
+ @${ECHO} "= "libtiff; cd libtiff; ${MAKE}
+ @${ECHO} "= "tools; cd tools; ${MAKE}
+ @${ECHO} "= "man; cd man; ${MAKE}
+ @if [ "@HTML@" = yes ]; then \
+ ${ECHO} "= "html; cd html; ${MAKE}; \
+ fi
+
+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; \
+ fi
+
+clean:
+ @if [ "@PORT@" = yes ]; then \
+ ${ECHO} "= "port; cd port; ${MAKE} clean; \
+ fi
+ @${ECHO} "= "libtiff; cd libtiff; ${MAKE} clean
+ @${ECHO} "= "tools; cd tools; ${MAKE} clean
+ @${ECHO} "= "man; cd man; ${MAKE} clean
+ @if [ "@HTML@" = yes ]; then \
+ ${ECHO} "= "html; cd html; ${MAKE} clean; \
+ fi
+# -cd contrib/dbs; ${MAKE} clean
+# -cd contrib/dbs/xtiff; ${MAKE} clean
+
+clobber distclean: clean
+ rm -f Makefile port.h config.log
+ rm -f libtiff/Makefile
+ rm -f tools/Makefile
+ rm -f man/Makefile
+ rm -f port/Makefile port/install.sh
+
+#
+# The folllowing rule creates a binary distribution for IRIX.
+#
+product::
+ rm -f dist/rawidb
+ SRC=`pwd` RAWIDB=`pwd`/dist/rawidb ${MAKE} install
+ 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/Makefile.msc \
+ libtiff/t4.h \
+ libtiff/tiff.h \
+ libtiff/tiffcomp.h \
+ libtiff/tiffconf.h \
+ libtiff/tiffio.h \
+ libtiff/tiffiop.h \
+ libtiff/mkg3states.c \
+ libtiff/mkspans.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_lzw.c \
+ libtiff/tif_msdos.c \
+ libtiff/tif_next.c \
+ libtiff/tif_open.c \
+ libtiff/tif_packbits.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_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/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/intro.3t \
+ man/query.3t \
+ man/size.3t \
+ man/strip.3t \
+ man/swab.3t \
+ man/tile.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.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/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 \
+ contrib/mac-mpw \
+ ${NULL}
+DISTFILES=\
+ ${TIFFFILES} \
+ dist/tiff.alpha \
+ dist/tiff.version \
+ ${OTHERFILES} \
+ ${CONTRIBFILES} \
+ ${NULL}
+
+CONFIG=\
+ -with-CC=ncc \
+ -with-GCOPTS=" " \
+ -with-JPEG=yes \
+ -with-DIR_JPEG=../src/jpeg-5a \
+ -with-ZIP=yes \
+ -with-DIR_LIBGZ=../src/zlib \
+ -with-HTML \
+ ${NULL}
+
+rcsclean:
+ rcsclean ${TIFFFILES} && co ${TIFFFILES}
+
+alpha:
+ (cd ${SRCDIR}/dist; sh newalpha; 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=`awk '{print "Alpha" $$3}' ${SRCDIR}/dist/tiff.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 '{for (i=1; i<=$$3; i++) printf " -nAlpha%03d",i}'\
+ ${SRCDIR}/dist/tiff.alpha`; \
+ 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="v`cat ${SRCDIR}/VERSION``awk '{print $$3}' ${SRCDIR}/dist/tiff.alpha`"; \
+ 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:
+ VERSION="Release`sed 's/\./_/g' ${SRCDIR}/VERSION`"; \
+ NOW=`date`; \
+ for i in ${TIFFFILES}; do \
+ REV=`rlog -h -d"$$NOW" ${SRCDIR}/$$i|fgrep 'head:'|awk '{print $$2}'`;\
+ rcs "-N$$VERSION:$$REV" "-sRel:$$REV" ${SRCDIR}/$$i && co -sRel ${SRCDIR}/$$i; \
+ done
+
+# create release distribution archive
+release.tar:
+ VERSION=v`cat ${SRCDIR}/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..cb680214
--- /dev/null
+++ b/README
@@ -0,0 +1,60 @@
+$Header: /usr/people/sam/tiff/RCS/README,v 1.26 1995/07/01 00:57:02 sam 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-1995 Sam Leffler
+Copyright (c) 1991-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.
diff --git a/TODO b/TODO
new file mode 100644
index 00000000..1b6beea0
--- /dev/null
+++ b/TODO
@@ -0,0 +1,10 @@
+# $Header: /usr/people/sam/tiff/RCS/TODO,v 1.2 1995/07/03 18:42:38 sam Exp $
+
+o update manual pages
+o tiffcmp read data by strip/tile instead of scanline
+o YCbCr sampling support
+o html manual pages
+o extracate colorspace conversion support
+o look at isolating all codecs from TIFF library
+o tiffcp problem with JPEG-encoded image
+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..595d40fa
--- /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 <bothner@cygnus.com>.
+# 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 <sys/systemcfg.h>
+
+ 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 <unistd.h>
+ 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 ;;
+ i[34]86: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 /bin/uname -X 2>/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
+ elif test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-unknown-isc$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 <<EOF
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+ printf ("m68k-sony-newsos\n"); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/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..15d0760e
--- /dev/null
+++ b/config.site
@@ -0,0 +1,141 @@
+# $Header: /usr/people/sam/tiff/RCS/config.site,v 1.5 1995/07/17 14:53:35 sam Exp $
+#
+# TIFF Software
+#
+# Copyright (c) 1990-1995 Sam Leffler
+# Copyright (c) 1991-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.
+#
+
+#
+# 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" # yes|no|auto configure DSO support
+#HTML="no" # yes|no configure HTML documentation
+#JPEG="no" # yes|no configure JPEG support
+#ZIP="no" # yes|no configure Deflate support
+#LIBGL="auto" # yes|no|auto configure IRIS GL-based tools
+#LIBIMAGE="auto" # yes|no|auto configure SGI RGB image tools
+
+#
+# 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
+
+#
+# JPEG-specific parameters; used when JPEG support is enabled.
+#
+# NB: JPEG support requires release 5 or later of the IJG code,
+# which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
+#
+#DIR_JPEG="../jpeg" # directory for JPEG include files
+#LIBJPEG="-L \${JPEGDIR} -ljpeg" # JPEG library to load
+
+#
+# Deflate-specific parameters; used when Deflate support is enabled.
+#
+# NB: Deflate support requires version 0.92 or later of the libgz
+# library written by Jean-loup Gailly and Mark Adler. The library
+# was last found at ftp://ftp.uu.net/graphics/png/code/zlib-0.93.tar.gz.
+#
+#DIR_LIBGZ="../zlib" # directory for libgz include files
+#LIBGZ="-L \${ZIPDIR} -lgz" # libgz library to load
+
+#
+# HTML-specific parameters; only used when the
+# HTML package is configured for installation.
+#
+# Note that ``PATH''s are the virtual pathnames used
+# in forming URLs; they are not directory pathnames
+# in the filesystem.
+#
+#DIR_HTML="/var/httpd/htdocs/tiff" # directory for HTML documentation
+#DIR_CGI="/var/httpd/cgi-bin" # directory for CGI scripts
+#HTMLPATH="/tiff" # virtual path to HTML materials
+#CGIPATH="/cgi-bin" # virtual path to CGI scripts
+
+#
+# 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
+
+#
+# Dynamic Shared Object (DSO) support.
+#
+# Beware that adding new support for DSOs may require some
+# modifications to the */Makefile.dso files.
+#
+#DSOSUF="so" # DSO filename suffix
+#DSOOPTS="-shared -rdata_shared" # options for building DSOs
+
+#
+# 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
+#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..b4f5891c
--- /dev/null
+++ b/configure
@@ -0,0 +1,1510 @@
+#!/bin/sh
+# $Header: /usr/people/sam/tiff/RCS/configure,v 1.15 1995/07/17 14:57:08 sam Exp $
+#
+# Tag Image File Format (TIFF) Software
+#
+# Copyright (c) 1988-1995 Sam Leffler
+# Copyright (c) 1991-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.
+#
+
+# Configuration script for the TIFF Software
+
+#
+# Shell script to setup machine-dependent files in
+# preparation for building TIFF source.
+#
+
+#
+# Setup general configuration parameters.
+#
+DIR_BIN=/usr/local/bin
+DIR_LIB=/usr/local/lib
+DIR_INC=/usr/local/include
+DIR_HTML=/var/httpd/htdocs/tiff
+DIR_CGI=/var/httpd/cgi-bin
+DIR_JPEG=.
+DIR_LIBGZ=.
+HTMLPATH=/tiff
+CGIPATH=/cgi-bin
+DSO=auto
+HTML=no
+JPEG=no
+ZIP=no
+PORT=auto
+LIBGL=auto
+LIBIMAGE=auto
+MACHDEPLIBS=-lm
+
+: ${MAKE=make} # make to use
+# screws up the test of `-f -'
+unset MAKEFLAGS
+RM="rm -f"
+
+POSIXLY_CORRECT=1; export POSIXLY_CORRECT # disable GNU extensions
+
+#
+# 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
+ --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
+}
+
+QUIET=no
+SITE=
+TARGET=
+SRCDIR=
+#
+# 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;;
+ -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.15 $"
+ 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 "Can not locate sources in $SRCDIR."
+ kill -1 $$
+fi
+SRCDIR=`echo "$SRCDIR" | sed 's;\([^/]\)/*$;\1;'`
+
+#
+# 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
+
+VERSION="v`cat $SRCDIR/VERSION``awk '{print $3}' $SRCDIR/dist/tiff.alpha`"
+DATE=`date`
+
+Note()
+{
+ echo "$@" 1>&4
+}
+
+Note ""
+Note "Configuring TIFF Software $VERSION."
+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
+elif [ -f $SRCDIR/config.site ]; then
+ Note "Reading site-wide parameters from $SRCDIR/config.site."
+ . $SRCDIR/config.site
+fi
+if [ -f config.local ]; then
+ Note "Reading local parameters from config.local."
+ . ./config.local
+elif [ -f $SRCDIR/config.local ]; then
+ Note "Reading local parameters from $SRCDIR/config.local."
+ . $SRCDIR/config.local
+fi
+
+identifyTarget()
+{
+ random=`date | awk '{print $4}' | sed -e 's/.*://'` 2>/dev/null
+ case "$random" in
+ 1*) Note "Wow, you've got a $1 system!";;
+ 2*) Note "Hmm, looks like a $1 system.";;
+ 3*) Note "Oh no, not another $1 system...";;
+ 4*) Note "Well I'll be, a $1 system.";;
+ 5*) Note "Fee, fie, foe, this smells like a $1 system.";;
+ *) Note "Gosh, aren't you lucky to have 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
+
+cat 1>&5 <<EOF
+This file contains any messages produced by compilers while
+running configure, to aid in debugging if configure makes a mistake.
+
+EOF
+
+#
+# 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
+}
+
+#
+# Locate a C and C++ compiler and verify they work and
+# satisfy our needs (using assorted heuristics).
+#
+JUNK="
+ a.out
+ confsed
+ conftestmmap
+ confx confy
+ 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<<EOF
+#ifdef __GNUC__
+yes;
+#endif
+EOF
+
+#
+# Check if the specified compiler is from GNU
+#
+isGNU()
+{
+ $1 -E xgnu.c 2>&5 | egrep yes >/dev/null 2>&1
+}
+
+#
+# NB: use ANSI C prototype to weed out non-ANSI compilers.
+#
+cat>dummy.c<<EOF
+main(int argc, char* argv) { exit(0); }
+EOF
+
+: ${ENVOPTS=}
+CCOMPILER=
+for i in $CC gcc cc ncc dcc xlc c89 gcc2; do
+ if isGNU $i; then
+ ISGCC=yes
+ else
+ ISGCC=no
+ fi
+ #
+ # Guess special options needed to get an
+ # ANSI C compiler and/or similar. Should
+ # probably be combined with above checks
+ # so we only select an ANSI C compiler.
+ #
+ if [ -z "$ENVOPTS" ]; then
+ case $ISGCC-$TARGET in
+ no-*-irix*) C_ANSI=-ansi;;
+ no-*-hp*) C_ANSI="-Aa -D_HPUX_SOURCE -Dhpux";;
+ no-*-apollo-*) C_ANSI="-A nansi";;
+ *-sco*) C_ANSI="-Dsco";;
+ *-aix*) C_ANSI="-Dunix -qlanglvl=ansi -qsrcmsg" ;;
+ esac
+ else
+ C_ANSI="$ENVOPTS"
+ fi
+ $RM dummy dummy.o
+ ($i -o dummy $C_ANSI dummy.c) >/dev/null 2>&5 && {
+ CC=$i;
+ CCOMPILER=`findApp $i $PATH`
+ if [ -z "$ENVOPTS" ]; then
+ ENVOPTS="$C_ANSI"
+ fi
+ break;
+ }
+done
+if [ -z "$CCOMPILER" ]; then
+ cat<<EOF
+Cannot locate a working ANSI C compiler.
+
+If the compiler is in a non-standard location, set the environment
+variable CC to the absolute pathname of the compiler that is to be used
+and rerun this script.
+
+If command line options are required for ANSI C compilation, set the
+variable ENVOPTS to these options and rerun this script.
+
+If you are trying to use GNU gcc, but you do not have version 2.6.1
+or newer, then you must update your compiler (and probably libg++ as
+well) before you can compile this software. Consult the documentation
+for information about obtaining an up-to-date version of gcc.
+EOF
+ boom
+fi
+Note "Using $CCOMPILER for a C compiler (set CC to override)."
+
+test "$ENVOPTS" && {
+ Note "Using $ENVOPTS to get the appropriate compilation environment."
+}
+
+CheckForGandO()
+{
+ f=$1
+ if test -s $f; then
+ grep -i \(error\|warning\) $f 1>&5 2>&5 || return 1
+ fi
+ return 0
+}
+
+if [ -z "$GCOPTS" ]; then
+ $CCOMPILER $ENVOPTS -g -c dummy.c >/dev/null 2>&5 && {
+ Note "Looks like $CCOMPILER supports the -g option."
+ if $CCOMPILER $ENVOPTS $GCOPTS -c -g -O dummy.c >t 2>&1 && CheckForGandO t; then
+ GCOPTS="$GCOPTS -g"
+ else
+ Note "... but not together with the -O option, not using it."
+ fi
+ }
+fi
+if [ "$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<<EOF
+
+Something is wrong with "$MAKE" or $MAKE does not accept Makefiles
+from stdin with "-f -". If you have MAKE set in your environment,
+verify it points to the right program you want to" use to build this
+software. Otherwise, verify that you have the make program installed
+somewhere on your system and set the MAKE environment variable to the
+pathname of the program.
+EOF
+ boom
+ }
+else
+ cat<<EOF
+No $MAKE located in the search path.
+
+There was no $MAKE program in the restricted search used by this script
+If $MAKE is in a non-standard location set the MAKE environment variable
+to the pathname of the appropriate program.
+EOF
+ boom
+fi
+
+#
+# Check whether or not $MAKE automatically sets MAKE
+# in the Makefiles. If not, we add an explicit define
+# for places where recursive calls are made.
+#
+if [ -z "$SETMAKE" ]; then
+M=
+eval `(cat<<'EOF'
+all:
+ @echo M="${MAKE}"
+EOF
+) | $MAKE -f - 2>&5`
+ if [ "$M" ]; then
+ SETMAKE=
+ else
+ Note "Looks like $MAKE does not setup MAKE in Makefiles, will compensate."
+ SETMAKE="MAKE = ${MAKE}"
+ fi
+fi
+
+test "$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 "$AROPTS" || AROPTS=rc
+test "$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; then
+ AROPTS=crs
+ Note "Looks like ar has an s option to build symbol tables."
+ fi
+fi
+
+#
+# runMake target rules ...
+#
+runMake()
+{
+ target="$1"; shift
+ $RM $target
+ (for i in "$@"; do
+ echo "$i";
+ done) | ${MAKE} -f - $target 2>&5
+}
+
+#
+# Look for a library using a known (unique) function.
+#
+CheckForLibrary()
+{
+ f=$1; shift
+ libs="$@";
+ cat>t.c<<EOF
+int t() { $f(); return 0; }
+int main(){ t(); return 0; }
+EOF
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} t.c $libs" >/dev/null
+}
+
+#
+# Look for an include file.
+#
+CheckForIncludeFile()
+{
+ (for i do
+ echo "#include \"$i\""
+ done)>t.c
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" >/dev/null
+}
+
+#
+# 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}" >/dev/null
+}
+
+#
+# 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
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" |\
+ awk '{while($0~/[,(][ \t]*$/){printf"%s",$0;getline}print}' |\
+ grep "$f[ ]*(.*)" >/dev/null
+ 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
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" | grep "$v" >/dev/null
+ 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
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} -E t.c" | grep FOUND >/dev/null
+}
+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 <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+EOF
+ else
+ cat>t.c<<'EOF'
+/* this was lifted from GNU autoconf */
+/* Thanks to Mike Haertel and Jim Avera for this test. */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#ifdef BSD
+# ifndef BSD4_1
+# define HAVE_GETPAGESIZE
+# endif
+#endif
+
+#ifndef HAVE_GETPAGESIZE
+# include <sys/param.h>
+# 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
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} t.c" >/dev/null
+}
+
+CheckForBigEndian()
+{
+ echo 'main() { int one = 1; char* cp = (char*)&one; exit(*cp!=0); }'>t.c
+ runMake t "t:; ${CCOMPILER} ${ENVOPTS} t.c" >/dev/null
+}
+
+#
+# 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 port.h; target="$param"
+ getConfigTag CCOMPILER port.h; ccompiler="$param"
+ CCOMP=$CCOMPILER
+ if [ $ISGCC = yes ]; then
+ getGCCVersion()
+ {
+ eval `$1 -v 2>&1 | \
+ sed -n -e '/version/s/.* \([0-9]*\)\.\([0-9]*\).\([0-9]*\)/GCCdist=\1;GCCmajor=\2;GCCminor=\3/p'`
+ GCCversion="${GCCdist}.${GCCmajor}.${GCCminor}"
+ }
+ getGCCVersion $CCOMPILER
+ CCOMP="${CCOMP}-${GCCversion}"
+ fi
+ test "$target" = "$TARGET" && test "$ccompiler" = "$CCOMP"
+}
+
+#
+# Built port.h based on the system and compiler setup.
+#
+BuildPortDotH()
+{
+ Note ""
+ Note "Creating port.h with necessary definitions."
+
+ (EmitCPlusPlusPrologue _PORT_
+
+ CheckForIncludeFile sys/types.h && echo '#include <sys/types.h>'
+ CheckVarDecl mode_t 'typedef int mode_t;' sys/types.h stdlib.h
+ 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
+
+ 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
+ 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 <stdio.h>'
+ CheckForIncludeFile unistd.h && echo '#include <unistd.h>'
+ CheckForIncludeFile string.h && echo '#include <string.h>'
+ CheckForIncludeFile stdlib.h && echo '#include <stdlib.h>'
+ if CheckForDefine O_RDONLY fcntl.h; then
+ echo '#include <fcntl.h>'
+ Note "... O_RDONLY is in <fcntl.h>"
+ elif CheckForDefine O_RDONLY sys/file.h; then
+ echo '#include <sys/file.h>'
+ Note "... O_RDONLY is in <sys/file.h>"
+ 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 strcasecmp \
+ 'extern int strcasecmp(const char*, const char*);' string.h
+ 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);' math.h
+ CheckFuncDecl unlink 'extern int unlink(const char*);' unistd.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
+ CheckFuncDecl strtoul \
+ 'extern unsigned long strtoul(const char*, char**, int);' stdlib.h
+ #
+ # unistd.h is for sco3.2v4.[0-2] and GNU libc (yech!)
+ #
+ CheckFuncDecl getopt \
+ 'extern int getopt(int, char* const*, const char*);' stdlib.h unistd.h
+ CheckVarDecl 'char.*optarg' 'extern char* optarg;' stdlib.h unistd.h
+ CheckVarDecl 'int.*opterr' 'extern int opterr;' stdlib.h unistd.h
+ CheckVarDecl 'int.*optind' 'extern int optind;' stdlib.h unistd.h
+ EmitCPlusPlusEpilogue
+ )>xport.h
+ mv xport.h port.h; chmod 444 port.h
+ Note "Done creating port.h."
+}
+
+if test -f port.h && CheckPortDotH; then
+ Note ""
+ Note "Using previously created port.h."
+else
+ $RM xport.h t.c a.out port.h
+ BuildPortDotH
+fi
+
+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
+Note "Done checking system libraries."
+
+Note ""
+Note "Checking for Dynamic Shared Object (DSO) support."
+if [ "$DSO" = auto ]; then
+ case $TARGET in
+ *-irix*)
+ if (findApp rld /lib:/usr/lib:$PATH) >/dev/null 2>&1; then
+ DSOSUF=so
+ DSOOPTS='-shared -rdata_shared -check_registry ${SRCDIR}/${PORT}/irix/so_locations -quickstart_info'
+ fi
+ ;;
+ *) DSO=no;;
+ 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<<EOF
+int f() { return 0; }
+EOF
+ runMake t \
+ "t.o:; ${CCOMPILER} ${ENVOPTS} -c t.c" \
+ "t: t.o; ${CCOMPILER} ${ENVOPTS} ${DSOOPTS} -o t.${DSOSUF} t.o" >/dev/null
+ }
+ if CheckCCDSO; then
+ Note "Looks like your system supports SVR4-style DSOs."
+ DSO=yes
+ else
+ cat 1>&4 <<EOF
+Looks like your system supports SVR4-style DSOs...
+... sigh, but $CCOMPILER does not support DSOs in the expected way.
+EOF
+ DSO=no
+ fi
+fi
+Note "Done checking for DSO support."
+
+if [ "$DSO" = no ]; then
+ MAKEDSOINCLUDE='#'
+ DSOSUF=a DSOOPTS=
+else
+ MAKEDSOINCLUDE="$MAKEINCLUDE"
+fi
+
+Note ""
+if [ "$LIBIMAGE" = auto ]; then
+ if CheckForLibrary iopen -limage && CheckForIncludeFile gl/image.h; then
+ Note "Looks like there is support for SGI RGB images."
+ LIBIMAGE=yes
+ else
+ LIBIMAGE=no
+ fi
+fi
+if [ "$LIBGL" = auto ]; then
+ if CheckForLibrary winopen -lgl && CheckForIncludeFile gl.h; then
+ Note "Looks like there is support for IRIS GL."
+ LIBGL=yes
+ else
+ LIBGL=no
+ fi
+fi
+
+test $LIBGL = no -a $LIBIMAGE = no || Note ""
+Note "Selecting programs used during installation."
+
+
+#
+# Miscellaneous ``little'' programs.
+#
+test "$CHMOD" || CHMOD=`findAppDef chmod $PATH chmod`
+test "$LN" || LN=`findAppDef ln $PATH ln`
+test "$SED" || SED=`findAppDef sed $PATH sed`
+test "$STRIP" || STRIP=`findAppDef strip $PATH strip`
+
+#
+# Check if mv -f is supported
+#
+if [ -z "$MV_F" ]; then
+ $RM t.c; echo "">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 <<EOF
+
+"$x" is not a valid manual page installation scheme. 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.
+
+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<<EOF
+
+TIFF configuration parameters are:
+
+[ 1] Directory for tools: $DIR_BIN
+[ 2] Directory for libraries: $DIR_LIB
+[ 3] Directory for include files: $DIR_INC
+[ 4] Directory for manual pages: $DIR_MAN
+[ 5] Directory for HTML documentation: $DIR_HTML
+[ 6] Manual page installation scheme: $MANSCHEME
+
+EOF
+}
+
+promptForParameter()
+{
+ case $1 in
+ 1) promptForNonNullStringParameter "$DIR_BIN" \
+ "Directory to install tools"; DIR_BIN="$param"
+ ;;
+ 2) promptForNonNullStringParameter "$DIR_LIB" \
+ "Directory to install libraries"; DIR_LIB="$param"
+ ;;
+ 3) promptForNonNullStringParameter "$DIR_INC" \
+ "Directory to install include files"; DIR_INC="$param"
+ ;;
+ 4) promptForNonNullStringParameter "$DIR_MAN" \
+ "Directory to install manual pages"; DIR_MAN="$param"
+ ;;
+ 5) promptForNonNullStringParameter "$DIR_HTML" \
+ "Directory to install HTML documentation"; DIR_HTML="$param"
+ ;;
+ 6) promptForManPageScheme;;
+ esac
+}
+
+if [ $QUIET = no ]; then
+ ok=skip
+ while [ "$ok" != y ] && [ "$ok" != yes ]; do
+ if [ "$ok" != skip ]; then
+ for i in 1 2 3 4 5 6; do
+ promptForParameter $i;
+ done
+ fi
+ printConfig; prompt "Are these ok [yes]?"; read ok
+ test -z "$ok" && ok=yes
+ case "$ok" in
+ [1-9]|1[0-7]) promptForParameter $ok;;
+ [yY]*|[nN]*) continue;;
+ ?*)
+ echo ""
+ echo "\"y\", \"yes\", or <RETURN> accepts the displayed parameters."
+ echo "A number lets you change the numbered parameter."
+ echo ""
+ ;;
+ esac
+ ok=skip
+ if [ "${JPEG}" = yes ]; then
+ test -d "${DIR_JPEG}" || {
+ cat<<EOF
+
+The JPEG source directory, ${DIR_JPEG}, does not seem to be setup
+correctly. This must be corrected if the JPEG support is to be enabled.
+Either fix the pathname or disable the JPEG support.
+
+EOF
+ }
+ fi
+ if [ "${ZIP}" = yes ]; then
+ test -d "${DIR_LIBGZ}" || {
+ cat<<EOF
+
+The libgz source directory, ${DIR_LIBGZ}, does not seem to be setup
+correctly. This must be corrected if the ZIP support is to be enabled.
+Either fix the pathname or disable the ZIP support.
+
+EOF
+ }
+ fi
+ done
+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";;
+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.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 "$CONF_JPEG" || CONF_JPEG="-DJPEG_SUPPORT"
+ test "$LIBJPEG" || LIBJPEG="\${JPEGDIR}/libjpeg.a"
+else
+ CONF_JPEG=
+ LIBJPEG=
+fi
+if [ "${ZIP}" = yes ]; then
+ test "$CONF_ZIP" || CONF_ZIP="-DZIP_SUPPORT"
+ test "$LIBGZ" || LIBGZ="\${ZIPDIR}/libgz.a"
+else
+ CONF_ZIP=
+ LIBGZ=
+fi
+
+Note ""
+
+# NB: these should be sorted alphabetically
+cat>>confsed<<EOF
+/@AR@/s;;${AR};g
+/@AROPTS@/s;;${AROPTS};g
+/@CCOMPILER@/s;;${CCOMPILER};g
+/@CGIPATH@/s;;${CGIPATH};g
+/@CHMOD@/s;;${CHMOD};g
+/@CONF_JPEG@/s;;${CONF_JPEG};g
+/@CONF_ZIP@/s;;${CONF_ZIP};g
+/@DATE@/s;;${DATE};g
+/@DIR_BIN@/s;;${DIR_BIN};g
+/@DIR_CGI@/s;;${DIR_CGI};g
+/@DIR_HTML@/s;;${DIR_HTML};g
+/@DIR_JPEG@/s;;${DIR_JPEG};g
+/@DIR_LIBGZ@/s;;${DIR_LIBGZ};g
+/@DIR_INC@/s;;${DIR_INC};g
+/@DIR_LIB@/s;;${DIR_LIB};g
+/@DIR_MAN@/s;;${DIR_MAN};g
+/@DSO@/s;;${DSO};g
+/@DSOOPTS@/s;;${DSOOPTS};g
+/@DSOSUF@/s;;${DSOSUF};g
+/@ENVOPTS@/s;;${ENVOPTS};g
+/@FILLORDER@/s;;${FILLORDER};g
+/@GCOPTS@/s;;${GCOPTS};g
+/@HTML@/s;;${HTML};g
+/@HTMLPATH@/s;;${HTMLPATH};g
+/@INSTALL@/s;;${INSTALL};g
+/@LIBJPEG@/s;;${LIBJPEG};g
+/@LIBGL@/s;;${LIBGL};g
+/@LIBGZ@/s;;${LIBGZ};g
+/@LIBIMAGE@/s;;${LIBIMAGE};g
+/@LIBPORT@/s;;${LIBPORT};g
+/@LN@/s;;${LN};g
+/@LN_S@/s;;${LN_S};g
+/@MACHDEPLIBS@/s;;${MACHDEPLIBS};g
+/@MAKEDSOINCLUDE@/s;;${MAKEDSOINCLUDE};g
+/@MANAPPS@/s;;${MANAPPS};g
+/@MANAPPNAME@/s;;${MANAPPNAME};g
+/@MANLIBNAME@/s;;${MANLIBNAME};g
+/@MANCVT@/s;;${MANCVT};g
+/@MANSEDLOCAL@/s;;${MANSEDLOCAL};g
+/@MANLIB@/s;;${MANLIB};g
+/@MV_F@/s;;${MV_F};g
+/@PORT@/s;;${PORT};g
+/@PORTFUNCS@/s;;${PORTFUNCS};g
+/@RANLIB@/s;;${RANLIB};g
+/@SED@/s;;${SED};g
+/@SETMAKE@/s;;${SETMAKE};g
+/@SRCDIR@/s;;${SRCDIR};g
+/@STRIP@/s;;${STRIP};g
+/@TARGET@/s;;${TARGET};g
+/@VERSION@/s;;${VERSION};g
+/@WARNING@/s;;Warning, this file was automatically created by the TIFF configure script;g
+
+EOF
+
+SedConfigFiles()
+{
+ for F do
+ test -f $SRCDIR/$F.in || {
+ bitch "$SRCDIR/$F.in is missing; this should be part of the distribution."
+ boom
+ }
+ dir=`echo $F | $SED 's;/[^/]*$;;'`
+ if [ $dir != $F ] && [ ! -d $dir ]; then
+ Note "Creating $dir directory"
+ mkdir $dir
+ fi
+ suffix=`echo $F | $SED 's/.*\.//'`
+ if [ "$suffix" = h ]; then
+ #
+ # Compare old and new versions so that include files
+ # are only updated when something has changed--this
+ # saves time for subsequent makes. Note we screen
+ # out use of @DATE@ 'cuz otherwise that'll mess up
+ # the comparison (this assumes dates are used in lines
+ # of the form DATE: @DATE@).
+ #
+ $RM $F.new; $SED -f confsed $SRCDIR/$F.in > $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 <<EOF
+Help, there was a problem crafting $F from $F.in.
+The command:
+
+ $SED -f confsed $SRCDIR/$F.in >$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
+ libtiff/Makefile
+ man/Makefile
+ tools/Makefile
+ port/install.sh
+"
+SedConfigFiles $CONF_FILES
+test $PORT = yes && SedConfigFiles port/Makefile
+test $HTML = yes && SedConfigFiles html/Makefile
+
+#
+# NB: the dist directory is needed only when building SGI inst images.
+#
+test -d dist || mkdir dist
+
+Note "Done."
+
+$RM $JUNK
+exit 0
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 <stdio.h>
+#include <tiffio.h>
+
+#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 <math.h>
+#include <stdio.h>
+#include <tiffio.h>
+
+#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<<bits_per_pixel) - 1;
+
+ 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_MINISBLACK);
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+ TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refblackwhite);
+ TIFFSetField(tif, TIFFTAG_TRANSFERFUNCTION, gray);
+ TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
+
+ scan_line = (u_char *) malloc(WIDTH / (8 / bits_per_pixel));
+
+ for (i = 0; i < HEIGHT; i++) {
+ for (j = 0, k = 0; j < WIDTH;) {
+ gray_index = (j / chunk_size) + ((i / chunk_size) * nchunks);
+
+ switch (bits_per_pixel) {
+ case 8:
+ scan_line[k++] = gray_index;
+ j++;
+ break;
+ case 4:
+ scan_line[k++] = (gray_index << 4) + gray_index;
+ j += 2;
+ break;
+ case 2:
+ scan_line[k++] = (gray_index << 6) + (gray_index << 4)
+ + (gray_index << 2) + gray_index;
+ j += 4;
+ break;
+ }
+ }
+ TIFFWriteScanline(tif, scan_line, i, 0);
+ }
+
+ free(scan_line);
+ TIFFClose(tif);
+ exit(0);
+}
+
+void
+Usage()
+{
+ fprintf(stderr, "Usage: %s -depth (8 | 4 | 2) tiff-image\n", programName);
+ exit(0);
+}
diff --git a/contrib/dbs/tiff-palette.c b/contrib/dbs/tiff-palette.c
new file mode 100644
index 00000000..3c456ff3
--- /dev/null
+++ b/contrib/dbs/tiff-palette.c
@@ -0,0 +1,277 @@
+/*
+ * tiff-palette.c -- create a Class P (palette) 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 <stdio.h>
+#include <tiffio.h>
+
+#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 <math.h>
+#include <stdio.h>
+#include <tiffio.h>
+
+#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 <math.h>
+#include <stdio.h>
+#include <tiffio.h>
+#include <X11/Xatom.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xproto.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Label.h>
+#include <X11/cursorfont.h>
+#define XK_MISCELLANY
+#include <X11/keysymdef.h>
+#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[] = "<Key>q: quit() \n \
+ <Key>Q: quit() \n \
+ <Message>WM_PROTOCOLS: quit()\n \
+ <Key>p: previous() \n \
+ <Key>P: previous() \n \
+ <Key>n: next() \n \
+ <Key>N: next() \n \
+ <Configure>: 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/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 <file>.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 <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+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/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 <stdio.h>
+#include <sys/time.h>
+#include <pixrect/pixrect_hs.h>
+#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 <stdio.h>
+#include <pixrect/pixrect_hs.h>
+#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/tags/Makefile.gcc b/contrib/tags/Makefile.gcc
new file mode 100644
index 00000000..c4db62a2
--- /dev/null
+++ b/contrib/tags/Makefile.gcc
@@ -0,0 +1,56 @@
+# Makefile for XLIBTIFF
+#
+# Written by: Niles Ritter
+#
+# This Makefile is for use with gcc (2.2.2 or later)
+#
+DESTDIR=.
+#
+AR = /usr/bin/ar
+AROPTS = rc
+RANLIB = /usr/bin/ranlib
+NULL=
+
+TIFFLIB=../../libtiff
+PORT=../..
+
+IPATH= -I. -I${TIFFLIB} -I${PORT}
+CONF_LIBRARY=\
+ ${NULL}
+CC= gcc
+COPTS= -ansi -g
+CFLAGS= ${COPTS} ${IPATH} ${CONF_LIBRARY}
+#
+LIBS= ./libxtiff.a ${TIFFLIB}/libtiff.a
+
+OBJS= \
+ xtif_dir.o \
+ maketif.o \
+ listtif.o \
+ ${NULL}
+
+PROGS= maketif listtif
+LIBXTIFF= libxtiff.a
+ALL= ${LIBXTIFF} ${PROGS}
+
+all: ${ALL}
+
+library: ${LIBXTIFF}
+
+test: ${PROGS}
+ ./maketif
+ ./listtif
+
+maketif: maketif.o libxtiff.a
+ ${CC} ${COPTS} maketif.o ${LIBS} -o maketif
+
+listtif: listtif.o libxtiff.a
+ ${CC} ${COPTS} listtif.o ${LIBS} -o listtif
+
+libxtiff.a: xtif_dir.o
+ ${AR} ${AROPTS} libxtiff.a xtif_dir.o
+ ${RANLIB} libxtiff.a
+
+clean:
+ rm -f ${ALL} ${OBJS} core a.out newtif.tif
+
diff --git a/contrib/tags/Makefile.mpw b/contrib/tags/Makefile.mpw
new file mode 100644
index 00000000..92f506f3
--- /dev/null
+++ b/contrib/tags/Makefile.mpw
@@ -0,0 +1,67 @@
+#***********************************************************************
+#
+# MPW build file for example LIBXTIFF utilities
+#
+# written by Niles D. Ritter.
+#
+CC = c
+AR = lib -o
+RM = delete -y
+LN = duplicate -y
+
+#debug option
+#DEBUG= -sym full
+DEBUG=
+
+# data/code model options
+#MODEL=
+MODEL= -model far
+
+TIFFLIB = :::libtiff:
+
+LINK.c = Link {LDFLAGS}
+.o Ä .c
+ {CC} {DEBUG} {CFLAGS} {CPPFLAGS} {Default}.c -o {Default}.o
+LDFLAGS = {DEBUG} {MODEL} -c 'MPS ' -t MPST -w
+CFLAGS = {MODEL}
+CPPFLAGS = -I {TIFFLIB}
+OBJS = maketif.o listtif.o xtif_dir.o
+CLEANOBJS = maketif.o listtif.o xtif_dir.o
+CLEANOTHER = newtif.tif
+CLEANINC =
+LIBS = {TIFFLIB}libtiff.o ¶
+ libxtiff.o ¶
+ "{CLibraries}"StdClib.o ¶
+ "{Libraries}"Stubs.o ¶
+ "{Libraries}"Runtime.o ¶
+ "{Libraries}"Interface.o
+
+PROGS= maketif listtif
+LIBXTIFF= libxtiff.o
+ALL= {LIBXTIFF} {PROGS}
+
+all Ä {ALL}
+
+library Ä {LIBXTIFF}
+
+test Ä {PROGS}
+ maketif
+ listtif
+
+compile Ä {OBJS}
+
+maketif Ä maketif.o libxtiff.o
+ {LINK.c} -o maketif maketif.o {LIBS}
+
+listtif Ä listtif.o libxtiff.o
+ {LINK.c} -o listtif listtif.o {LIBS}
+
+libxtiff.o Ä xtif_dir.o
+ lib -o libxtiff.o xtif_dir.o
+
+clean Ä
+ {RM} {CLEANOBJS} || set status 0
+ {RM} {LIBXTIFF} || set status 0
+ {RM} {PROGS} || set status 0
+ {RM} Å.tif || set status 0
+
diff --git a/contrib/tags/README b/contrib/tags/README
new file mode 100644
index 00000000..2d096100
--- /dev/null
+++ b/contrib/tags/README
@@ -0,0 +1,116 @@
+
+Client module for adding to LIBTIFF tagset
+-------------------------------------------
+ Author: Niles Ritter
+
+
+In the past, users of the "libtiff" package had to modify the
+source code of the library if they required additional private tags
+or codes not recognized by libtiff. Thus, whenever
+a new revision of libtiff came out the client would have to
+perform modifications to six or seven different files to re-install
+their tags.
+
+The latest versions of libtiff now provide client software new routines,
+giving them the opportunity to install private extensions at runtime,
+rather than compile-time. This means that the client may encapsulate
+all of their private tags into a separate module, which need only
+be recompiled when new versions of libtiff are released; no manual
+editing of files is required.
+
+How it works
+------------
+
+The mechanism for overriding the tag access has been enabled with
+a single new routine, which has the following calling sequence:
+
+ TIFFExtendProc old_extender;
+
+ old_extender = TIFFSetTagExtender(tag_extender);
+
+which must be called prior to opening or creating TIFF files.
+
+This routine sets a static pointer to the user-specified function
+<tag_extender>, which in turn is called by TIFFDefaultDirectory(),
+just after the usual TIFFSetField() and TIFFGetField() methods
+are defined, and just before the compression tag is set. It also
+returns a pointer to the previously-defined value of the tag-extender,
+so that multiple clients may be installed.
+
+The TIFFExtendProc method that you define should be used to override
+the TIFF file's "vsetfield" and "vgetfield" methods, so that you
+can trap your new, private tags, and install their values into
+a private directory structure. For your convienience, a new pointer
+has also been added to the "TIFF" file structure:
+
+ tidata_t tif_clientdir; /* client TIFF directory */
+
+into which you may install whatever private directory structures you like.
+You should also override the tag-printing method from within your
+"vsetfield" method, to permit the symbolic printing of your new tags.
+
+
+Example Client Code:
+--------------------
+
+An example module has been provided as a template for installing
+your own tags into a client tag extender. The module is called
+"xtif_dir.c", and defines all of the interface routines, tag field
+access, tag printing, etc. for most purpose.
+
+To see how the client module operates, there are three "fake"
+tags currently installed. If you use the existing makefile you can
+build them with:
+
+ make all -f Makefile.gcc !or Makefile.mpw
+ maketif
+ listtif
+
+This will build two example programs called "maketif" and "listtif"
+and then run them. These programs do nothing more than create a small
+file called "newtif.tif", install the fake tags, and then list them out
+using TIFFPrintDirectory().
+
+Installing Private Tags
+-----------------------
+
+To use this module for installing your own tags, edit each of the files
+
+ xtif_dir.c
+ xtiffio.h
+ xtiffiop.h
+
+and search for the string "XXX". At these locations the comments
+will direct you how to install your own tag values, define their
+types, etc. Three examples tags are currently installed, demonstrating
+how to implement multi-valued tags, single-valued tags, and ASCII tags.
+The examples are not valid, registered tags, so you must replace them with
+your own.
+
+To test the routines, also edit the test programs "maketif.c" and
+"listtif.c" and replace the portions of the code that set the
+private tag values and list them.
+
+Once you have edited these files, you may build the client module
+with the Makefile provided, and run the test programs.
+
+To use these files in your own code, the "xtif_dir.c" module defines
+replacement routines for the standard "TIFFOpen()" "TIFFFdOpen",
+and "TIFFClose()" routines, called XTIFFOpen, XTIFFFdOpen and XTIFFClose.
+You must use these routines in order to have the extended tag handlers
+installed. Once installed, the standard TIFFGetField() and TIFFSetField
+routines may be used as before.
+
+Adding Extended Tags to "tools"
+-------------------------------
+To create an extended-tag savvy "tiffinfo" program or other utility, you may
+simply recompile and link the tools to your "libxtiff" library, adding
+
+ -DTIFFOpen=XTIFFOpen -DTIFFClose=XTIFFClose -DTIFFFdOpen=XTIFFFdOpen
+
+to the compile statement.
+
+Bugs, Comments Etc:
+------------------
+ Send all reports and suggestions to ndr@tazboy.jpl.nasa.gov
+ (Niles Ritter).
diff --git a/contrib/tags/listtif.c b/contrib/tags/listtif.c
new file mode 100644
index 00000000..2ea12cea
--- /dev/null
+++ b/contrib/tags/listtif.c
@@ -0,0 +1,32 @@
+/*
+ * listtif.c -- lists a tiff file.
+ */
+
+#include "xtiffio.h"
+#include <stdlib.h>
+
+void main(int argc,char *argv[])
+{
+ char *fname="newtif.tif";
+ int flags;
+
+ TIFF *tif=(TIFF*)0; /* TIFF-level descriptor */
+
+ if (argc>1) fname=argv[1];
+
+ tif=XTIFFOpen(fname,"r");
+ if (!tif) goto failure;
+
+ /* We want the double array listed */
+ flags = TIFFPRINT_MYMULTIDOUBLES;
+
+ TIFFPrintDirectory(tif,stdout,flags);
+ XTIFFClose(tif);
+ exit (0);
+
+failure:
+ printf("failure in listtif\n");
+ if (tif) XTIFFClose(tif);
+ exit (-1);
+}
+
diff --git a/contrib/tags/maketif.c b/contrib/tags/maketif.c
new file mode 100644
index 00000000..aad6f153
--- /dev/null
+++ b/contrib/tags/maketif.c
@@ -0,0 +1,70 @@
+/*
+ * maketif.c -- creates a little TIFF file, with
+ * the XTIFF extended tiff example tags.
+ */
+
+#include <stdlib.h>
+#include "xtiffio.h"
+
+
+void SetUpTIFFDirectory(TIFF *tif);
+void WriteImage(TIFF *tif);
+
+#define WIDTH 20
+#define HEIGHT 20
+
+void main()
+{
+ TIFF *tif=(TIFF*)0; /* TIFF-level descriptor */
+
+ tif=XTIFFOpen("newtif.tif","w");
+ if (!tif) goto failure;
+
+ SetUpTIFFDirectory(tif);
+ WriteImage(tif);
+
+ XTIFFClose(tif);
+ exit (0);
+
+failure:
+ printf("failure in maketif\n");
+ if (tif) XTIFFClose(tif);
+ exit (-1);
+}
+
+
+void SetUpTIFFDirectory(TIFF *tif)
+{
+ double mymulti[6]={0.0,1.0,2.0, 3.1415926, 5.0,1.0};
+ uint32 mysingle=3456;
+ char *ascii="This file was produced by Steven Spielberg. NOT";
+
+ TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,WIDTH);
+ TIFFSetField(tif,TIFFTAG_IMAGELENGTH,HEIGHT);
+ TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE);
+ TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_MINISBLACK);
+ TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
+ TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8);
+ TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,20);
+
+ /* Install the extended TIFF tag examples */
+ TIFFSetField(tif,TIFFTAG_EXAMPLE_MULTI,6,mymulti);
+ TIFFSetField(tif,TIFFTAG_EXAMPLE_SINGLE,mysingle);
+ TIFFSetField(tif,TIFFTAG_EXAMPLE_ASCII,ascii);
+}
+
+
+void WriteImage(TIFF *tif)
+{
+ int i;
+ char buffer[WIDTH];
+
+ memset(buffer,0,sizeof(buffer));
+ for (i=0;i<HEIGHT;i++)
+ if (!TIFFWriteScanline(tif, buffer, i, 0))
+ TIFFError("WriteImage","failure in WriteScanline\n");
+}
+
+
+
+
diff --git a/contrib/tags/xtif_dir.c b/contrib/tags/xtif_dir.c
new file mode 100644
index 00000000..c9137aac
--- /dev/null
+++ b/contrib/tags/xtif_dir.c
@@ -0,0 +1,343 @@
+/*
+ * xtif_dir.c
+ *
+ * Extended TIFF Directory Tag Support.
+ *
+ * You may use this file as a template to add your own
+ * extended tags to the library. Only the parts of the code
+ * marked with "XXX" require modification. Three example tags
+ * are shown; you should replace them with your own.
+ *
+ * Author: Niles D. Ritter
+ */
+
+#include "xtiffiop.h"
+#include <stdio.h>
+
+/* Tiff info structure.
+ *
+ * Entry format:
+ * { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM,
+ * OkToChange, PassDirCountOnSet, AsciiName }
+ *
+ * For ReadCount, WriteCount, -1 = unknown; used for mult-valued
+ * tags and ASCII.
+ */
+
+static const TIFFFieldInfo xtiffFieldInfo[] = {
+
+ /* XXX Replace these example tags with your own extended tags */
+ { TIFFTAG_EXAMPLE_MULTI, -1,-1, TIFF_DOUBLE, FIELD_EXAMPLE_MULTI,
+ TRUE, TRUE, "MyMultivaluedTag" },
+ { TIFFTAG_EXAMPLE_SINGLE, 1, 1, TIFF_LONG, FIELD_EXAMPLE_SINGLE,
+ TRUE, FALSE, "MySingleLongTag" },
+ { TIFFTAG_EXAMPLE_ASCII, -1,-1, TIFF_ASCII, FIELD_EXAMPLE_ASCII,
+ TRUE, FALSE, "MyAsciiTag" },
+};
+#define N(a) (sizeof (a) / sizeof (a[0]))
+
+
+static void
+_XTIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
+{
+ xtiff *xt = XTIFFDIR(tif);
+ XTIFFDirectory *xd = &xt->xtif_dir;
+ int i,num;
+
+ /* call the inherited method */
+ if (PARENT(xt,printdir))
+ (PARENT(xt,printdir))(tif,fd,flags);
+
+ /* XXX Add field printing here. Replace the three example
+ * tags implemented below with your own.
+ */
+
+ fprintf(fd,"--My Example Tags--\n");
+
+ /* Our first example tag may have a lot of values, so we
+ * will only print them out if the TIFFPRINT_MYMULTIDOUBLES
+ * flag is passed into the print method.
+ */
+ if (TIFFFieldSet(tif,FIELD_EXAMPLE_MULTI))
+ {
+ fprintf(fd, " My Multi-Valued Doubles:");
+ if (flags & TIFFPRINT_MYMULTIDOUBLES)
+ {
+ double *value = xd->xd_example_multi;
+
+ num = xd->xd_num_multi;
+ fprintf(fd,"(");
+ for (i=0;i<num;i++) fprintf(fd, " %lg", *value++);
+ fprintf(fd,")\n");
+ } else
+ fprintf(fd, "(present)\n");
+ }
+
+ if (TIFFFieldSet(tif,FIELD_EXAMPLE_SINGLE))
+ {
+ fprintf(fd, " My Single Long Tag: %lu\n", xd->xd_example_single);
+ }
+
+ if (TIFFFieldSet(tif,FIELD_EXAMPLE_ASCII))
+ {
+ _TIFFprintAsciiTag(fd,"My ASCII Tag",
+ xd->xd_example_ascii);
+ }
+}
+
+static int
+_XTIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
+{
+ xtiff *xt = XTIFFDIR(tif);
+ XTIFFDirectory* xd = &xt->xtif_dir;
+ int status = 1;
+ uint32 v32=0;
+ int i=0, v=0;
+ va_list ap1 = ap;
+
+ /* va_start is called by the calling routine */
+
+ switch (tag) {
+ /*
+ * XXX put your extended tags here; replace the implemented
+ * example tags with your own.
+ */
+ case TIFFTAG_EXAMPLE_MULTI:
+ /* multi-valued tags need to store the count as well */
+ xd->xd_num_multi = (uint16) va_arg(ap, int);
+ _TIFFsetDoubleArray(&xd->xd_example_multi, va_arg(ap, double*),
+ (long) xd->xd_num_multi);
+ break;
+ case TIFFTAG_EXAMPLE_SINGLE:
+ xd->xd_example_single = va_arg(ap, uint32);
+ break;
+ case TIFFTAG_EXAMPLE_ASCII:
+ _TIFFsetString(&xd->xd_example_ascii, va_arg(ap, char*));
+ break;
+ default:
+ /* call the inherited method */
+ return (PARENT(xt,vsetfield))(tif,tag,ap);
+ break;
+ }
+ if (status) {
+ /* we have to override the print method here,
+ * after the compression tags have gotten to it.
+ * This makes sense because the only time we would
+ * need the extended print method is if an extended
+ * tag is set by the reader.
+ */
+ if (!(xt->xtif_flags & XTIFFP_PRINT))
+ {
+ PARENT(xt,printdir) = TIFFMEMBER(tif,printdir);
+ TIFFMEMBER(tif,printdir) = _XTIFFPrintDirectory;
+ xt->xtif_flags |= XTIFFP_PRINT;
+ }
+ 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);
+}
+
+
+static int
+_XTIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
+{
+ xtiff *xt = XTIFFDIR(tif);
+ XTIFFDirectory* xd = &xt->xtif_dir;
+
+ switch (tag) {
+ /*
+ * XXX put your extended tags here; replace the implemented
+ * example tags with your own.
+ */
+ case TIFFTAG_EXAMPLE_MULTI:
+ *va_arg(ap, uint16*) = xd->xd_num_multi;
+ *va_arg(ap, double**) = xd->xd_example_multi;
+ break;
+ case TIFFTAG_EXAMPLE_ASCII:
+ *va_arg(ap, char**) = xd->xd_example_ascii;
+ break;
+ case TIFFTAG_EXAMPLE_SINGLE:
+ *va_arg(ap, uint32*) = xd->xd_example_single;
+ break;
+ default:
+ /* return inherited method */
+ return (PARENT(xt,vgetfield))(tif,tag,ap);
+ break;
+ }
+ return (1);
+}
+
+#define CleanupField(member) { \
+ if (xd->member) { \
+ _TIFFfree(xd->member); \
+ xd->member = 0; \
+ } \
+}
+/*
+ * Release storage associated with a directory.
+ */
+static void
+_XTIFFFreeDirectory(xtiff* xt)
+{
+ XTIFFDirectory* xd = &xt->xtif_dir;
+
+ /*
+ * XXX - Purge all Your allocated memory except
+ * for the xtiff directory itself. This includes
+ * all fields that require a _TIFFsetXXX call in
+ * _XTIFFVSetField().
+ */
+
+ CleanupField(xd_example_multi);
+ CleanupField(xd_example_ascii);
+
+}
+#undef CleanupField
+
+static void _XTIFFLocalDefaultDirectory(TIFF *tif)
+{
+ xtiff *xt = XTIFFDIR(tif);
+ XTIFFDirectory* xd = &xt->xtif_dir;
+
+ /* Install the extended Tag field info */
+ _TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
+
+ /*
+ * free up any dynamically allocated arrays
+ * before the new directory is read in.
+ */
+
+ _XTIFFFreeDirectory(xt);
+ _TIFFmemset(xt,0,sizeof(xtiff));
+
+ /* Override the tag access methods */
+
+ PARENT(xt,vsetfield) = TIFFMEMBER(tif,vsetfield);
+ TIFFMEMBER(tif,vsetfield) = _XTIFFVSetField;
+ PARENT(xt,vgetfield) = TIFFMEMBER(tif,vgetfield);
+ TIFFMEMBER(tif,vgetfield) = _XTIFFVGetField;
+
+ /*
+ * XXX Set up any default values here.
+ */
+
+ xd->xd_example_single = 234;
+}
+
+
+
+/**********************************************************************
+ * Nothing below this line should need to be changed.
+ **********************************************************************/
+
+static TIFFExtendProc _ParentExtender;
+
+/*
+ * This is the callback procedure, and is
+ * called by the DefaultDirectory method
+ * every time a new TIFF directory is opened.
+ */
+
+static void
+_XTIFFDefaultDirectory(TIFF *tif)
+{
+ xtiff *xt;
+
+ /* Allocate Directory Structure if first time, and install it */
+ if (!(tif->tif_flags & XTIFF_INITIALIZED))
+ {
+ xt = _TIFFmalloc(sizeof(xtiff));
+ if (!xt)
+ {
+ /* handle memory allocation failure here ! */
+ return;
+ }
+ _TIFFmemset(xt,0,sizeof(xtiff));
+ /*
+ * Install into TIFF structure.
+ */
+ TIFFMEMBER(tif,clientdir) = (tidata_t)xt;
+ tif->tif_flags |= XTIFF_INITIALIZED; /* dont do this again! */
+ }
+
+ /* set up our own defaults */
+ _XTIFFLocalDefaultDirectory(tif);
+
+ /* Since an XTIFF client module may have overridden
+ * the default directory method, we call it now to
+ * allow it to set up the rest of its own methods.
+ */
+
+ if (_ParentExtender)
+ (*_ParentExtender)(tif);
+
+}
+
+/*
+ * XTIFF Initializer -- sets up the callback
+ * procedure for the TIFF module.
+ */
+
+static
+void _XTIFFInitialize(void)
+{
+ static first_time=1;
+
+ if (! first_time) return; /* Been there. Done that. */
+ first_time = 0;
+
+ /* Grab the inherited method and install */
+ _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
+}
+
+
+/*
+ * Public File I/O Routines.
+ */
+TIFF*
+XTIFFOpen(const char* name, const char* mode)
+{
+ /* Set up the callback */
+ _XTIFFInitialize();
+
+ /* Open the file; the callback will set everything up
+ */
+ return TIFFOpen(name, mode);
+}
+
+TIFF*
+XTIFFFdOpen(int fd, const char* name, const char* mode)
+{
+ /* Set up the callback */
+ _XTIFFInitialize();
+
+ /* Open the file; the callback will set everything up
+ */
+ return TIFFFdOpen(fd, name, mode);
+}
+
+
+void
+XTIFFClose(TIFF *tif)
+{
+ xtiff *xt = XTIFFDIR(tif);
+
+ /* call inherited function first */
+ TIFFClose(tif);
+
+ /* Free up extended allocated memory */
+ _XTIFFFreeDirectory(xt);
+ _TIFFfree(xt);
+}
diff --git a/contrib/tags/xtiffio.h b/contrib/tags/xtiffio.h
new file mode 100644
index 00000000..2aea724d
--- /dev/null
+++ b/contrib/tags/xtiffio.h
@@ -0,0 +1,52 @@
+/*
+ * xtiffio.h -- Public interface to Extended TIFF tags
+ *
+ * This is a template for defining a client module
+ * which supports tag extensions to the standard libtiff
+ * set. Only portions of the code marked "XXX" need to
+ * be changed to support your tag set.
+ *
+ * written by: Niles D. Ritter
+ */
+
+#ifndef __xtiffio_h
+#define __xtiffio_h
+
+#include "tiffio.h"
+
+/*
+ * XXX Define your private Tag names and values here
+ */
+
+/* These tags are not valid, but are provided for example */
+#define TIFFTAG_EXAMPLE_MULTI 61234
+#define TIFFTAG_EXAMPLE_SINGLE 61235
+#define TIFFTAG_EXAMPLE_ASCII 61236
+
+/*
+ * XXX Define Printing method flags. These
+ * flags may be passed in to TIFFPrintDirectory() to
+ * indicate that those particular field values should
+ * be printed out in full, rather than just an indicator
+ * of whether they are present or not.
+ */
+#define TIFFPRINT_MYMULTIDOUBLES 0x80000000
+
+/**********************************************************************
+ * Nothing below this line should need to be changed by the user.
+ **********************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern TIFF* XTIFFOpen(const char* name, const char* mode);
+extern TIFF* XTIFFFdOpen(int fd, const char* name, const char* mode);
+extern void XTIFFClose(TIFF *tif);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __xtiffio_h */
+
diff --git a/contrib/tags/xtiffiop.h b/contrib/tags/xtiffiop.h
new file mode 100644
index 00000000..0d3f1f2c
--- /dev/null
+++ b/contrib/tags/xtiffiop.h
@@ -0,0 +1,65 @@
+/*
+ * Private Extended TIFF library interface.
+ *
+ * uses private LIBTIFF interface.
+ *
+ * The portions of this module marked "XXX" should be
+ * modified to support your tags instead.
+ *
+ * written by: Niles D. Ritter
+ *
+ */
+
+#ifndef __xtiffiop_h
+#define __xtiffiop_h
+
+#include "tiffiop.h"
+#include "xtiffio.h"
+
+/**********************************************************************
+ * User Configuration
+ **********************************************************************/
+
+/* XXX - Define number of your extended tags here */
+#define NUM_XFIELD 3
+#define XFIELD_BASE (FIELD_LAST-NUM_XFIELD)
+
+/* XXX - Define your Tag Fields here */
+#define FIELD_EXAMPLE_MULTI (XFIELD_BASE+0)
+#define FIELD_EXAMPLE_SINGLE (XFIELD_BASE+1)
+#define FIELD_EXAMPLE_ASCII (XFIELD_BASE+2)
+
+
+/* XXX - Define Private directory tag structure here */
+struct XTIFFDirectory {
+ uint16 xd_num_multi; /* dir-count for the multi tag */
+ double* xd_example_multi;
+ uint32 xd_example_single;
+ char* xd_example_ascii;
+};
+typedef struct XTIFFDirectory XTIFFDirectory;
+
+/**********************************************************************
+ * Nothing below this line should need to be changed by the user.
+ **********************************************************************/
+
+struct xtiff {
+ TIFF *xtif_tif; /* parent TIFF pointer */
+ uint32 xtif_flags;
+#define XTIFFP_PRINT 0x00000001
+ XTIFFDirectory xtif_dir; /* internal rep of current directory */
+ TIFFVSetMethod xtif_vsetfield; /* inherited tag set routine */
+ TIFFVGetMethod xtif_vgetfield; /* inherited tag get routine */
+ TIFFPrintMethod xtif_printdir; /* inherited dir print method */
+};
+typedef struct xtiff xtiff;
+
+
+#define PARENT(xt,pmember) ((xt)->xtif_ ## pmember)
+#define TIFFMEMBER(tf,pmember) ((tf)->tif_ ## pmember)
+#define XTIFFDIR(tif) ((xtiff *)TIFFMEMBER(tif,clientdir))
+
+/* Extended TIFF flags */
+#define XTIFF_INITIALIZED 0x80000000
+
+#endif /* __xtiffiop_h */
diff --git a/contrib/vms/libtiff/makevms.com b/contrib/vms/libtiff/makevms.com
new file mode 100644
index 00000000..c29b62de
--- /dev/null
+++ b/contrib/vms/libtiff/makevms.com
@@ -0,0 +1,189 @@
+$!========================================================================
+$!
+$! Name : MAKEVMS
+$!
+$! Purpose : Compile TIFF library
+$!
+$! Arguments :
+$!
+$! 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="USE_VARARGS=0,USE_PROTOTYPES=1,USE_CONST=1,"+ -
+ "BSDTYPES,MMAP_SUPPORT"
+$ 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
+$ C_COMPILE=C_COMPILE+ -
+ "/FLOAT=IEEE_FLOAT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES"
+$ ENDIF
+$!
+$ SOURCES="TIF_AUX,TIF_CCITTRLE,TIF_CLOSE,TIF_COMPRESS,"+ -
+ "TIF_DIR,TIF_DIRINFO,TIF_DIRREAD,TIF_DIRWRITE,"+ -
+ "TIF_DUMPMODE,TIF_ERROR,TIF_FAX3,TIF_FAX4,TIF_FLUSH,TIF_GETIMAGE,"+ -
+-! "TIF_JPEG,"+ -
+ "TIF_LZW,TIF_NEXT,TIF_OPEN,TIF_PACKBITS,"+ -
+ "TIF_PRINT,TIF_READ,TIF_STRIP,TIF_SWAB,TIF_THUNDER,TIF_TILE,"+ -
+ "TIF_VERSION,TIF_VMS,TIF_WARNING,TIF_WRITE"
+$ LIBFILE="TIFF"
+$ IF F$SEARCH(LIBFILE+".OLB").EQS."" THEN -
+ LIBRARY/CREATE 'LIBFILE'
+$!
+$! Create VERSION.H
+$!
+$ IF F$SEARCH("VERSION.H").EQS.""
+$ THEN
+$ OPEN/READ VERS [-]VERSION.
+$ READ VERS PRIMVERS
+$ CLOSE VERS
+$ OPEN/READ VERS [-.DIST]TIFF.ALPHA
+$ READ VERS ALPHAVERS
+$ CLOSE VERS
+$ ALPHAVERS=F$ELEMENT(2," ",ALPHAVERS)
+$ OPEN/WRITE VERS VERSION.H
+$ WRITE VERS "#define VERSION ""LIBTIFF, Version "+PRIMVERS+ALPHAVERS+ -
+ "\nCopyright (c) 1988-1995 Sam Leffler\n"+ -
+ "Copyright (c) 1991-1995 Silicon Graphics, Inc."""
+$ CLOSE VERS
+$ ENDIF
+$!
+$! Create G3STATES.H
+$!
+$ IF F$SEARCH("G3STATES.H").EQS.""
+$ THEN
+$ WRITE SYS$OUTPUT "Creating G3STATES.H"
+$ 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
+$ ELSE
+$ LINK MKG3STATES,SYS$INPUT:/OPTIONS
+SYS$SHARE:VAXCRTL/SHARE
+$ ENDIF
+$ DELETE MKG3STATES.OBJ;*
+$ ENDIF
+$ MKG3STATES:=$'THIS_DIR'MKG3STATES
+$!
+$! return (0) in mkg3states causes a
+$! %NONAME-W-NOMSG, Message number 00000000
+$! warning to be written at the end of g3states.h
+$! unless messages are suppressed
+$!
+$ SET MESSAGE/NOID/NOFAC/NOSEV/NOTEXT
+$ DEFINE/USER SYS$OUTPUT G3STATES.H
+$ MKG3STATES -C
+$ SET MESSAGE 'SAVE_MESS'
+$ 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'
+$ PURGE '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 100644
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..fbf029e2
--- /dev/null
+++ b/contrib/vms/libtiff/tiffshraxp.opt
@@ -0,0 +1,117 @@
+! VMS linker options file for linking the TIFF library into a shareable image
+!
+IDENTIFICATION="LIBTIFF 3.4-002"
+!
+! Please update the minor version number below, when adding new routines
+GSMATCH=LEQUAL,1,8
+!
+! 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
+!
+! Then take the object library
+!
+TIFF/LIBRARY
diff --git a/contrib/vms/libtiff/tiffshrvax.opt b/contrib/vms/libtiff/tiffshrvax.opt
new file mode 100644
index 00000000..5b62e134
--- /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-002"
+!
+! Please update the minor version number below, when adding new routines
+GSMATCH=LEQUAL,1,8
+!
+! Place the transfer vector at the beginning of the image
+!
+CLUSTER=TIFFVEC,,,TIFFVEC
+!
+! Then take the object library
+!
+TIFF/LIBRARY
+!
+! 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 100644
index 00000000..f22688fc
--- /dev/null
+++ b/contrib/vms/libtiff/tiffvec.mar
@@ -0,0 +1,126 @@
+ .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
+ .END
diff --git a/contrib/vms/tools/makevms.com b/contrib/vms/tools/makevms.com
new file mode 100644
index 00000000..685e0b31
--- /dev/null
+++ b/contrib/vms/tools/makevms.com
@@ -0,0 +1,134 @@
+$!========================================================================
+$!
+$! 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
+$ 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
+$!
+$ SOURCES="TIFFDUMP,TIFFINFO,TIFFCMP,TIFFCP,TIFFMEDIAN,"+ -
+ "TIFF2BW,TIFFDITHER,TIFF2PS,FAX2TIFF,PAL2RGB,"+ -
+ "GIF2TIFF,PPM2TIFF,RAS2TIFF,TIFFSPLIT,RGB2YCBCR"
+$!
+$! The other programs need GETOPT.OBJ
+$!
+$ FILE="[-.PORT]GETOPT"
+$ 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
+$ C_COMPILE/OBJECT='OBJ_FILE' 'FILE'
+$ PURGE 'OBJ_FILE'
+$ ENDIF
+$!
+$! 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',[-.PORT]GETOPT,'LIB_DIR'TIFF/OPTIONS
+$ ELSE
+$ LINK'LINK_OPTIONS' 'FILE',[-.PORT]GETOPT, -
+ '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/dist/newalpha b/dist/newalpha
new file mode 100755
index 00000000..5b1a2669
--- /dev/null
+++ b/dist/newalpha
@@ -0,0 +1,8 @@
+#! /bin/sh
+# $Header: /usr/people/sam/tiff/dist/RCS/newalpha,v 1.1 1994/12/17 18:27:58 sam Exp $
+if test -r tiff.alpha; then
+ ALPHA=`cat tiff.alpha`; rm -f tiff.alpha
+ echo "$ALPHA" | awk '{ printf "define ALPHA %03d\n", $3+1}' > tiff.alpha
+else
+ echo "define ALPHA 001" >tiff.alpha
+fi
diff --git a/dist/newversion b/dist/newversion
new file mode 100644
index 00000000..cea07c5f
--- /dev/null
+++ b/dist/newversion
@@ -0,0 +1,32 @@
+#! /bin/sh
+# $Header: /usr/people/sam/tiff/dist/RCS/newversion,v 1.1 1994/12/17 18:27:58 sam Exp $
+#
+# TIFF Software
+#
+# Copyright (c) 1994, 1995 Sam Leffler
+# Copyright (c) 1994, 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.
+#
+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..86878704
--- /dev/null
+++ b/dist/tiff.alpha
@@ -0,0 +1 @@
+define ALPHA 018
diff --git a/dist/tiff.spec b/dist/tiff.spec
new file mode 100644
index 00000000..4c4c181c
--- /dev/null
+++ b/dist/tiff.spec
@@ -0,0 +1,73 @@
+# $Header: /usr/people/sam/tiff/dist/RCS/tiff.spec,v 1.2 1995/06/28 04:59:00 sam Exp $
+#
+# TIFF Software
+#
+# Copyright (c) 1994 Sam Leffler
+# Copyright (c) 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.
+#
+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"
+ exp "tiff.sw.tools"
+ endsubsys
+ subsys dev
+ id "${TIFF_NAME} Library"
+ 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
+ endimage
+
+ image html
+ id "${TIFF_NAME} HTML Materials"
+ version "${CUR_VERS}"
+ subsys sw
+ id "${TIFF_NAME} Software Distribution"
+ exp "tiff.html.sw"
+ 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..c6a70530
--- /dev/null
+++ b/html/Makefile.in
@@ -0,0 +1,96 @@
+# $Header: /usr/people/sam/tiff/html/RCS/Makefile.in,v 1.4 1995/07/19 01:54:06 sam Exp $
+#
+# @WARNING@
+#
+# Tag Image File Format Library Manual Pages
+#
+# Copyright (c) 1991-1995 Sam Leffler
+# Copyright (c) 1991-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 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 = /bin/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 \
+ ${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/strike.jpg \
+ images/warning.gif \
+ ${NULL}
+TARGETS=
+
+all: ${TARGETS}
+
+install: all
+ ${INSTALL} -m 755 -dir -idb tiff.html.sw ${HTML} ${HTML}/images
+ for i in ${HTMLFILES} ${IMAGES}; do \
+ ${INSTALL} -idb tiff.html.sw -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..ab6c2d63
--- /dev/null
+++ b/html/bugs.html
@@ -0,0 +1,66 @@
+<HTML>
+<HEAD>
+<TITLE>
+Bugs and the TIFF Mailing List
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/cover.jpg WIDTH=110 HEIGHT=110 ALIGN=left BORDER=1 HSPACE=6>
+Bugs and the TIFF Mailing List
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<P>
+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.
+
+<P>
+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
+<UL>
+<A HREF="mailto:tiff-request@sgi.com">tiff-request@sgi.com</A>
+</UL>
+For example, to subscribe, send the line
+<UL><PRE>
+subscribe
+</PRE></UL>
+in the body of your message. The line <TT>help</TT> will return a list of
+the commands understood by the mailing list management software.
+
+<P>
+Submissions (including bug reports) should be directed to:
+<UL>
+<A HREF="mailto:tiff@sgi.com">tiff@sgi.com</A>
+</UL>
+When corresponding about this software please always specify what
+version you have and what system you are running on.
+
+<P>
+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).
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/28 23:57:28 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/build.html b/html/build.html
new file mode 100644
index 00000000..111674ca
--- /dev/null
+++ b/html/build.html
@@ -0,0 +1,901 @@
+<HTML>
+<HEAD>
+<TITLE>
+Building the TIFF Software Distribution
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/cramps.gif WIDTH=159 HEIGHT=203 ALIGN=left BORDER=1 HSPACE=6>
+Building the Software Distribution
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<UL>
+<LI><A HREF=#UNIX>Building on a UNIX system</A>.
+<LI><A HREf=#Mac>Building on a Macintosh system</A>.
+<LI><A HREF=#PC>Building on an MS-DOS or Windows system</A>.
+<LI><A HREF=#VMS>Building on a VMS system</A>.
+<LI><A HREF=#Other>Building the Software on Other Systems</A>
+</UL>
+
+<BR CLEAR=left>
+
+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.
+
+<A NAME=UNIX><HR><H2>Building on a UNIX System</H2></A>
+
+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 <TT>make</TT>
+ to build the software
+and then <TT>make install</TT> to do the installation; for example:
+
+<UL><PRE>
+hyla% <B>cd tiff-v3.4beta099</B>
+hyla% <B>./configure</B>
+ <I>...lots of messages...</I>
+hyla% <B>make</B>
+ <I>...lots of messages...</I>
+hyla# <B>make install</B>
+</PRE></UL>
+
+In general, the software is designed such that the following should
+be ``<I>make-able</I>'' in each directory:
+
+<UL><PRE>
+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 <EM>absolutely everything</EM> that can be recreated
+</PRE></UL>
+
+Note that after running "<TT>make clobber</TT>" or
+"<TT>make distclean</TT>" the <TT>configure</TT> script must
+be run again to create the Makefiles and other make-related files.
+
+<A NAME="BuildTrees"><P><HR WIDTH=65% ALIGN=right><H3>Build Trees</H3></A>
+
+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.
+
+<UL><PRE>
+hyla% <B>cd tiff-v3.4beta099</B>
+hyla% <B>ls</B>
+COPYRIGHT VERSION config.sub dist man
+Makefile.in config.guess configure html port
+README config.site contrib libtiff tools
+hyla% <B>./configure</B>
+</PRE></UL>
+
+<P>
+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.
+
+<UL><PRE>
+hyla% <B>cd tiff-v3.4beta099</B>
+hyla% <B>mkdir obj obj/mycpu</B>
+hyla% <B>cd obj/mycpu</B>
+hyla% <B>../../configure</B>
+</PRE></UL>
+
+This second scheme is useful for:
+
+<UL>
+<LI>building multiple targets from a single source tree
+<LI>building from a read-only source tree (e.g. if you receive
+ the distribution on CD-ROM)
+</UL>
+
+Beware that if you choose to use the second scheme for configuring
+the software you must not use an absolute pathname when you run configure
+(i.e. a pathname that begins with ``/'') and the make that you use
+to build the software must correctly support the VPATH facility.
+
+<P>
+<IMG SRC="images/warning.gif" ALT="NOTE: " ALIGN=left HSPACE=8>
+<B>HPUX 9.05</B>:
+ <EM>The standard make incorrectly processes VPATH; either use gmake
+ or configure builds in the source tree.</EM>
+
+<A NAME="ConfigFiles"><P><HR WIDTH=65% ALIGN=right><H3>Configuration Files</H3></A>
+
+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.
+
+<P>
+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 <B>/usr/local</B> hierarchy.
+To change this behaviour the appropriate parameters can be
+specified either:
+<UL>
+<LI>on the command line to configure,
+<LI>in a site-wide configuration file, or
+<LI>in a target-specific configuration file.
+</UL>
+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.
+
+<P>
+Site-wide configuration files are named
+<B>config.site</B> and are automatically searched for first
+in any directory specified on the command line to configure
+(using the <TT>-site</TT> option), or if that fails, in
+the directory in in which the configure script is located.
+
+<P>
+Target-specific configuration files are named <B>config.local</B>
+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.
+
+<P>
+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 <B>/usr/contrib</B>
+ area and to make use of the Adobe Font Metric files that are already
+distributed as part of the BSDI 1.1 distribution:
+
+<PRE>
+#
+# 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
+DIR_HTML="/usr/contrib/html/tiff" # directory for HTML documentation
+</PRE>
+
+<P>
+For a complete list of the possible configuration parameters, look
+at the sample <B>config.site</B> file provided in the distribution
+or check the section below.
+
+<A NAME="Packages"><P><HR WIDTH=65% ALIGN=right><H3>Configuring Optional Packages/Support</H3></A>
+
+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
+<B>config.site</B> or <B>config.local</B> file, or by using a
+<TT>-with-&lt;PACKAGE&gt;</TT> option when invoking configure;
+e.g. <TT>configure -with-AFM</TT>.
+
+<DL>
+<DT><I>DSO Support</I>
+<DD>The <TT>DSO</TT> 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
+(<TT>auto</TT>).
+If DSO support is <EM>explicitly enabled</EM> and there is no
+support for using DSOs in the expected way then DSOs are not used.
+
+<P>
+<DT><I>HTML Package</I>
+<DD>The <TT>HTML</TT> package contains this HTML documentation about TIFF.
+By default this package is not configured for installation
+since HTML documentation can be viewed directly from
+the source directory.
+You may want to configure the installation of the HTML materials
+if these documents are going to be shared by many people.
+
+<P>
+<DT><I>JPEG Support</I>
+<DD>The <TT>JPEG</TT> package enables support for the handling
+of TIFF images with JPEG-encoded data.
+Support for JPEG-encoded data requires the Independent JPEG Group (IJG)
+<TT>libjpeg</TT> distribution.
+By default JPEG support is not configured.
+
+<P>
+<DT><I>ZIP Support</I>
+<DD>The <TT>ZIP</TT> support enables support for the handling
+of TIFF images with deflate-encoded data.
+Support for deflate-encoded data requires the freely available
+<TT>zlib</TT> distribution written by Jean-loup Gailly and Mark Adler.
+By default this package is not configured.
+
+</DL>
+
+<A NAME="Sample"><P><HR WIDTH=65% ALIGN=right><H3>A Sample Configuration Session</H3></A>
+
+This section shows a sample configuration session and describes
+the work done. The session is shown indented in a <TT>fixed width
+font</TT> with user-supplied input in a <TT><B>bold font</B></TT>.
+Comments are shown in a normal or <I>italic</I> font.
+This session was collected on a 486 machine running BSDI 1.1.
+
+<UL><PRE><TT>
+wullbrandt% <B>mkdir tiff</B>
+wullbrandt% <B>cd tiff</B>
+wullbrandt% <B>ln -s /hosts/oxford/usr/people/sam/tiff src</B>
+</TT></PRE></UL>
+
+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.
+
+<UL><PRE><TT>
+wullbrandt% <B>src/configure</B>
+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!
+</TT></PRE></UL>
+
+Note that configure announces the distribution version and the
+deduced target configuration (<TT>i386-unknown-bsdi1.1</TT> here).
+
+<UL><PRE><TT>
+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.
+</TT></PRE></UL>
+
+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 <TT>CC</TT> environment variable to the appropriate
+pathname, by supplying the parameter on the command line, e.g.
+<TT>-with-CC=gcc</TT>, or by setting <TT>CC</TT> in a configuration
+file.
+
+<P>
+<IMG SRC="images/info.gif" ALIGN=left HSPACE=10>
+<EM>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 <TT>ENVOPTS</TT> parameter.</EM>
+
+<P>
+Once a compiler is selected configure does several checks to see:
+<UL>
+<LI>if the compiler accepts a -g option to enable the generation
+ of debugging symbols, and
+<LI>if the compiler includes an ANSI C preprocessor.
+</UL>
+
+<UL><PRE><TT>
+Using /usr/ucb/make to configure the software.
+</TT></PRE></UL>
+
+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
+<TT>MACHDEPLIBS</TT> parameter.
+
+<P><I>Creating port.h.</I>
+The <B>port.h</B> file is included by all the C code
+in the system. It includes definitions for functions and type
+definitions that are missing from system include files, <TT>#defines</TT>
+to enable or disable system-specific functionality, and other
+odds and ends.
+
+<UL><PRE><TT>
+Creating 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 port.h.
+</TT></PRE></UL>
+
+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 "<TT>make distclean</TT>" in the top-level directory
+of the build tree will remove the <B>port.h</B> file (along
+with all the other files generated by configure).
+
+<P><I>Selecting emulated library functions.</I>
+Certain functions used by the software 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 <B>port</B> directory
+to use instead. Building the TIFF
+software on unsupported systems may require
+adding to the code to the <B>port</B> directory.
+
+<UL><PRE><TT>
+Checking system libraries for functionality to emulate.
+Done checking system libraries.
+</TT></PRE></UL>
+
+If a routine must be emulated and configure does not automatically
+check for it, the routine name can be specified using the <TT>PORTFUNCS</TT>
+parameter. To add emulation support for a new function <TT>foo</TT>,
+create a file <B>port/foo.c</B> that contains the emulation code
+and then set <TT>PORTFUNCS=foo</TT> in a configuration file or modify
+the configure script to automatically check for the missing function.
+
+<UL><PRE><TT>
+Checking for Dynamic Shared Object (DSO) support.
+Done checking for DSO support.
+</TT></PRE></UL>
+
+If the <TT>DSO</TT> package is enabled (<TT>DSO=auto</TT> or
+<TT>DSO=yes</TT>), 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.
+
+<P><I>Selecting utility programs.</I>
+configure locates various system utility programs that are
+used during installation of the software.
+
+<UL><PRE><TT>
+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.
+</TT></PRE></UL>
+
+<P><I>Selecting default configuration parameters.</I>
+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.
+
+<UL><PRE><TT>
+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] Directory for HTML documentation: /var/httpd/htdocs/tiff
+[ 6] Manual page installation scheme: bsd-nroff-gzip-0.gz
+
+Are these ok [yes]?
+</TT></PRE></UL>
+
+
+
+At this point you can interactively modify any of the
+displayed parameters. Hitting a carriage return or typing
+<TT>yes</TT> 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 <EM>for each parameter</EM>.
+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.
+
+<P>
+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.
+
+<UL><PRE><TT>
+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.
+</TT></PRE></UL>
+
+<A NAME="Parameters"><P><HR WIDTH=65% ALIGN=right><H3>Configuration Parameters</H3></A>
+
+This section gives a brief description of the less obvious
+configuration parameters. Consult the distributed <B>config.site</B>
+for a <EM>complete list of parameters</EM>.
+The list here is sorted alphabetically.
+
+<P>
+<TABLE BORDER CELLPADDING=3>
+
+<TR>
+<TD VALIGN=top><TT>AROPTS</TT></TD>
+<TD>The options passed to ar when creating an archive.
+Note that configure will automatically check to see if ar
+supports an <TT>s</TT> to create a symbol table instead of
+using ranlib.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>DIR_BIN</TT></TD>
+<TD>The directory where client applications should be installed; by
+default this is <B>/usr/local/bin</B>.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>DIR_HTML</TT></TD>
+<TD>The directory where HTML-based
+documentation should be installed; by default this is
+<B>/var/httpd/htdocs/tiff</B> (usually appropriate for the
+NCSA HTTP server).</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>DIR_LIB</TT></TD>
+<TD>The directory to install libraries and DSO's; by default
+this is <B>/usr/local/lib</B>.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>DIR_MAN</TT></TD>
+<TD>The top-most directory of the manual area where manual
+pages should be installed.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>DSOOPTS</TT></TD>
+<TD>When DSO's are built, the options to specify to <TT>CC</TT>
+to create a DSO.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>DSOSUF</TT></TD>
+<TD>When DSO's are built, the filename suffix for a DSO.
+If this is set to <TT>"a"</TT> then statically linked archives are used.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>ENVOPTS</TT></TD>
+<TD>Options to pass to <TT>CC</TT> to force ANSI C compilation.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>FILLORDER</TT></TD>
+<TD>The order of bits in a byte on the server machine;
+either LSB2MSB or MSB2LSB.
+This is normally selected according to the target system.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>GCOPTS</TT></TD>
+<TD>Special options to pass the C compiler. If this parameter
+is set, then configure may append other options to this list.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>INSTALL</TT></TD>
+<TD>The pathname of the install program to use. Note that this program
+must emulate the command line interface used by the IRIX install program.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>LIBPORT</TT></TD>
+<TD>The 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.
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>LLDOPTS</TT>
+<TD>Extra command line options passed to <TT>CC</TT>
+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.)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>MACHDEPLIBS</TT></TD>
+<TD>Target-dependent libraries that should be used when linking
+tools.
+Note that if this parameter is specified configure will append to
+the list of libraries.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>MANSCHEME</TT></TD>
+<TD>The scheme to use when preparing and installing manual pages.
+Schemes are constructed according to:
+<UL>
+&lt;<I>organization</I>&gt;-&lt;<I>formatting</I>&gt;-&lt;<I>compression</I>&gt;[-&lt;<I>suffix</I>&gt;]
+</UL>
+where:
+&lt;<I>organization</I>&gt; is either <TT>bsd</TT>
+for BSD-style section organization (e.g. file formats in
+section 5) or <TT>sysv</TT> for System V-style
+organization (e.g. file formats in section 4).
+&lt;<I>formatting</I>&gt; is either <TT>nroff</TT> to force
+installation of formatted materials (using nroff) or
+<TT>source</TT> to get the nroff source installed.
+&lt;<I>compression</I>&gt; is either the name of a program
+to compress the manual pages (gipz, compress, pack) or
+<TT>cat</TT> for uncompressed data.
+&lt;<I>suffix</I>&gt; is either the file suffix to convert
+installed pages to (e.g. 0.gz for gzip-compressed pages under BSD)
+or <TT>strip</TT> to force the normal ".4f" suffix to be converted to ".4"
+(or ".5" if using the BSD organization). If no -&lt;suffix&gt;
+is specified then filenames are not converted when they are installed.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>PORTFUNCS</TT></TD>
+<TD>A 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.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>SETMAKE</TT></TD>
+<TD>If make does not automatically set <TT>$MAKE</TT> 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 <TT>bin</TT> is used.</TD>
+</TR>
+
+</TABLE>
+
+
+<A NAME=PC><P><HR><H2>Building the Software under MS/DOS or Windows</H2></A>
+
+<I>
+There is a Makefile for Microsoft C.
+There is OS support for MS-DOS and for Windows.
+Someone needs to fill this in....
+</I>
+
+
+<A NAME=Mac><P><HR><H2>Building the Software on a Macintosh</H2></A>
+
+The directory <B>contrib/mac-mpw</B> contains support for
+compiling the library and tools under the MPW Shell on a
+Macintosh system.
+This support was contributed by Niles Ritter
+(<A HREF=mailto:ndr@tazboy.jpl.nasa.gov>ndr@tazboy.jpl.nasa.gov</A>).
+
+<P>
+[<I>From the file <B>contrib/mac-mpw/README</B>.</I>]
+
+<P>
+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.
+
+<P>
+The <file>.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.
+
+<P>
+This translation trick is necessary to protect the files when
+they are put into unix tarfiles, which tend to mangle the
+special characters.
+
+
+
+<A NAME=VMS><P><HR><H2>Building the Software on a VMS System</H2></A>
+
+The VMS port was done by Karsten Spang
+(<A HREF="mailto:krs@kampsax.dk">krs@kampsax.dk</a>), who also
+"sort of" maintains it.
+The VMS specific files are not in the main directories. Instead they
+are placed under <TT>[.CONTRIB.VMS...]</TT> 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].
+
+<OL>
+<LI>Move the VMS specific files to their proper directories.
+<PRE>
+$ SET DEFAULT DISK:[TIFF.CONTRIB.VMS]
+$ RENAME [.LIBTIFF]*.* [-.-.LIBTIFF]
+$ RENAME [.TOOLS]*.* [-.-.TOOLS]
+</PRE>
+<LI>Compile the library.
+<PRE>
+$ SET DEFAULT DISK:[TIFF.LIBTIFF]
+$ @MAKEVMS
+</PRE>
+<LI>Compile the tools.
+<PRE>
+$ SET DEFAULT DISK:[TIFF.TOOLS]
+$ @MAKEVMS
+</PRE>
+<LI>Define the programs.
+<PRE>
+$ DEFINE TIFFSHR DISK:[TIFF.LIBTIFF]TIFFSHR
+$ TIFFCP :==$DISK:[TIFF.TOOLS]TIFFCP
+$ TIFFCMP :==$DISK:[TIFF.TOOLS]TIFFCMP
+$ TIFFINFO :==$DISK:[TIFF.TOOLS]TIFFINFO
+$ TIFFDUMP :==$DISK:[TIFF.TOOLS]TIFFDUMP
+$ TIFF2PS :==$DISK:[TIFF.TOOLS]TIFF2PS
+$ TIFFDITHER:==$DISK:[TIFF.TOOLS]TIFFDITHER
+$ TIFF2BW :==$DISK:[TIFF.TOOLS]TIFF2BW
+$ TIFFMEDIAN:==$DISK:[TIFF.TOOLS]TIFFMEDIAN
+$ TIFFSPLIT :==$DISK:[TIFF.TOOLS]TIFFSPLIT
+$ 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
+</PRE>
+</OL>
+
+You will want to add these lines to your <TT>LOGIN.COM</TT>
+file, after changing
+the name of the directory that you have used on your machine.
+
+<P>
+This release has been tested on OpenVMS/VAX 5.5-2, using VAX C 3.2.
+A pre-release was tested under OpenVMS/AXP ?.? using DEC C ?.?, it is
+believed that the 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*.
+
+<P>
+The command procedures (<TT>MAKEVMS.COM</TT>) for building the
+library and tools,
+is believed to choose the correct options for the VAX and AXP cases
+automatically.
+
+<P>
+On the AXP, IEEE floating point is used by default. If you want VAX
+floating point, remove the <TT>/FLOAT=IEEE_FLOAT</TT> qualifier, and change
+<TT>HAVE_IEEEFP=1</TT> to <TT>HAVE_IEEEFP=0</TT> in the <TT>MAKEVMS.COM</TT>
+files in both the <B>libtiff</B> and <B>tools</B> directories.
+
+
+<H3>Compiling your own program on a VMS system:</H3>
+
+When compiling a source file in which you
+<TT>"#include <tiffio.h>"</TT>, use the
+following command
+<PRE>
+ $ CC/INCLUDE=DISK:[TIFF.LIBTIFF]
+</PRE>
+This ensures that the header file is found.
+On the AXP, also add <TT>/FLOAT=IEEE_FLOAT</TT>
+(if used when building the library).
+
+
+<H3>Linking your own program to the TIFF library on a VMS system:</H3>
+
+You can link to the library in two ways: Either using the shareable
+library, or using the object library.
+The possibilities are:
+
+<OL>
+<LI>Using the shareable TIFF library.
+<PRE>
+$ LINK MY_PROGRAM,DISK:[TIFF.LIBTIFF]TIFF/OPTIONS,SYS$INPUT:/OPTIONS
+ SYS$SHARE:VAXCRTL/SHAREABLE
+</PRE>
+<LI>Using the TIFF object library.
+<PRE>
+$ LINK MY_PROGRAM,DISK:[TIFF.LIBTIFF]TIFF/LIBRARY,SYS$INPUT:/OPTIONS
+ SYS$SHARE:VAXCRTL/SHAREABLE
+</PRE>
+</OL>
+
+Method 1 uses the shortest link time and smallest <TT>.EXE</TT>
+files, but it
+requires that <TT>TIFFSHR</TT> is defined as above at link time and
+<STRONG>at run time</STRONG>.
+Using the compilation procedure above, the tools are linked in this way.
+
+<P>
+Method 2 gives somewhat longer link time and larger <TT>.EXE</TT>
+files, but does
+not require <TT>TIFFSHR</TT> 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.
+
+<P>
+On the AXP, the C runtime library is linked automatically, this
+means that
+
+<PRE>
+ SYS$INPUT:/OPTIONS
+ SYS$SHARE:VAXCRTL/SHAREABLE
+</PRE>
+
+should not be used.
+
+
+<A NAME=Other><P><HR><H2>Building the Software on Other Systems</H2></A>
+
+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 <B>libtiff</B>
+directory.
+
+<P>
+The library requires two files that are generated by <I>on-the-fly</I>.
+The file <B>tif_fax3sm.c</B> has the state tables for the
+Group 3 and Group 4 decoders.
+This file is normally generated by the <TT>mkg3states</TT> program
+on a UNIX system; for example,
+
+<UL><PRE><TT>
+cd libtiff
+cc -o mkg3states mkg3states.c
+rm -f tif_fax3sm.c
+./mkg3states -c const tif_fax3sm.c
+</TT></PRE></UL>
+
+Consult the source code for this program if you have questions.
+
+<P>
+The second file required to build the library, <B>version.h</B>,
+contains the version
+information returned by the <TT>TIFFGetVersion</TT> routine.
+This file is built on a UNIX system using commands that can be found
+in the file <B>Makefile.in</B>.
+An example copy of <B>version.h</B> is:
+
+<UL><LISTING>
+#define VERSION "LIBTIFF, Version 3.4beta015 \nCopyright (c) 1988-1995 Sam Leffler\nCopyright (c) 1991-1995 Silicon Graphics, Inc."
+</LISTING></UL>
+
+<P>
+Otherwise, when building the library on a non-UNIX system be sure to
+consult the files <B>tiffcomp.h</B> and <B>tiffconf.h</B>.
+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.
+
+<P>
+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 <A HREF=internals.html#Config>documentation</A>.
+
+<P>
+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 <B>port</B> directory is provided to emulate routines
+that may be missing on some systems.
+On UNIX systems the <TT>configure</TT> script automatically figures
+out which routines are not present on a system and enables the use
+of the equivalent emulation routines from the <B>port</B> directory.
+It may be necessary to manually do this work on a non-UNIX system.
+
+
+<A NAME=Testing><P><HR><H2>Checking out the Software</H2></A>
+
+<P>
+Assuming you have working versions of <TT>tiffgt</TT> and <TT>tiffsv</TT>,
+you can just
+use them to view any of the sample images available for testing
+(see the <A HREF=images.html>section on obtaining the test images</A>).
+Otherwise, you can do a cursory check of the library with
+the <TT>tiffcp</TT> and <TT>tiffcmp</TT> programs. For example,
+
+<UL><PRE>
+tiffcp -lzw cramps.tif x.tif
+tiffcmp cramps.tif x.tif
+</PRE></UL>
+
+<P>
+(<TT>tiffcmp</TT> should be silent if the files compare correctly).
+
+
+
+<A NAME=TOC><P><HR><H2>Table of Contents</H2></A>
+
+The following files makup the core library:
+
+<PRE>
+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/version.h version string (generated by Makefile)
+
+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_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_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-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
+</PRE>
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/07/07 02:34:32 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/contrib.html b/html/contrib.html
new file mode 100644
index 00000000..f11a7892
--- /dev/null
+++ b/html/contrib.html
@@ -0,0 +1,99 @@
+<HTML>
+<HEAD>
+<TITLE>
+Contributed TIFF Software
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/smallliz.jpg WIDTH=144 HEIGHT=108 ALIGN=left BORDER=1 HSPACE=6>
+Contributed TIFF Software
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+
+<P>
+The <B>contrib</B> directory has contributed software that
+uses the TIFF library.
+
+<P>
+<TABLE BORDER CELLPADDING=3>
+
+<TR>
+<TD VALIGN=top>
+<B>contrib/vms</B>
+</TD>
+<TD>
+scripts and files from Karsten Spang for building
+ the library and tools under VMS
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top>
+<B>contrib/dbs</B>
+</TD>
+<TD>
+a simple X-based TIFF viewer from Dan & Chris Sears
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top>
+<B>contrib/ras</B>
+</TD>
+<TD>
+two programs by Patrick Naughton for converting
+ between Sun rasterfile format and TIFF (these
+ require <TT>libpixrect.a</TT>, as opposed to the one in
+ tools that doesn't)
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top>
+<B>contrib/mac-mpw</B>
+</TD>
+<TD>
+scripts and files from Niles Ritter for building
+ the library and tools under Macintosh/MPW C.
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top>
+<B>contrib/tags</B>
+</TD>
+<TD>
+scripts and files from Niles Ritter for adding private
+ tag support at runtime, without changing libtiff.
+</TD>
+</TR>
+
+</TABLE>
+
+<P>
+Don't send me mail asking about these programs. Send questions
+and/or bug reports directly to the authors.
+
+
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/07/07 02:34:32 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/document.html b/html/document.html
new file mode 100644
index 00000000..09bacf25
--- /dev/null
+++ b/html/document.html
@@ -0,0 +1,60 @@
+<HTML>
+<HEAD>
+<TITLE>
+TIFF Documentation
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/jim.gif WIDTH=139 HEIGHT=170 ALIGN=left BORDER=1 HSPACE=6>
+TIFF Documentation
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<PRE>
+
+</PRE>
+
+<P>
+A copy of the 6.0 specification is available by public ftp at
+
+<UL>
+<A HREF="ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.Z">ftp:://ftp.sgi.com/graphics/tiff/TIFF6.ps.Z</A>
+</UL>
+
+This is a PostScript version of the final 6.0 specification compressed
+the standard UNIX compress(1) program.
+An uncompressed PostScript file is also available as TIFF6.ps in
+the same directory.
+Adobe (nee Aldus) also provides the 6.0 spec online in
+Acrobat format (PDF); this can be found at
+
+<UL>
+<A HREF="ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PDFfiles/TIFF6.pdf">ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PDFfiles/TIFF6.pdf</A>
+</UL>
+
+TIFF Technical Notes can be retrieved from
+
+<UL>
+<A HREF=ftp://ftp.sgi.com/graphics/tiff>ftp://ftp.sgi.com/graphics/tiff</A>
+</UL>
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/29 00:15:58 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/images.html b/html/images.html
new file mode 100644
index 00000000..40682299
--- /dev/null
+++ b/html/images.html
@@ -0,0 +1,48 @@
+<HTML>
+<HEAD>
+<TITLE>
+TIFF Test Images
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/bali.jpg WIDTH=158 HEIGHT=107 ALIGN=left BORDER=1 HSPACE=6>
+TIFF Test Images
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<P>
+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
+<A HREF="ftp://ftp.sgi.com/graphics/tiff/v3.0pics.tar.Z">ftp://ftp.sgi.com/graphics/tiff/v3.0pics.tar.Z</A>.
+
+<P>
+There are two other good sources for TIFF test images:
+the contributed software <B>contrib/dbs</B> includes several
+programs that generate test images suitable for debugging, and
+the <TT>tiffcp</TT> program can be used to generate a variety
+of images with different storage characteristics.
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/28 23:57:28 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/images/back.gif b/html/images/back.gif
new file mode 100644
index 00000000..11d0c35f
--- /dev/null
+++ b/html/images/back.gif
Binary files differ
diff --git a/html/images/bali.jpg b/html/images/bali.jpg
new file mode 100644
index 00000000..1f5c146d
--- /dev/null
+++ b/html/images/bali.jpg
Binary files differ
diff --git a/html/images/cat.gif b/html/images/cat.gif
new file mode 100644
index 00000000..5bd3fac1
--- /dev/null
+++ b/html/images/cat.gif
Binary files differ
diff --git a/html/images/cover.jpg b/html/images/cover.jpg
new file mode 100644
index 00000000..8698cfb0
--- /dev/null
+++ b/html/images/cover.jpg
Binary files differ
diff --git a/html/images/cramps.gif b/html/images/cramps.gif
new file mode 100644
index 00000000..9153f9ae
--- /dev/null
+++ b/html/images/cramps.gif
Binary files differ
diff --git a/html/images/dave.gif b/html/images/dave.gif
new file mode 100644
index 00000000..c36d4477
--- /dev/null
+++ b/html/images/dave.gif
Binary files differ
diff --git a/html/images/info.gif b/html/images/info.gif
new file mode 100644
index 00000000..783d6315
--- /dev/null
+++ b/html/images/info.gif
Binary files differ
diff --git a/html/images/jello.jpg b/html/images/jello.jpg
new file mode 100644
index 00000000..df99e663
--- /dev/null
+++ b/html/images/jello.jpg
Binary files differ
diff --git a/html/images/jim.gif b/html/images/jim.gif
new file mode 100644
index 00000000..9a18a031
--- /dev/null
+++ b/html/images/jim.gif
Binary files differ
diff --git a/html/images/note.gif b/html/images/note.gif
new file mode 100644
index 00000000..7177d68a
--- /dev/null
+++ b/html/images/note.gif
Binary files differ
diff --git a/html/images/oxford.gif b/html/images/oxford.gif
new file mode 100644
index 00000000..dd4b86e1
--- /dev/null
+++ b/html/images/oxford.gif
Binary files differ
diff --git a/html/images/quad.jpg b/html/images/quad.jpg
new file mode 100644
index 00000000..4b7df170
--- /dev/null
+++ b/html/images/quad.jpg
Binary files differ
diff --git a/html/images/ring.gif b/html/images/ring.gif
new file mode 100644
index 00000000..2a614f49
--- /dev/null
+++ b/html/images/ring.gif
Binary files differ
diff --git a/html/images/smallliz.jpg b/html/images/smallliz.jpg
new file mode 100644
index 00000000..8eb827f8
--- /dev/null
+++ b/html/images/smallliz.jpg
Binary files differ
diff --git a/html/images/strike.gif b/html/images/strike.gif
new file mode 100644
index 00000000..0709d198
--- /dev/null
+++ b/html/images/strike.gif
Binary files differ
diff --git a/html/images/warning.gif b/html/images/warning.gif
new file mode 100644
index 00000000..f51eb4b1
--- /dev/null
+++ b/html/images/warning.gif
Binary files differ
diff --git a/html/index.html b/html/index.html
new file mode 100644
index 00000000..dc481524
--- /dev/null
+++ b/html/index.html
@@ -0,0 +1,88 @@
+<HTML>
+<HEAD>
+<TITLE>
+TIFF Software
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/jello.jpg WIDTH=256 HEIGHT=192 ALIGN=left BORDER=1 HSPACE=6>
+TIFF Software
+<HR SIZE=4 WIDTH=55% ALIGN=left>
+</H1>
+
+<B>Latest Release</B>: <I>None</I><BR>
+<B>Latest Software</B>: <A HREF="v3.4beta018.html">v3.4beta018</A><BR>
+<B>Master FTP Site</B>: <A HREF="ftp://ftp.sgi.com/graphics/tiff">ftp.sgi.com (192.48.153.1), directory graphics/tiff</A><BR>
+<B>Home Page</B>: <A HREF="http://www-mipl.jpl.nasa.gov/~ndr/tiff/">
+ http://www-mipl.jpl.nasa.gov/~ndr/tiff/</A> <BR>
+<B>FAQ Page</B>: <I>forthcoming</I><BR>
+
+
+<BR CLEAR=left>
+<PRE>
+
+</PRE>
+
+<H5>
+<IMG SRC=images/note.gif WIDTH=32 HEIGHT=32 ALIGN=left HSPACE=6>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<P>
+This software provides support for the <I>Tag Image File Format</I> (TIFF),
+a widely used format for storing image data. The latest version of
+the TIFF specification is <A HREF=document.html>available on-line</A>
+in several different formats,
+as are a number of <A HREF=ftp://ftp.sgi.com/graphics/tiff>TIFF Technical Notes (TTN's)</A>.
+
+<P>
+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.
+
+<P>
+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.
+
+
+<P>
+The following sections are included in this documentation:
+
+<UL>
+<LI><A HREF="support.html">TIFF 6.0 specification coverage</A>
+<LI><A HREF="libtiff.html">Using the TIFF Library</A>
+<LI><A HREF="internals.html">Modifying the TIFF Library</A>
+<LI><A HREF="tools.html">TIFF tools overview</A>
+<LI><A HREF="contrib.html">Contributed software</A>
+<LI><A HREF="document.html">TIFF documentation</A>
+<LI><A HREF="build.html">Building the software distribution</A>
+<LI><A HREF="bugs.html">Bugs and the TIFF mailing list</A>
+<LI><A HREF="images.html">Test images</A>
+<LI><A HREF="misc.html">Acknowledgements and copyright issues</A>
+</UL>
+
+A PostScript version of this documentation is available on-line at
+the master FTP site listed above.
+
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/07/19 01:54:06 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/internals.html b/html/internals.html
new file mode 100644
index 00000000..8a9368c2
--- /dev/null
+++ b/html/internals.html
@@ -0,0 +1,627 @@
+<HTML>
+<HEAD>
+<TITLE>
+Modifying The TIFF Library
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/dave.gif WIDTH=107 HEIGHT=148 BORDER=2 ALIGN=left HSPACE=6>
+Modifying The TIFF Library
+</H1>
+
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<PRE>
+
+</PRE>
+
+<P>
+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:
+
+<UL>
+<LI><A HREF=#Config>Library Configuration</A>
+<LI><A HREF=#Portability>General Portability Comments</A>
+<LI><A HREF="#Types">Types and Portability</A>
+<LI><A HREF=#AddingTags>Adding New Tags</A>
+<LI><A HREF=#AddingCODECS>Adding New Builtin Codecs</A>
+<LI><A HREF=#AddingCODECTags>Adding New Codec-private Tags</A>
+<LI><A HREF=#Other>Other Comments</A>
+</UL>
+
+
+<A NAME="Config"><P><HR WIDTH=65% ALIGN=right><H3>Library Configuration</H3></A>
+
+Information on compiling the library is given
+<A HREF=build.html>elsewhere in this documentation</A>.
+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 <TT>port.h</TT>
+(as generated by the <TT>configure</TT> script for UNIX systems)
+or <B>tiffconf.h</B>.
+
+<P>
+Configuration defines are split into three areas:
+<UL>
+<LI>those that control which compression schemes are
+ configured as part of the builtin codecs,
+<LI>those that control support for groups of tags that
+ are considered optional, and
+<LI>those that control operating system or machine-specific support.
+</UL>
+
+<P>
+If the define <TT>COMPRESSION_SUPPORT</TT> is <STRONG>not defined</STRONG>
+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),
+and a 2-bit encoding scheme used by NeXT (compression 32766).
+To override this behaviour define <TT>COMPRESSION_SUPPORT</TT>
+and then one or more additional defines to enable configuration of
+the appropriate codecs (see the table below); e.g.
+
+<UL><PRE>
+#define COMPRESSION_SUPPORT
+#define CCITT_SUPPORT
+#define PACKBITS_SUPPORT
+</PRE></UL>
+
+Several other compression schemes are configured separately from
+the default set because they depend on ancillary software
+packages that are not distributed with <TT>libtiff</TT>.
+
+<P>
+Support for JPEG compression is controlled by <TT>JPEG_SUPPORT</TT>.
+The JPEG codec that comes with <TT>libtiff</TT> 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
+<A HREF=ftp://ftp.uu.net/graphics/jpeg>ftp.uu.net:/graphics/jpeg/</A>.
+
+
+<P>
+<IMG SRC="images/info.gif" ALT="NOTE: " ALIGN=left HSPACE=8>
+<EM>Enabling JPEG support automatically enables support for
+the TIFF 6.0 colorimetry and YCbCr-related tags.</EM>
+
+<P>
+Experimental support for the deflate algorithm is controlled by
+<TT>DEFLATE_SUPPORT</TT>.
+The deflate codec that comes with <TT>libtiff</TT> is designed
+for use with version 0.92 or later of the freely available
+<TT>libgz</TT> library written by Jean-loup Gailly and Mark Adler.
+The data format used by this library is described
+in the files
+<A HREF=ftp://ftp.uu.net/pub/archiving/zip/doc/zlib-3.1.doc>zlib-3.1.doc</A>,
+and
+<A HREF=ftp://ftp.uu.net/pub/archiving/zip/doc/deflate-1.1.doc>deflate-1.1.doc</A>,
+available in the directory
+<A HREF=ftp://ftp.uu.net/pub/archiving/zip/doc>ftp.uu.net:/pub/archiving/zip/doc</A>.</EM>
+The library can be retried from the directory
+<A HREF=ftp://ftp.uu.net/graphics/jpeg>ftp.uu.net:/graphics/jpeg/</A>.
+
+<P>
+<IMG SRC="images/warning.gif" ALT="NOTE: " ALIGN=left HSPACE=8 VSPACE=6>
+<EM>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.</EM>
+
+
+<P>
+By default <B>tiffconf.h</B> defines
+<TT>COLORIMETRY_SUPPORT</TT>,
+<TT>YCBCR_SUPPORT</TT>,
+and
+<TT>CMYK_SUPPORT</TT>.
+
+<P>
+<TABLE BORDER CELLPADDING=3>
+
+<TR><TH ALIGN=left>Define</TH><TH ALIGN=left>Description</TH></TR>
+
+<TR>
+<TD VALIGN=top><TT>CCITT_SUPPORT</TT></TD>
+<TD>CCITT Group 3 and 4 algorithms (compression codes 2, 3, 4,
+ and 32771)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>PACKBITS_SUPPORT</TT></TD>
+<TD>Macintosh PackBits algorithm (compression 32773)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>LZW_SUPPORT</TT></TD>
+<TD>Lempel-Ziv & Welch (LZW) algorithm (compression 5)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>THUNDER_SUPPORT</TT></TD>
+<TD>4-bit
+run-length encoding scheme from ThunderScan (compression 32809)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>NEXT_SUPPORT</TT></TD>
+<TD>2-bit encoding scheme used by NeXT (compression 32766)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>OJPEG_SUPPORT</TT></TD>
+<TD>obsolete JPEG scheme defined in the 6.0 spec (compression 6)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>JPEG_SUPPORT</TT></TD>
+<TD>current JPEG scheme defined in TTN2 (compression 7)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>ZIP_SUPPORT</TT></TD>
+<TD>experimental Deflate scheme (compression 32946)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>COLORIMETRY_SUPPORT</TT></TD>
+<TD>support for the TIFF 6.0 colorimetry tags</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>YCBCR_SUPPORT</TT></TD>
+<TD>support for the TIFF 6.0 YCbCr-related tags</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>CMYK_SUPPORT</TT></TD>
+<TD>support for the TIFF 6.0 CMYK-related tags</TD>
+</TR>
+
+</TABLE>
+
+
+<A NAME="Portability"><P><HR WIDTH=65% ALIGN=right><H3>General Portability Comments</H3></A>
+
+This software is developed on Silicon Graphics UNIX
+systems (big-endian, MIPS CPU, 32-bit ints,
+IEEE floating point).
+The <TT>configure</TT> 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.
+
+<P>
+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.
+
+<P>
+The software is written to assume an ANSI C compilation environment.
+If your compiler does not support ANSI function prototypes, <TT>const</TT>,
+and <TT>&lt;stdarg.h&gt;</TT> then you will have to make modifications to the
+software. In the past I have tried to support compilers without <TT>const</TT>
+and systems without <TT>&lt;stdarg.h&gt;</TT>, but I am
+<EM>no longer interested in these
+antiquated environments</EM>. With the general availability of
+the freely available GCC compiler, I
+see no reason to incorporate modifications to the software for these
+purposes.
+
+<P>
+An effort has been made to isolate as many of the
+operating system-dependencies
+as possible in two files: <B>tiffcomp.h</B> and
+<B>libtiff/tif_&lt;os&gt;.c</B>. The latter file contains
+operating system-specific routines to do I/O and I/O-related operations.
+The UNIX (<B>tif_unix.c</B>),
+Macintosh (<B>tif_apple.c</B>),
+and VMS (<B>tif_vms.c</B>)
+code has had the most use;
+the MS/DOS support (<TT>tif_msdos.c</TT>) assumes
+some level of UNIX system call emulation (i.e.
+<TT>open</TT>,
+<TT>read</TT>,
+<TT>write</TT>,
+<TT>fstat</TT>,
+<TT>malloc</TT>,
+<TT>free</TT>).
+
+<P>
+Native CPU byte order is determined on the fly by
+the library and does not need to be specified.
+The <TT>HOST_FILLORDER</TT> and <TT>HOST_BIGENDIAN</TT>
+definitions are not currently used, but may be employed by
+codecs for optimization purposes.
+
+<P>
+The following defines control general portability:
+
+<P>
+<TABLE BORDER CELLPADDING=3 WIDTH=100%>
+
+<TR>
+<TD VALIGN=top><TT>BSDTYPES</TT></TD>
+<TD>Define this if your system does NOT define the
+ usual BSD typedefs: <TT>u_char</TT>,
+ <TT>u_short</TT>, <TT>u_int</TT>, <TT>u_long</TT>.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>HAVE_IEEEFP</TT></TD>
+<TD>Define 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.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>HAVE_MMAP</TT></TD>
+<TD>Define this if there is support for memory mapping files.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>HOST_FILLORDER</TT></TD>
+<TD>Define the native CPU bit order: one of <TT>FILLORDER_MSB2LSB</TT>
+ or <TT>FILLORDER_LSB2MSB</TT></TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><TT>HOST_BIGENDIAN</TT></TD>
+<TD>Define 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</TD>
+</TR>
+</TABLE>
+
+<P>
+On UNIX systems <TT>HAVE_MMAP</TT> is defined through the running of
+the <TT>configure</TT> script; otherwise support for memory-mapped
+files is disabled.
+Note that <B>tiffcomp.h</B> defines <TT>HAVE_IEEEFP</TT> to be
+1 (<TT>BSDTYPES</TT> is not defined).
+
+
+<A NAME="Types"><P><HR WIDTH=65% ALIGN=right><H3>Types and Portability</H3></A>
+
+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:
+
+
+<P>
+<TABLE BORDER CELLPADDING=3 WIDTH=100%>
+
+<TR>
+<TD>uint16</TD>
+<TD>16-bit unsigned integer</TD>
+<TD>tiff.h</TD>
+</TR>
+
+<TR>
+<TD>int16</TD>
+<TD>16-bit signed integer</TD>
+<TD>tiff.h</TD>
+</TR>
+
+<TR>
+<TD>uint32</TD>
+<TD>32-bit unsigned integer</TD>
+<TD>tiff.h</TD>
+</TR>
+
+<TR>
+<TD>int32</TD>
+<TD>32-bit signed integer</TD>
+<TD>tiff.h</TD>
+</TR>
+
+<TR>
+<TD>dblparam_t</TD>
+<TD>promoted type for floats</TD>
+<TD>tiffcomp.h</TD>
+</TR>
+
+</TABLE>
+
+<P>
+(to clarify <TT>dblparam_t</TT>, it is the type that float parameters are
+promoted to when passed by value in a function call.)
+
+<P>
+The following typedefs are used throughout the library and interfaces
+to refer to certain objects whose size is dependent on the TIFF image
+structure:
+
+
+<P>
+<TABLE BORDER CELLPADDING=3 WIDTH=100%>
+
+<TR>
+<TD WIDTH=25%>typedef unsigned int ttag_t;</TD> <TD>directory tag</TD>
+</TR>
+
+<TR>
+<TD>typedef uint16 tdir_t;</TD> <TD>directory index</TD>
+</TR>
+
+<TR>
+<TD>typedef uint16 tsample_t;</TD> <TD>sample number</TD>
+</TR>
+
+<TR>
+<TD>typedef uint32 tstrip_t;</TD> <TD>strip number</TD>
+</TR>
+
+<TR>
+<TD>typedef uint32 ttile_t;</TD> <TD>tile number</TD>
+</TR>
+
+<TR>
+<TD>typedef int32 tsize_t;</TD> <TD>i/o size in bytes</TD>
+</TR>
+
+<TR>
+<TD>typedef void* tdata_t;</TD> <TD>image data ref</TD>
+</TR>
+
+<TR>
+<TD>typedef void* thandle_t;</TD> <TD>client data handle</TD>
+</TR>
+
+<TR>
+<TD>typedef int32 toff_t;</TD> <TD>file offset (should be off_t)</TD>
+</TR>
+
+<TR>
+<TD>typedef unsigned char* tidata_t;</TD> <TD>internal image data</TD>
+</TR>
+
+</TABLE>
+
+<P>
+Note that <TT>tstrip_t</TT>, <TT>ttile_t</TT>, and <TT>tsize_t</TT>
+are constrained to be
+no more than 32-bit quantities by 32-bit fields they are stored
+in in the TIFF image. Likewise <TT>tsample_t</TT> is limited by the 16-bit
+field used to store the <TT>SamplesPerPixel</TT> tag. <TT>tdir_t</TT>
+constrains
+the maximum number of IFDs that may appear in an image and may
+be an arbitrary size (without penalty). <TT>ttag_t</TT> must be either
+<TT>int</TT>, <TT>unsigned int</TT>, pointer, or <TT>double</TT>
+because the library uses a varargs
+interface and ANSI C restricts the type of the parameter before an
+ellipsis to be a promoted type. <TT>toff_t</TT> is defined as
+<TT>int32</TT> 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 <TT>tidata_t</TT> 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.
+
+
+<P><HR WIDTH=65% ALIGN=right><H3>General Comments</H3></A>
+
+The library is designed to hide as much of the details of TIFF 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).
+
+<A NAME=AddingTags><P><HR WIDTH=65% ALIGN=right><H3>Adding New Tags</H3></A>
+
+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''.
+
+<OL>
+<LI>Define the tag in <B>tiff.h</B>.
+<LI>Add a field to the directory structure in <B>tif_dir.h</B>
+ and define a <TT>FIELD_*</TT> bit.
+<LI>Add an entry in the <TT>TIFFFieldInfo</TT> array defined at the top of
+ <B>tif_dirinfo.c</B>.
+ 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. <TT>LONG</TT> before <TT>SHORT</TT>).
+<LI>Add entries in <TT>_TIFFVSetField()</TT> and <TT>_TIFFVGetField()</TT>
+ for the new tag.
+<LI>(<I>optional</I>) If the value associated with the tag is not a scalar value
+ (e.g. the array for <TT>TransferFunction</TT>) and requires
+ special processing,
+ then add the appropriate code to <TT>TIFFReadDirectory()</TT> and
+ <TT>TIFFWriteDirectory()</TT>. You're best off finding a similar tag and
+ cribbing code.
+<LI>Add support to <TT>TIFFPrintDirectory()</TT> in <B>tif_print.c</B>
+ to print the tag's value.
+</OL>
+
+<P>
+If you want to maintain portability, beware of making assumptions
+about data types. Use the typedefs (<TT>uint16</TT>, etc. when dealing with
+data on disk and <TT>t*_t</TT> when stuff is in memory) and be careful about
+passing items through printf or similar vararg interfaces.
+
+<A NAME=AddingCODECS><P><HR WIDTH=65% ALIGN=right><H3>Adding New Builtin Codecs</H3></A>
+
+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 <A HREF=#AddingTags>Adding New Tags</A>, above),
+or do the following to add support directly to the core library:
+
+<OL>
+<LI>Define the tag value in <B>tiff.h</B>.
+<LI>Edit the file <B>tif_codec.c</B> to add an entry to the
+ _TIFFBuiltinCODECS array (see how other algorithms are handled).
+<LI>Add the appropriate function prototype declaration to
+ <B>tiffiop.h</B> (close to the bottom).
+<LI>Create a file with the compression scheme code, by convention files
+ are named <B>tif_*.c</B> (except perhaps on some systems where the
+ tif_ prefix pushes some filenames over 14 chars.
+<LI>Edit <B>Makefile.in</B> (and any other Makefiles)
+ to include the new source file.
+</OL>
+
+<P>
+A codec, say <TT>foo</TT>, can have many different entry points:
+
+<PRE>
+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 &gt;0 and &lt;rows/strip */
+fooCleanup(tif) /* called when compression scheme is replaced by user */
+</PRE>
+
+<P>
+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 <TT>PlanarConfig</TT>=2
+(separate planes). This is important for algorithms such as JPEG.
+If <TT>PlanarConfig</TT>=1 (interleaved), then sample will always be 0.
+
+
+<A NAME=AddingCODECTags><P><HR WIDTH=65% ALIGN=right><H3>Adding New Codec-private Tags</H3></A>
+
+To add tags that are meaningful <EM>only when a particular compression
+algorithm is used</EM> follow these steps:
+
+<OL>
+<LI>Define the tag in <B>tiff.h</B>.
+<LI>Allocate storage for the tag values in the private state block of
+ the codec.
+<LI>Insure the state block is created when the codec is initialized.
+<LI>At <TT>TIFFInitfoo</TT> time override the method pointers in the
+ TIFF structure
+ for getting, setting and printing tag values. For example,
+<PRE>
+ 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 */
+</PRE>
+ (Actually you may decide not to override the
+ <TT>tif_printdir</TT> method, but rather just specify it).
+<LI>Create a private <TT>TIFFFieldInfo</TT> array for your tags and
+ merge them into the core tags at initialization time using
+ <TT>_TIFFMergeFieldInfo</TT>; e.g.
+<PRE>
+ _TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo));
+</PRE>
+ (where <TT>N</TT> is a macro used liberaly throughout the distributed code).
+<LI>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
+ <TT>FIELD_*</TT> 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 <TT>TIFFTAG_FAXMODE</TT> in <B>tif_fax3.c</B>
+ for an example of this).
+<LI>Fill in the print routine, if appropriate.
+</OL>
+
+Note that space has been allocated in the <TT>FIELD_*</TT> bit space for
+codec-private tags. Define your bits as <TT>FIELD_CODEC+&lt;offset&gt;</TT> to
+keep them away from the core tags. If you need more tags than there
+is room for, just increase <TT>FIELD_SETLONGS</TT> at the top of
+<B>tiffiop.h</B>.
+
+
+<A NAME=Other><P><HR WIDTH=65% ALIGN=right><H3>Other Comments</H3></A>
+
+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 <TT>TIFFFlushData1()</TT> 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
+<TT>tif_postdecode</TT>
+routine (set it to <TT>TIFFNoPostDecode</TT>) and doing the required work
+internally. For an example of doing this look at the horizontal
+differencing code in the routines in <B>tif_predict.c</TT>.
+
+<P>
+The variables <TT>tif_rawcc</TT>, <TT>tif_rawdata</TT>, and
+<TT>tif_rawcp</TT> in a <TT>TIFF</TT> structure
+are associated with the raw data buffer. <TT>tif_rawcc</TT> must be non-zero
+for the library to automatically flush data. The variable
+<TT>tif_scanlinesize</TT> is the size a user's scanline buffer should be. The
+variable <TT>tif_tilesize</TT> 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 <TT>cc</TT> parameter to the
+<TT>tif_decode*</TT> and <TT>tif_encode*</TT>
+routines should be used in terminating
+decompression/compression. This ensures these routines can be used,
+for example, to decode/encode entire strips of data.
+
+<P>
+In general, if you have a new compression algorithm to add, work from
+the code for an existing routine. In particular,
+<B>libitff/tif_dumpmode.c</B>
+has the trivial code for the "nil" compression scheme,
+<B>tif_packbits.c</B> is a
+simple byte-oriented scheme that has to watch out for buffer
+boundaries, and <B>tif_lzw.c</B> 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.
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/07/07 02:34:32 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/intro.html b/html/intro.html
new file mode 100644
index 00000000..60736bed
--- /dev/null
+++ b/html/intro.html
@@ -0,0 +1,80 @@
+<HTML>
+<HEAD>
+<TITLE>
+Introduction to the TIFF Documentation
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/strike.gif WIDTH=128 HEIGHT=100 ALIGN=left HSPACE=6>
+Introduction to the TIFF Documentation
+</H1>
+
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<P>
+The following definitions are used throughout this documentation.
+They are consistent with the terminology used in the TIFF 6.0 specification.
+
+<DL>
+<DT><I>Sample</I>
+<DD>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
+<DT><I>Pixel</I>
+<DD>A collection of one or more samples that go together.
+<DT><I>Row</I>
+<DD>An Nx1 rectangular collection of pixels.
+<DT><I>Tile</I>
+<DD>An NxM rectangular organization of data (or pixels).
+<DT><I>Strip</I>
+<DD>A tile whose width is the full image width.
+<DT><I>Compression</I>
+<DD>A scheme by which pixel or sample data are stored in
+ an encoded form, specifically with the intent of reducing the
+ storage cost.
+<DT><I>Codec</I>
+<DD>Software that implements the decoding and encoding algorithms
+ of a compression scheme.
+</UL>
+
+<P>
+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.
+
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/28 23:57:28 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/libtiff.html b/html/libtiff.html
new file mode 100644
index 00000000..5dd77ce5
--- /dev/null
+++ b/html/libtiff.html
@@ -0,0 +1,742 @@
+<HTML>
+<HEAD>
+<TITLE>
+Using The TIFF Library
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/cat.gif WIDTH=113 HEIGHT=146 BORDER=2 ALIGN=left HSPACE=6>
+Using The TIFF Library
+</H1>
+
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<PRE>
+
+</PRE>
+
+<P>
+<TT>libtiff</TT> 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.
+
+<P>
+<TT>libtiff</TT>
+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.
+
+<P>
+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 <A HREF="http://www-mipl.jpl.nasa.gov/~ndr/tiff/man/>
+UNIX manual pages</A> that accompany this software.
+
+<P>
+The following sections are found in this chapter:
+
+<UL>
+<LI><A HREF=#Version>How to tell which version you have</A>
+<LI><A HREF=#Typedefs>Library Datatypes</A>
+<LI><A HREF=#Mman>Memory Management</A>
+<LI><A HREF=#Errors>Error Handling</A>
+<LI><A HREF=#FIO>Basic File Handling</A>
+<LI><A HREF=#Dirs>TIFF Directories</A>
+<LI><A HREF=#Tags>TIFF Tags</A>
+<LI><A HREF=#Compression>TIFF Compression Schemes</A>
+<LI><A HREF=#ByteOrder>Byte Order</A>
+<LI><A HREF=#DataPlacement>Data Placement</A>
+<LI><A HREF=#TIFFRGBAImage>TIFFRGBAImage Support</A>
+<LI><A HREF=#Scanlines>Scanline-based Image I/O</A>
+<LI><A HREF=#Strips>Strip-oriented Image I/O</A>
+<LI><A HREF=#Tiles>Tile-oriented Image I/O</A>
+<LI><A HREF=#Other>Other Stuff</A>
+</UL>
+
+
+<A NAME="Version"><P><HR WIDTH=65% ALIGN=right><H3>How to tell which version you have</H3></A>
+
+The software version can be found by looking at the file named
+<TT>VERSION</TT>
+that is located at the top of the source tree; the precise alpha number
+is given in the file <TT>dist/tiff.alpha</TT>.
+If you have need to refer to this
+specific software, you should identify it as:
+
+<PRE>
+ TIFF &lt;<I>version</I>&gt; &lt;<I>alpha</I>&gt;
+</PRE>
+
+where &lt;<I>version</I>&gt; is whatever you get from
+<KBD>"cat VERSION"</KBD> and &lt;<I>alpha</I>&gt; is
+what you get from <KBD>"cat dist/tiff.alpha"</KBD>.
+
+<P>
+Within an application that uses <TT>libtiff</TT> the <TT>TIFFGetVersion</TT>
+routine will return a pointer to a string that contains software version
+information.
+
+<A NAME="Typedefs"><P><HR WIDTH=65% ALIGN=right><H3>Library Datatypes</H3></A>
+
+<TT>libtiff</TT> defines a portable programming interface through the
+use of a set of C type definitions.
+These definitions, defined in in the files <B>tiff.h</B> and
+<B>tiffio.h</B>,
+isolate the <TT>libtiff</TT> API from the characteristics
+of the underlying machine.
+To insure portable code and correct operation, applications that use
+<TT>libtiff</TT> should use the typedefs and follow the function
+prototypes for the library API.
+
+<A NAME="Mman"><P><HR WIDTH=65% ALIGN=right><H3>Memory Management</H3></A>
+
+<TT>libtiff</TT> uses a machine-specific set of routines for managing
+dynamically allocated memory.
+<TT>_TIFFmalloc</TT>, <TT>_TIFFrealloc</TT>, and <TT>_TIFFfree</TT>
+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 <TT>malloc</TT>,
+<TT>realloc</TT>, and <TT>free</TT> routines in the C library.)
+
+<P>
+To deal with segmented pointer issues <TT>libtiff</TT> also provides
+<TT>_TIFFmemcpy</TT>, <TT>_TIFFmemset</TT>, and <TT>_TIFFmemmove</TT>
+routines that mimic the equivalent ANSI C routines, but that are
+intended for use with memory allocated through <TT>_TIFFmalloc</TT>
+and <TT>_TIFFrealloc</TT>.
+
+<A NAME="Errors"><P><HR WIDTH=65% ALIGN=right><H3>Error Handling</H3></A>
+
+<TT>libtiff</TT> 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 <TT>TIFFSetErrorHandler</TT>.
+Likewise warning messages are directed to a single handler routine
+that can be specified with a call to <TT>TIFFSetWarningHandler</TT>
+
+<A NAME="FIO"><P><HR WIDTH=65% ALIGN=right><H3>Basic File Handling</H3></A>
+
+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:
+
+<UL><LISTING>
+#include "tiffio.h"
+main()
+{
+ TIFF* tif = TIFFOpen("foo.tif", "r");
+ ... do stuff ...
+ TIFFClose(tif);
+}
+</LISTING></UL>
+
+The handle returned by <TT>TIFFOpen</TT> is <I>opaque</I>, 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.
+
+<P>
+To create or overwrite a TIFF image the file is also opened, but with
+a <TT>"w"</TT> argument:
+
+<UL><LISTING>
+#include "tiffio.h"
+main()
+{
+ TIFF* tif = TIFFOpen("foo.tif", "w");
+ ... do stuff ...
+ TIFFClose(tif);
+}
+</LISTING></UL>
+
+If the file already exists it is first truncated to zero length.
+
+<P>
+<IMG SRC=images/warning.gif ALIGN=left HSPACE=6>
+<EM>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.
+</EM>
+
+<P>
+<TT>libtiff</TT> buffers much information associated with writing a
+valid TIFF image. Consequently, when writing a TIFF image it is necessary
+to always call <TT>TIFFClose</TT> or <TT>TIFFFlush</TT> to flush any
+buffered information to a file. Note that if you call <TT>TIFFClose</TT>
+you do not need to call <TT>TIFFFlush</TT>.
+
+<A NAME="Dirs"><P><HR WIDTH=65% ALIGN=right><H3>TIFF Directories</H3></A>
+
+TIFF supports the storage of multiple images in a single file.
+Each image has an associated data structure termed a <I>directory</I>
+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.
+
+<P>
+<TT>libtiff</TT> 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 <TT>TIFFClose</TT> or <TT>TIFFFlush</TT> are called).
+
+<P>
+For a file open for reading the <TT>TIFFSetDirectory</TT> routine can
+be used to select an arbitrary directory; directories are referenced by
+number with the numbering starting at 0. Otherwise the
+<TT>TIFFReadDirectory</TT> and <TT>TIFFWriteDirectory</TT> 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:
+
+<UL><LISTING>
+#include "tiffio.h"
+main(int argc, char* argv[])
+{
+ TIFF* tif = TIFFOpen(argv[1], "r");
+ if (tif) {
+ int dircount = 1;
+ do {
+ dircount++;
+ } while (TIFFReadDirectory(tif));
+ printf("%d directories in %s\n", dircount, argv[1]);
+ TIFFClose(tif);
+ }
+ exit(0);
+}
+</LISTING></UL>
+
+<P>
+Finally, note that there are several routines for querying the
+directory status of an open file:
+<TT>TIFFCurrentDirectory</TT> returns the index of the current
+directory and
+<TT>TIFFLastDirectory</TT> returns an indication of whether the
+current directory is the last directory in a file.
+There is also a routine, <TT>TIFFPrintDirectory</TT>, that can
+be called to print a formatted description of the contents of
+the current directory; consult the manual page for complete details.
+
+<A NAME="Tags"><P><HR WIDTH=65% ALIGN=right><H3>TIFF Tags</H3></A>
+
+Image-related information such as the image width and height, number
+of samples, orientation, colorimetric information, etc.
+are stored in each image
+directory in <I>fields</I> or <I>tags</I>.
+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.
+
+<P>
+<TT>libtiff</TT> 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 <A HREF=../contrib/tags/README>elsewhere</A>.
+
+<P>
+<TT>libtiff</TT> provides two interfaces for getting and setting tag
+values: <TT>TIFFGetField</TT> and <TT>TIFFSetField</TT>.
+These routines use a variable argument list-style interface to pass
+parameters of different type through a single function interface.
+The <I>get interface</I> 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 <I>set interface</I> takes the tag values either by-reference or
+by-value.
+The TIFF specification defines
+<I>default values</I> for some tags.
+To get the value of a tag, or its default value if it is undefined,
+the <TT>TIFFGetFieldDefaulted</TT> interface may be used.
+
+<P>
+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.
+
+<A NAME="Compression"><P><HR WIDTH=65% ALIGN=right><H3>TIFF Compression Schemes</H3></A>
+
+<TT>libtiff</TT> includes support for a wide variety of
+data compression schemes.
+In normal operation a compression scheme is automatically used when
+the TIFF <TT>Compression</TT> tag is set, either by opening a file
+for reading, or by setting the tag when writing.
+
+<P>
+Compression schemes are implemented by software modules termed <I>codecs</I>
+that implements 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 <TT>TIFFRegisterCODEC</TT> routine.
+This interface can also be used to override the core-library
+implementation for a compression scheme.
+
+<A NAME="ByteOrder"><P><HR WIDTH=65% ALIGN=right><H3>Byte Order</H3></A>
+
+The TIFF specification says, and has always said, that
+<EM>a correct TIFF
+reader must handle images in big-endian and little-endian byte order</EM>.
+<TT>libtiff</TT> 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).
+
+
+<A NAME="DataPlacement"><P><HR WIDTH=65% ALIGN=right><H3>Data Placement</H3></A>
+
+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.
+<TT>libtiff</TT> provides no mechanism for controlling the placement
+of data in a file; image data is typically written before directory
+information.
+
+<A NAME="TIFFRGBAImage"><P><HR WIDTH=65% ALIGN=right><H3>TIFFRGBAImage Support</H3></A>
+
+<TT>libtiff</TT> 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.
+
+<P>
+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 <TT>TIFFReadRGBAImage</TT> can be used:
+
+<UL><LISTING>
+#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, raster, w, h, 0)) {
+ ...process raster data...
+ }
+ _TIFFfree(raster);
+ }
+ TIFFClose(tif);
+ }
+ exit(0);
+}
+</LISTING></UL>
+
+Note above that <TT>_TIFFmalloc</TT> is used to allocate memory for
+the raster passed to <TT>TIFFReadRGBAImage</TT>; this is important
+to insure the ``appropriate type of memory'' is passed on machines
+with segmented architectures.
+
+<P>
+Alternatively, <TT>TIFFReadRGBAImage</TT> 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:
+
+<UL><LISTING>
+#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);
+}
+</LISTING></UL>
+
+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:
+
+<UL>
+<LI>repeatedly fetch (and manipulate) an image without opening
+ and closing the file
+<LI>interpose a method for packing raster pixel data according to
+ application-specific needs (or write the data at all)
+<LI>interpose methods that handle TIFF formats that are not already
+ handled by the core library
+</UL>
+
+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.
+
+<P>
+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.
+
+<P>
+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.
+
+<P>
+The TIFF image viewer found in <B>tools/sgigt.c</B> is an example
+of an application that makes use of the <TT>TIFFRGBAImage</TT>
+support.
+
+<A NAME="Scanlines"><P><HR WIDTH=65% ALIGN=right><H3>Scanline-based Image I/O</H3></A>
+
+The simplest interface provided by <TT>libtiff</TT> 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 (<TT>RowsPerStrip</TT> is one).
+
+<P>
+Two routines are provided for scanline-based i/o:
+<TT>TIFFReadScanline</TT>
+and
+<TT>TIFFWriteScanline</TT>.
+For example, to read the contents of a file that
+is assumed to be organized in strips, the following might be used:
+
+<UL><LISTING>
+#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);
+ }
+}
+</LISTING></UL>
+
+<TT>TIFFScanlineSize</TT> returns the number of bytes in
+a decoded scanline, as returned by <TT>TIFFReadScanline</TT>.
+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:
+
+<UL><LISTING>
+#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);
+ }
+}
+</LISTING></UL>
+
+Beware however that if the following code were used instead to
+read data in the case <TT>PLANARCONFIG_SEPARATE</TT>,
+
+<UL><LISTING>
+ for (row = 0; row < imagelength; row++)
+ for (s = 0; s < nsamples; s++)
+ TIFFReadScanline(tif, buf, row, s);
+</LISTING></UL>
+
+then problems would arise if <TT>RowsPerStrip</TT> 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).
+
+<A NAME="Strips"><P><HR WIDTH=65% ALIGN=right><H3>Strip-oriented Image I/O</H3></A>
+
+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.
+
+<P>
+A simple example of reading an image by strips is:
+
+<UL><LISTING>
+#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);
+ }
+}
+</LISTING></UL>
+
+Notice how a strip size of <TT>-1</TT> is used; <TT>TIFFReadEncodedStrip</TT>
+will calculate the appropriate size in this case.
+
+<P>
+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 <TT>PLANARCONFIG_SEPARATE</TT>
+then all the strips of data holding the first sample will be
+read, followed by strips for the second sample, etc.
+
+<P>
+Finally, note that the last strip of data in an image may have fewer
+rows in it than specified by the <TT>RowsPerStrip</TT> tag. A
+reader should not assume that each decoded strip contains a full
+set of rows in it.
+
+<P>
+The following is an example of how to read raw strips of data from
+a file:
+
+<UL><LISTING>
+#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);
+ }
+}
+</LISTING></UL>
+
+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.
+
+<A NAME="Tiles"><P><HR WIDTH=65% ALIGN=right><H3>Tile-oriented Image I/O</H3></A>
+
+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.
+
+<P>
+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.
+
+<P>
+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:
+
+<UL><LISTING>
+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);
+ }
+}
+</LISTING></UL>
+
+(once again, we assume samples are packed contiguously.)
+
+<P>
+Alternatively a direct interface to the low-level data is provided
+a la strips. Tiles can be read with
+<TT>TIFFReadEncodedTile</TT> or
+<TT>TIFFReadRawTile</TT>,
+and written with
+<TT>TIFFWriteEncodedTile</TT> or
+<TT>TIFFWriteRawTile</TT>.
+For example, to read all the tiles in an image:
+
+<UL><LISTING>
+#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);
+ }
+}
+</LISTING></UL>
+
+
+
+<A NAME="Other"><P><HR WIDTH=65% ALIGN=right><H3>Other Stuff</H3></A>
+
+<P>
+<I>Some other stuff will almost certainly go here...</I>
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/07/07 02:34:32 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/misc.html b/html/misc.html
new file mode 100644
index 00000000..d9fd7c1b
--- /dev/null
+++ b/html/misc.html
@@ -0,0 +1,104 @@
+<HTML>
+<HEAD>
+<TITLE>
+Acknowledgments and Other Issues
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/ring.gif WIDTH=124 HEIGHT=124 ALIGN=left BORDER=1 HSPACE=6>
+Acknowledgments and Other Issues
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<PRE>
+
+</PRE>
+
+
+<H2>Acknowledgements</H2>
+
+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 <TT>libtiff/mkg3states.c</TT> and
+<TT>libtiff/tif_fax3.h</TT> 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:
+
+<PRE>
+ Bjorn P. Brox Dan McCoy
+ J.T. Conklin Richard Minner
+ Soren Pingel Dalsgaard Niles Ritter
+ Steve Johnson Karsten Spang
+</PRE>
+
+(my apology to anyone that was inadvertently not listed.)
+
+<H2>Warning</H2>
+
+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.
+
+
+<H2>Use and Copyright</H2>
+
+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.
+
+<P><H5><PRE>
+Copyright (c) 1988-1995 Sam Leffler
+Copyright (c) 1991-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.
+</PRE></H5>
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/28 23:57:28 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/support.html b/html/support.html
new file mode 100644
index 00000000..6480ad7f
--- /dev/null
+++ b/html/support.html
@@ -0,0 +1,671 @@
+<HTML>
+<HEAD>
+<TITLE>
+TIFF 6.0 Specification Coverage
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/strike.gif WIDTH=128 HEIGHT=100 ALIGN=left HSPACE=6>
+TIFF 6.0 Specification Coverage
+</H1>
+
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<P>
+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.
+
+<P>
+<TABLE BORDER CELLPADDING=3>
+
+<TR>
+<TD VALIGN=top>
+<I>Core requirements</I>
+</TD>
+<TD>
+Both <TT>"MM"</TT> and <TT>"II"</TT> 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 <B>not</B> supported in that related subfiles (e.g.
+a reduced resolution version of an image) are not automatically
+updated.
+<P>
+Tags handled:
+<TT>ExtraSamples</TT>,
+<TT>ImageWidth</TT>,
+<TT>ImageLength</TT>,
+<TT>NewSubfileType</TT>,
+<TT>ResolutionUnit</TT>.
+<TT>Rowsperstrip</TT>,
+<TT>StripOffsets</TT>,
+<TT>StripByteCounts</TT>,
+<TT>XResolution</TT>,
+<TT>YResolution</TT>,
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><I>Tiled Images</I></TD>
+<TD><TT>TileWidth</TT>,
+ <TT>TileLength</TT>,
+ <TT>TileOffsets</TT>,
+ <TT>TileByteCounts</TT>
+</TD>
+</TR>
+
+<TD VALIGN=top><I>Image Colorimetry Information</I></TD>
+<TD><TT>WhitePoint</TT>,
+ <TT>PrimaryChromaticities</TT>,
+ <TT>TransferFunction</TT>,
+ <TT>ReferenceBlackWhite</TT>
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><I>Class B for bilevel images</I></TD>
+<TD><TT>SamplesPerPixel</TT> = 1<BR>
+ <TT>BitsPerSample</TT> = 1<BR>
+ <TT>Compression</TT> = 1 (none), 2 (CCITT 1D), or 32773 (PackBits)<BR>
+ <TT>PhotometricInterpretation</TT> = 0 (Min-is-White), 1 (Min-is-Black)<BR>
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><I>Class G for grayscale images</I></TD>
+<TD><TT>SamplesPerPixel</TT> = 1<BR>
+ <TT>BitsPerSample</TT> = 4, 8<BR>
+ <TT>Compression</TT> = 1 (none) 5 (LZW)<BR>
+ <TT>PhotometricInterpretation</TT> = 0 (Min-is-White), 1 (Min-is-Black)<BR>
+</TD>
+
+</TR>
+<TR>
+<TD VALIGN=top><I>Class P for palette color images</I></TD>
+<TD><TT>SamplesPerPixel</TT> = 1<BR>
+ <TT>BitsPerSample</TT> = 1-8<BR>
+ <TT>Compression</TT> = 1 (none) 5 (LZW)<BR>
+ <TT>PhotometricInterpretation</TT> = 3 (Palette RGB)<BR>
+ <TT>ColorMap</TT>
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><I>Class R for RGB full color images</I></TD>
+<TD><TT>SamplesPerPixel</TT> = 3<BR>
+ <TT>BitsPerSample</TT> = <8,8,8><BR>
+ <TT>PlanarConfiguration</TT> = 1, 2<BR>
+ <TT>Compression</TT> = 1 (none) 5 (LZW)<BR>
+ <TT>PhotometricInterpretation</TT> = 2 (RGB)<BR>
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><I>Class F for facsimile</I></TD>
+<TD>(<I>Class B tags plus...</I>)<BR>
+ <TT>Compression</TT> = 3 (CCITT Group 3), 4 (CCITT Group 4)<BR>
+ <TT>FillOrder</TT> = 1 (MSB), 2 (LSB)<BR>
+ <TT>Group3Options</TT> = 1 (2d encoding), 4 (zero fill), 5 (2d+fill)<BR>
+ <TT>ImageWidth</TT> = 1728, 2048, 2482<BR>
+ <TT>NewSubFileType</TT> = 2<BR>
+ <TT>ResolutionUnit</TT> = 2 (Inch), 3 (Centimeter)<BR>
+ <TT>PageNumber</TT>,
+ <TT>XResolution</TT>,
+ <TT>YResolution</TT>,
+ <TT>Software</TT>,
+ <TT>BadFaxLines</TT>,
+ <TT>CleanFaxData</TT>,
+ <TT>ConsecutiveBadFaxLines</TT>,
+ <TT>DateTime</TT>,
+ <TT>DocumentName</TT>,
+ <TT>ImageDescription</TT>,
+ <TT>Orientation</TT>
+</TD>
+</TR>
+
+<TD VALIGN=top><I>Class S for separated images</I></TD>
+<TD><TT>SamplesPerPixel</TT> = 4<BR>
+ <TT>PlanarConfiguration</TT> = 1, 2<BR>
+ <TT>Compression</TT> = 1 (none), 5 (LZW)<BR>
+ <TT>PhotometricInterpretation</TT> = 5 (Separated)<BR>
+ <TT>InkSet</TT> = 1 (CMYK)<BR>
+ <TT>DotRange</TT>,
+ <TT>InkNames</TT>,
+ <TT>DotRange</TT>,
+ <TT>TargetPrinter</TT>
+</TD>
+</TR>
+
+<TD VALIGN=top><I>Class Y for YCbCr images</I></TD>
+<TD><TT>SamplesPerPixel</TT> = 3<BR>
+ <TT>BitsPerSample</TT> = <8,8,8><BR>
+ <TT>PlanarConfiguration</TT> = 1, 2<BR>
+ <TT>Compression</TT> = 1 (none), 5 (LZW), 7 (JPEG)<BR>
+ <TT>PhotometricInterpretation</TT> = 6 (YCbCr)<BR>
+ <TT>YCbCrCoefficients</TT>,
+ <TT>YCbCrSubsampling</TT>,
+ <TT>YCbCrPositioning</TT><BR>
+ (<I>colorimetry info from Appendix H; see above</I>)
+</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top><I>Class "JPEG" for JPEG images (per TTN2)</I></TD>
+<TD><TT>PhotometricInterpretation</TT> = 1 (grayscale), 2 (RGB), 5 (CMYK), 6 (YCbCr)<BR>
+ (<I>Class Y tags if YCbCr</I>)<BR>
+ (<I>Class S tags if CMYK</I>)<BR>
+ <TT>Compression</TT> = 7 (JPEG)<BR>
+</TD>
+</TR>
+</TABLE>
+
+<P>
+In addition, the library supports some optional compression algorithms
+that are, in some cases, of dubious value.
+
+<PRE>
+ Compression = 32766 NeXT 2-bit encoding
+ Compression = 32809 ThunderScan 4-bit encoding
+ Compression = 34999 PKZIP-style Deflate encoding (experimental)
+</PRE>
+
+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.
+
+<P>
+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.
+
+<P>
+<TABLE BORDER WIDTH=100% CELLPADDING=2>
+<TR>
+<TH ALIGN=left>Tag Name</TH> <TH>Value</TH> <TH ALIGN=center>R/W</TH> <TH ALIGN=left>Library's Use (Comments)</TH>
+</TR>
+<TR>
+<TD><TT>NewSubFileType</TT></TD>
+<TD ALIGN=center>254</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>none (called <TT>SubFileType</TT> in &lt;tiff.h&gt;)</TD>
+</TR>
+<TR>
+<TD><TT>SubFileType</TT></TD>
+<TD ALIGN=center>255</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>none (called <TT>OSubFileType</TT> in &lt;tiff.h&gt;)</TD>
+</TR>
+<TR>
+<TD><TT>ImageWidth</TT></TD>
+<TD ALIGN=center>256</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>lots</TD>
+</TR>
+<TR>
+<TD><TT>ImageLength</TT></TD>
+<TD ALIGN=center>257</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>lots</TD>
+</TR>
+<TR>
+<TD><TT>BitsPerSample</TT></TD>
+<TD ALIGN=center>258</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>lots</TD>
+</TR>
+<TR>
+<TD><TT>Compression</TT></TD>
+<TD ALIGN=center>259</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>to select appropriate codec</TD>
+</TR>
+<TR>
+<TD><TT>PhotometricInterpretation</TT></TD>
+<TD ALIGN=center>262</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>lots</TD>
+</TR>
+<TR>
+<TD><TT>Thresholding</TT></TD>
+<TD ALIGN=center>263</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>CellWidth</TT></TD>
+<TD ALIGN=center>264</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>CellLength</TT></TD>
+<TD ALIGN=center>265</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>FillOrder</TT></TD>
+<TD ALIGN=center>266</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>control bit order</TD>
+</TR>
+<TR>
+<TD><TT>DocumentName</TT></TD>
+<TD ALIGN=center>269</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ImageDescription</TT></TD>
+<TD ALIGN=center>270</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>Make</TT></TD>
+<TD ALIGN=center>271</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>Model</TT></TD>
+<TD ALIGN=center>272</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>StripOffsets</TT></TD>
+<TD ALIGN=center>273</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>Orientation</TT></TD>
+<TD ALIGN=center>274</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>SamplesPerPixel</TT></TD>
+<TD ALIGN=center>277</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>lots</TD>
+</TR>
+<TR>
+<TD><TT>RowsPerStrip</TT></TD>
+<TD ALIGN=center>278</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>StripByteCounts</TT></TD>
+<TD ALIGN=center>279</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>MinSampleValue</TT></TD>
+<TD ALIGN=center>280</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>MaxSampleValue</TT></TD>
+<TD ALIGN=center>281</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>XResolution</TT></TD>
+<TD ALIGN=center>282</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>YResolution</TT></TD>
+<TD ALIGN=center>283</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>used by Group 3 2d encoder</TD>
+</TR>
+<TR>
+<TD><TT>PlanarConfiguration</TT></TD>
+<TD ALIGN=center>284</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>PageName</TT></TD>
+<TD ALIGN=center>285</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>XPosition</TT></TD>
+<TD ALIGN=center>286</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>YPosition</TT></TD>
+<TD ALIGN=center>286</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>FreeOffsets</TT></TD>
+<TD ALIGN=center>288</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>FreeByteCounts</TT></TD>
+<TD ALIGN=center>289</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>GrayResponseUnit</TT></TD>
+<TD ALIGN=center>290</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>GrayResponseCurve</TT></TD>
+<TD ALIGN=center>291</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>Group3Options</TT></TD>
+<TD ALIGN=center>292</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>used by Group 3 codec</TD>
+</TR>
+<TR>
+<TD><TT>Group4Options</TT></TD>
+<TD ALIGN=center>293</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ResolutionUnit</TT></TD>
+<TD ALIGN=center>296</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>used by Group 3 2d encoder</TD>
+</TR>
+<TR>
+<TD><TT>PageNumber</TT></TD>
+<TD ALIGN=center>297</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ColorResponseUnit</TT></TD>
+<TD ALIGN=center>300</TD>
+<TD>&nbsp;</TD>
+<TD>parsed but ignored</TD>
+</TR>
+<TR>
+<TD><TT>TransferFunction</TT></TD>
+<TD ALIGN=center>301</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>Software</TT></TD>
+<TD ALIGN=center>305</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>DateTime</TT></TD>
+<TD ALIGN=center>306</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>Artist</TT></TD>
+<TD ALIGN=center>315</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>HostComputer</TT></TD>
+<TD ALIGN=center>316</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>Predictor</TT></TD>
+<TD ALIGN=center>317</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>used by LZW codec</TD>
+</TR>
+<TR>
+<TD><TT>WhitePoint</TT></TD>
+<TD ALIGN=center>318</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>PrimaryChromacities</TT></TD>
+<TD ALIGN=center>319</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ColorMap</TT></TD>
+<TD ALIGN=center>320</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>TileWidth</TT></TD>
+<TD ALIGN=center>322</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>TileLength</TT></TD>
+<TD ALIGN=center>323</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>TileOffsets</TT></TD>
+<TD ALIGN=center>324</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>TileByteCounts</TT></TD>
+<TD ALIGN=center>324</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>data i/o</TD>
+</TR>
+<TR>
+<TD><TT>BadFaxLines</TT></TD>
+<TD ALIGN=center>326</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>CleanFaxData</TT></TD>
+<TD ALIGN=center>327</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ConsecutiveBadFaxLines</TT></TD>
+<TD ALIGN=center>328</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>SubIFD</TT></TD>
+<TD ALIGN=center>330</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>subimage descriptor support</TD>
+</TR>
+<TR>
+<TD><TT>InkSet</TT></TD>
+<TD ALIGN=center>332</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>InkNames</TT></TD>
+<TD ALIGN=center>333</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>DotRange</TT></TD>
+<TD ALIGN=center>336</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>TargetPrinter</TT></TD>
+<TD ALIGN=center>337</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ExtraSamples</TT></TD>
+<TD ALIGN=center>338</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>lots</TD>
+</TR>
+<TR>
+<TD><TT>SampleFormat</TT></TD>
+<TD ALIGN=center>339</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>SMinSampleValue</TT></TD>
+<TD ALIGN=center>340</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>SMaxSampleValue</TT></TD>
+<TD ALIGN=center>341</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>JPEGTables</TT></TD>
+<TD ALIGN=center>347</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>used by JPEG codec</TD>
+</TR>
+<TR>
+<TD><TT>YCbCrCoefficients</TT></TD>
+<TD ALIGN=center>529</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>used by <TT>TIFFReadRGBAImage</TT> support</TD>
+</TR>
+<TR>
+<TD><TT>YCbCrSubsampling</TT></TD>
+<TD ALIGN=center>530</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>tile/strip size calculations</TD>
+</TR>
+<TR>
+<TD><TT>YCbCrPositioning</TT></TD>
+<TD ALIGN=center>531</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>ReferenceBlackWhite</TT></TD>
+<TD ALIGN=center>532</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR>
+<TD><TT>Matteing</TT></TD>
+<TD ALIGN=center>32995</TD>
+<TD ALIGN=center>R</TD>
+<TD>none (obsoleted by <TT>ExtraSamples</TT> tag)</TD>
+</TR>
+<TR>
+<TD><TT>DataType</TT></TD>
+<TD ALIGN=center>32996</TD>
+<TD ALIGN=center>R</TD>
+<TD>none (obsoleted by <TT>SampleFormat</TT> tag)</TD>
+</TR>
+<TR>
+<TD><TT>ImageDepth</TT></TD>
+<TD ALIGN=center>32997</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>tile/strip calculations</TD>
+</TR>
+<TR>
+<TD><TT>TileDepth</TT></TD>
+<TD ALIGN=center>32998</TD>
+<TD ALIGN=center>R/W</TD>
+<TD>tile/strip calculations</TD>
+</TR>
+</TABLE>
+
+<P>
+The <TT>Matteing</TT> and <TT>DataType</TT>
+tags have been obsoleted by the 6.0
+<TT>ExtraSamples</TT> and <TT>SampleFormat</TT> tags.
+Consult the documentation on the
+<TT>ExtraSamples</TT> 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".
+
+<P>
+The <TT>ImageDepth</TT>
+tag is a non-standard, but registered tag that specifies
+the Z-dimension of volumetric data. The combination of <TT>ImageWidth</TT>,
+<TT>ImageLength</TT>, and <TT>ImageDepth</TT>,
+defines a 3D volume of pixels that are
+further specified by <TT>BitsPerSample</TT> and
+<TT>SamplesPerPixel</TT>. The <TT>TileDepth</TT>
+tag (also non-standard, but registered) can be used to specified a
+subvolume "tiling" of a volume of data.
+
+<P>
+The Colorimetry, and CMYK tags are additions that appear in TIFF 6.0.
+Consult the TIFF 6.0 specification included in the <B>doc</B> directory
+and <A HREF=document.html>online</A>.
+
+<P>
+The JPEG-related tag is specified in
+<A HREF=ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt.gz>TIFF Technical Note #2</A> which defines
+a revised JPEG-in-TIFF scheme (revised over that appendix that was
+part of the TIFF 6.0 specification).
+
+
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/30 23:28:32 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/tools.html b/html/tools.html
new file mode 100644
index 00000000..5116e17c
--- /dev/null
+++ b/html/tools.html
@@ -0,0 +1,188 @@
+<HTML>
+<HEAD>
+<TITLE>
+TIFF Tools Overview
+</TITLE>
+</HEAD>
+
+<H1>
+<IMG SRC=images/quad.jpg WIDTH=144 HEIGHT=108 ALIGN=left BORDER=1 HSPACE=6>
+TIFF Tools Overview
+</H1>
+
+<H5>
+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
+<A HREF="http://home.mcom.com/comprod/netscape_nav.html">Netscape Navigator</A>.
+</H5>
+
+<BR CLEAR=left>
+
+<P>
+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.
+
+<H3>Device-dependent Programs</H3>
+
+There are two device-dependent programs that serve as simple examples
+for writing programs to display and save TIFF images.
+
+
+<P>
+<TABLE BORDER CELLPADDING=3>
+
+<TR>
+<TD valign=top WIDTH=10%><TT>tiffgt&nbsp;&nbsp;&nbsp;&nbsp;</TT></TD>
+<TD>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 <TT>TIFFRGBAImage</TT>
+facilities described elsewhere.</TD>
+</TR>
+
+<TR>
+<TD valign=top WIDTH=10%><TT>tiffsv</TT></TD>
+<TD>A program to save all or part of a screen dump on a Silicon
+Graphics system.
+As for <TT>tiffgt</TT> this code, while written to use the IRIS GL,
+can be easily tailored to other devices.</TD>
+</TR>
+
+</TABLE>
+
+<H3>Device-independent Programs</H3>
+
+The remaining programs should be device-independent:
+
+<P>
+<TABLE BORDER CELLPADDING=3>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffinfo</TT></TD>
+<TD>Display information about one or more TIFF files.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffdump</TT></TD>
+<TD>Display 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)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffcp</TT></TD>
+<TD>Copy, concatenate, and convert TIFF images (e.g.
+ switching from Compression=5 to Compression=1)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiff2ps</TT></TD>
+<TD>Convert TIFF images to PostScript</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffcmp</TT></TD>
+<TD>Compare the contents of two TIFF files (it does
+ not check all the directory information, but does check all the data)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiff2bw</TT></TD>
+<TD>A simple program to convert a color image to grayscale</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>ras2tiff</TT></TD>
+<TD>A quick hack that converts Sun rasterfile format images to
+ TIFF -- it's less than complete</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>rgb2ycbcr</TT></TD>
+<TD>Convert an RGB, grayscale, or bilevel TIFF image to a
+ YCbCr TIFF image; it's mainly provided for testing</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>gif2tiff</TT></TD>
+<TD>A quick hack that converts GIF 87a format images to TIFF</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>ppm2tiff</TT></TD>
+<TD>A quick hack that converts PPM format images to TIFF</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>fax2tiff</TT></TD>
+<TD>Convert raw Group 3 or Group 4 facsimile data to TIFF</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>pal2rgb</TT></TD>
+<TD>Convert a Palette-style image to a full color RGB image by
+ applying the colormap</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffdither</TT></TD>
+<TD>Dither a b&w image into a bilevel image (suitable for
+ use in creating fax files)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffsplit</TT></TD>
+<TD>Create one or more single-image files from a (possibly)
+ multi-image file</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>fax2ps</TT></TD>
+<TD>Convert a Group 3- or Group 4- compressed TIFF to PostScript
+ that is significantly more compressed than is generated by <TT>tiff2ps</TT>
+ (unless <TT>tiff2ps</TT> writes PS Level II)</TD>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>thumbnail</TT></TD>
+<TD>Copy 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 <TT>SubIFD</TT> tag
+ (and the library support for it)</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>tiffmedian</TT></TD>
+<TD>A 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.</TD>
+</TR>
+
+<TR>
+<TD VALIGN=top WIDTH=10%><TT>sgi2tiff</TT></TD>
+<TD>A program to convert SGI image files to TIFF. This
+ program is only useful on SGI machines as it uses <TT>-limage</TT>.</TD>
+</TR>
+
+</TABLE>
+
+<P>
+Check out the manual pages for details about the above programs.
+
+
+<P>
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>.
+Last updated: $Date: 1995/06/28 23:57:28 $
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/v3.4beta007.html b/html/v3.4beta007.html
new file mode 100644
index 00000000..816c7cbf
--- /dev/null
+++ b/html/v3.4beta007.html
@@ -0,0 +1,111 @@
+<HTML>
+<HEAD>
+<TITLE>
+Changes in TIFF v3.4beta007
+</TITLE>
+</HEAD>
+
+<BODY>
+
+<BASEFONT SIZE=4>
+<B><FONT SIZE=+3>T</FONT>IFF <FONT SIZE=+2>C</FONT>HANGE <FONT SIZE=+2>I</FONT>NFORMATION</B>
+<BASEFONT SIZE=3>
+
+<UL>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+<B>Current Version</B>: v3.4beta007<BR>
+<B>Previous Version</B>: v3.4beta004<BR>
+<B>Master FTP Site</B>: <A HREF="ftp://ftp.sgi.com/graphics/tiff">ftp.sgi.com (192.48.153.1), directory graphics/tiff</A><BR>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+</UL>
+
+<P>
+This document describes the changes made to the software between the
+<I>previous</I> and <I>current</I> 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:
+<UL>
+<LI><A HREF="#configure">Changes in the software configuration</A>
+<LI><A HREF="#libtiff">Changes in libtiff</A>
+<LI><A HREF="#port">Changes in the portability support</A>
+<LI><A HREF="#tools">Changes in the tools</A>
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="configure"><B><FONT SIZE=+3>C</FONT>HANGES IN THE SOFTWARE CONFIGURATION:</B></A>
+
+<UL>
+<LI>bit order was corrected for Pentium systems
+<LI>a new define, <TT>HOST_BIGENDIAN</TT>, was added for code that
+ wants to statically use information about native cpu byte order
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="libtiff"><B><FONT SIZE=+3>C</FONT>HANGES IN LIBTIFF:</B></A>
+
+<UL>
+<LI>the G3/G4 decoder was replaced by a new one that is faster and
+ has smaller state tables
+<LI>Niles Ritter's client tag extension hooks were added
+<LI>a new routine <TT>TIFFCurrentDirOffset</TT> was added for
+ applications that want to find out the file offset of a TIFF directory
+<LI>the calculation of the number of strips in an image was corected
+ for images with certain esoteric configurations
+<LI>a potential memory leak (very unlikely) was plugged
+<LI>the <TT>TIFFReadRGBAImage</TT> support was completely rewritten
+ and new, more flexible support was added for reading images into
+ a fixed-format raster
+<LI>YCbCr to RGB conversion done in the <TT>TIFFReadRGBAImage</TT> support
+ was optimized
+<LI>a bug in JPEG support calculation of strip size was corrected
+<LI>the LZW decoder was changed to initialize the code table to zero
+ to lessen potential problems that arise when invalid data is decoded
+<LI><B>tiffcomp.h</B> is now aware of OS/2
+<LI>some function prototypes in <B>tiffio.h</B> and <B>tiffiop.h</B>
+ that contained parameter
+ names have been changed to avoid complaints from certain compilers
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="port"><B><FONT SIZE=+3>C</FONT>HANGES IN THE PORTABILITY SUPPORT:</B></A>
+
+<UL>
+<LI><B>Makefile.in</B> has been corrected to use the parameters
+ chosen by the configure script
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="tools"><B><FONT SIZE=+3>C</FONT>HANGES IN THE TOOLS:</B></A>
+
+<UL>
+<LI><TT>fax2ps</TT> has been rewritten and moved over from the user
+ contributed software
+<LI>an uninitialized variable in <TT>pal2rgb</TT> has been fixed
+<LI><TT>ras2tiff</TT> now converts 24-bit RGB raster data so that
+ samples are written in the proper order
+<LI><TT>tiff2ps</TT> has been updated to include fixes
+ and enhancements from Alberto Accomazzi
+<LI><TT>tiffcp</TT> now has a <TT>-o</TT> option to select a directory
+ by file offset
+<LI><TT>tiffinfo</TT> is now capable of displaying the raw undecoded
+ image data in a file
+<LI><TT>tiffgt</TT> has been rewritten to use the new <TT>TIFFRGBAImage</TT>
+ support and to handle multiple files
+</UL>
+
+<A HREF="index.html"><IMG SRC="images/back.gif"></A> TIFF home page.<BR>
+
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>
+Last updated $Date: 1995/07/03 18:00:06 $.
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/v3.4beta016.html b/html/v3.4beta016.html
new file mode 100644
index 00000000..069bd6cf
--- /dev/null
+++ b/html/v3.4beta016.html
@@ -0,0 +1,121 @@
+<HTML>
+<HEAD>
+<TITLE>
+Changes in TIFF v3.4beta016
+</TITLE>
+</HEAD>
+
+<BODY>
+
+<BASEFONT SIZE=4>
+<B><FONT SIZE=+3>T</FONT>IFF <FONT SIZE=+2>C</FONT>HANGE <FONT SIZE=+2>I</FONT>NFORMATION</B>
+<BASEFONT SIZE=3>
+
+<UL>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+<B>Current Version</B>: v3.4beta016<BR>
+<B>Previous Version</B>: <A HREF=v3.4beta007.html>v3.4beta007</A><BR>
+<B>Master FTP Site</B>: <A HREF="ftp://ftp.sgi.com/graphics/tiff">ftp.sgi.com (192.48.153.1), directory graphics/tiff</A><BR>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+</UL>
+
+<P>
+This document describes the changes made to the software between the
+<I>previous</I> and <I>current</I> 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:
+<UL>
+<LI><A HREF="#configure">Changes in the software configuration</A>
+<LI><A HREF="#libtiff">Changes in libtiff</A>
+<LI><A HREF="#tools">Changes in the tools</A>
+<LI><A HREF="#man">Changes in the manual pages</A>
+<LI><A HREF="#html">Changes in the documentation</A>
+<LI><A HREF="#contrib">Changes in contributed software</A>
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="configure"><B><FONT SIZE=+3>C</FONT>HANGES IN THE SOFTWARE CONFIGURATION:</B></A>
+
+<UL>
+<LI>support was added for configuring the Deflate codec
+<LI>support was added for the HTML documentation
+<LI>codecs that are not configured for inclusion in the library
+ are no longer compiled
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="libtiff"><B><FONT SIZE=+3>C</FONT>HANGES IN LIBTIFF:</B></A>
+
+<UL>
+<LI>support was added for registering new codecs external to the library
+ and for overriding the codecs that are builtin to the library
+<LI>emulation support for the old <TT>DataType</TT> tag was improved
+<LI>suppport was added for the <TT>SMinSampleValue</TT>
+ and <TT>SMaxSampleValue</TT> tags
+<LI>the library no longer ignores <TT>TileWidth</TT> and <TT>TileLength</TT>
+ tags whose values are not a multiple of 16 (per the spec); this
+ permits old, improperly written, images to be read
+<LI>the support for the <TT>Predictor</TT> tag was placed in a reusable
+ module so that it can be shared by multiple codecs
+<LI>experimental compression support was added for the Deflate algorithm
+ (using the freely available zlib package)
+<LI>a new routine, <TT>TIFFWriteBufferSetup</TT> was added a la the
+ routine <TT>TIFFReadBufferSetup</TT>
+<LI>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
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="tools"><B><FONT SIZE=+3>C</FONT>HANGES IN THE TOOLS:</B></A>
+
+<UL>
+<LI>all the tools now use common code to process compress-oriented arguments
+<LI><TT>tiffdump</TT> should now compile on a Macintosh with MPW
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="man"><B><FONT SIZE=+3>C</FONT>HANGES IN THE MANUAL PAGES:</B></A>
+
+<UL>
+<LI>everything was updated
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="html"><B><FONT SIZE=+3>C</FONT>HANGES IN THE DOCUMENTATION:</B></A>
+
+<UL>
+<LI>everything was updated
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="contrib"><B><FONT SIZE=+3>C</FONT>HANGES IN CONTRIBUTED SOFTWARE:</B></A>
+
+<UL>
+<LI><B>contrib/dbs/xtiff</B> was made to compile
+<LI><B>contrib/mac-mpw</B> is new support for compiling the software on
+ a Macintosh under MPW; consult <A HREF=build.html#Mac>the documentation</A>
+ for details
+<LI><B>contrib/tags</B> is information on how to use the tag extenion
+ facilities; consult
+ <A HREF=../contrib/tags/README>contrib/tags/README</A> for details
+</UL>
+
+<A HREF="index.html"><IMG SRC="images/back.gif"></A> TIFF home page.<BR>
+
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>
+Last updated $Date: 1995/07/03 18:00:03 $.
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/html/v3.4beta018.html b/html/v3.4beta018.html
new file mode 100644
index 00000000..db1d84ed
--- /dev/null
+++ b/html/v3.4beta018.html
@@ -0,0 +1,83 @@
+<HTML>
+<HEAD>
+<TITLE>
+Changes in TIFF v3.4beta018
+</TITLE>
+</HEAD>
+
+<BODY>
+
+<BASEFONT SIZE=4>
+<B><FONT SIZE=+3>T</FONT>IFF <FONT SIZE=+2>C</FONT>HANGE <FONT SIZE=+2>I</FONT>NFORMATION</B>
+<BASEFONT SIZE=3>
+
+<UL>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+<B>Current Version</B>: v3.4beta018<BR>
+<B>Previous Version</B>: <A HREF=v3.4beta016.html>v3.4beta016</A><BR>
+<B>Master FTP Site</B>: <A HREF="ftp://ftp.sgi.com/graphics/tiff">ftp.sgi.com (192.48.153.1), directory graphics/tiff</A><BR>
+<HR SIZE=4 WIDTH=65% ALIGN=left>
+</UL>
+
+<P>
+This document describes the changes made to the software between the
+<I>previous</I> and <I>current</I> 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:
+<UL>
+<LI><A HREF="#configure">Changes in the software configuration</A>
+<LI><A HREF="#libtiff">Changes in libtiff</A>
+<LI><A HREF="#tools">Changes in the tools</A>
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="configure"><B><FONT SIZE=+3>C</FONT>HANGES IN THE SOFTWARE CONFIGURATION:</B></A>
+
+<UL>
+<LI>configure now recognizes IRIX 6.x systems
+<LI>configure now uses <TT>ENVOPTS</TT> when searching for an ANSI
+ C compiler; this fixes a problem configuring the software under
+ HP/UX with the native C compiler
+<LI>configure now correctly recognizes memory-mapped files are supported
+ under AIX
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="libtiff"><B><FONT SIZE=+3>C</FONT>HANGES IN LIBTIFF:</B></A>
+
+<UL>
+<LI><TT>make install</TT> now properly installs the include files
+<LI>some portability fixes from Bjorn Brox
+<LI>the G3/G4 codec now warns about decoded rows that are longer than
+ the image/tile width
+<LI>changes from Frank Cringle to make the library work with the
+ gcc-specific bounds checking software
+<LI>miscellaneous fixes to <TT>TIFFPrintDirectory</TT>
+<LI>bug fix to correct a problem where <TT>TIFFWriteRawStrip</TT>
+ could not be used to automatically grow an image's length
+</UL>
+
+<P><HR WIDTH=65% ALIGN=right>
+
+<A NAME="tools"><B><FONT SIZE=+3>C</FONT>HANGES IN THE TOOLS:</B></A>
+
+<UL>
+<LI>fixes from Frank Cringle to update <TT>fax2tiff</TT>
+<LI>portability fixes to <TT>tiff2bw</TT> and <TT>tiffcmp</TT>
+<LI><TT>tiffdump</TT> now uses the byte swapping routines in the library
+</UL>
+
+<A HREF="index.html"><IMG SRC="images/back.gif"></A> TIFF home page.<BR>
+
+<HR>
+
+<ADDRESS>
+<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:sam@engr.sgi.com">sam@engr.sgi.com</A>
+Last updated $Date: 1995/07/19 01:54:02 $.
+</ADDRESS>
+
+</BODY>
+</HTML>
diff --git a/libtiff/Makefile.in b/libtiff/Makefile.in
new file mode 100644
index 00000000..d1ce4ee2
--- /dev/null
+++ b/libtiff/Makefile.in
@@ -0,0 +1,281 @@
+# $Header: /usr/people/sam/tiff/libtiff/RCS/Makefile.in,v 1.20 1995/07/17 19:26:25 sam Exp $
+#
+# Tag Image File Format Library
+#
+# Copyright (c) 1988-1995 Sam Leffler
+# Copyright (c) 1991-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 = ${DEPTH}/@SRCDIR@/libtiff
+
+JPEGDIR = ${DEPTH}/@DIR_JPEG@
+ZIPDIR = ${DEPTH}/@DIR_LIBGZ@
+PORT = ${DEPTH}/port
+
+#
+# VERSION: @VERSION@
+# DATE: @DATE@
+# TARGET: @TARGET@
+# CCOMPILER: @CCOMPILER@
+#
+SHELL = /bin/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 INC_JPEG will
+# refer to the directory where the include files reside.
+#
+IPATH = -I. -I${DEPTH} -I${SRCDIR} -I${JPEGDIR} -I${ZIPDIR}
+#
+# To enable JPEG support (with the default configuration), include
+# -DJPEG_SUPPORT here, setup the include search path above, and
+# configure the tools to locate the appropriate libjpeg. Otherwise,
+# consult tiffconf.h for information on controlling the configuration
+# of optional library support.
+#
+CONF_LIBRARY=\
+ @CONF_JPEG@ \
+ @CONF_ZIP@ \
+ ${NULL}
+COPTS = @GCOPTS@
+OPTIMIZER=-O
+CFLAGS = @ENVOPTS@ ${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_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_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_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_unix.o \
+ tif_version.o \
+ tif_warning.o \
+ tif_write.o \
+ tif_zip.o \
+ ${NULL}
+TARGETS = libtiff.a
+
+all: ${TARGETS}
+ if [ "@DSO@" = yes ]; then \
+ ${MAKE} dso; \
+ fi
+
+libtiff.a: ${OBJS}
+ ${AR} ${AROPTS} libtiff.a $?
+ ${RANLIB} libtiff.a
+dso: ${OBJS}
+ ${CC} -o libtiff.@DSOSUF@ -shared -rdata_shared ${OBJS} \
+ @LIBJPEG@ @LIBGZ@
+ touch dso
+
+${OBJS}: ${SRCDIR}/tiffio.h ${SRCDIR}/tiff.h ${SRCDIR}/tif_dir.h
+${OBJS}: ${SRCDIR}/tiffcomp.h ${SRCDIR}/tiffiop.h ${SRCDIR}/tiffconf.h
+
+tif_fax3.o: ${SRCDIR}/t4.h ${SRCDIR}/tif_fax3.h
+#
+# NB: can't use these since the software may not be configure
+# for use with JPEG support. Really need dynamic include
+# file dependency support; but that's too much effort.
+#
+#tif_jpeg.o: ${JPEGDIR}/jpeglib.h ${JPEGDIR}/jerror.h
+tif_lzw.o: ${SRCDIR}/tif_predict.h
+tif_predict.o: ${SRCDIR}/tif_predict.h
+tif_zip.o: ${SRCDIR}/tif_predict.h
+#
+# NB: can't use these since the software may not be configure
+# for use with Deflate support.
+#
+#tif_zip.o: ${ZIPDIR}/zlib.h ${ZIPDIR}/zutil.h
+
+ALPHA = ${DEPTH}/@SRCDIR@/dist/tiff.alpha
+VERSION = ${DEPTH}/@SRCDIR@/VERSION
+
+version.h: ${VERSION} ${ALPHA}
+ VERSION=`cat ${VERSION}`; \
+ VERSION="$${VERSION}`awk '{print $$3}' ${ALPHA}`"; \
+ rm -f version.h; \
+ echo '#define VERSION "LIBTIFF, Version' $$VERSION '\\nCopyright (c) 1988-1995 Sam Leffler\\nCopyright (c) 1991-1995 Silicon Graphics, Inc."' >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
+ ${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
+ ${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
+ ${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
+ ${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
+ ${INSTALL} -idb tiff.sw.tools -m 444 -F @DIR_LIB@ -O libtiff.@DSOSUF@
+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@" = yes ]; then \
+ ${MAKE} installDSO; \
+ fi
+
+clean:
+ rm -f ${TARGETS} ${OBJS} core a.out mkg3states tif_fax3sm.c version.h \
+ libtiff.@DSOSUF@ dso
diff --git a/libtiff/Makefile.lcc b/libtiff/Makefile.lcc
new file mode 100644
index 00000000..5da688da
--- /dev/null
+++ b/libtiff/Makefile.lcc
@@ -0,0 +1,129 @@
+# $Header: /usr/people/sam/tiff/libtiff/RCS/Makefile.lcc,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 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/Makefile.msc b/libtiff/Makefile.msc
new file mode 100644
index 00000000..f1c9e30f
--- /dev/null
+++ b/libtiff/Makefile.msc
@@ -0,0 +1,151 @@
+# $Header: /usr/people/sam/tiff/libtiff/RCS/Makefile.msc,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 msc (7.0) using dmake.
+#
+DESTDIR=.
+#
+IPATH= -I. -I../jpeg
+CONF_LIBRARY=\
+ ${NULL}
+COPTS= -Oxaz -AL -DBSDTYPES -Zi -Zd
+CFLAGS= ${COPTS} ${IPATH} ${CONF_LIBRARY}
+#
+INCS= tiff.h tiffio.h
+SRCS= tif_fax3.c \
+ tif_fax4.c \
+ tif_aux.c \
+ tif_ccit.c \
+ tif_clos.c \
+ tif_comp.c \
+ tif_dir.c \
+ tif_diri.c \
+ tif_dirr.c \
+ tif_dirw.c \
+ tif_dump.c \
+ tif_erro.c \
+ tif_geti.c \
+ tif_jpeg.c \
+ tif_flus.c \
+ tif_lzw.c \
+ tif_next.c \
+ tif_open.c \
+ tif_pack.c \
+ tif_prin.c \
+ tif_read.c \
+ tif_swab.c \
+ tif_stri.c \
+ tif_thun.c \
+ tif_tile.c \
+ tif_unix.c \
+ tif_vers.c \
+ tif_warn.c \
+ tif_writ.c \
+ ${NULL}
+OBJS= tif_fax3.obj \
+ tif_fax4.obj \
+ tif_aux.obj \
+ tif_ccit.obj \
+ tif_clos.obj \
+ tif_comp.obj \
+ tif_dir.obj \
+ tif_diri.obj \
+ tif_dirr.obj \
+ tif_dirw.obj \
+ tif_dump.obj \
+ tif_erro.obj \
+ tif_geti.obj \
+ tif_jpeg.obj \
+ tif_flus.obj \
+ tif_lzw.obj \
+ tif_msdo.obj \
+ tif_next.obj \
+ tif_open.obj \
+ tif_pack.obj \
+ tif_prin.obj \
+ tif_read.obj \
+ tif_stri.obj \
+ tif_swab.obj \
+ tif_thun.obj \
+ tif_tile.obj \
+ tif_vers.obj \
+ tif_warn.obj \
+ tif_writ.obj \
+ ${NULL}
+ALL= libtiff.lib
+
+all: ${ALL}
+
+%.obj : %.c
+ $(CC) $(CFLAGS) -c $*.c
+
+#.INCLUDE .IGNORE : depend
+
+${ALL}: ${OBJS}
+ lib libtiff /NOIGNO /NOLOGO -+tif_fax3.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_fax4.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_aux.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_ccit.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_clos.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_comp.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_dir.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_diri.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_dirr.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_dirw.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_dump.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_erro.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_geti.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_jpeg.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_flus.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_lzw.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_msdo.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_next.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_open.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_pack.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_prin.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_read.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_stri.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_swab.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_thun.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_tile.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_vers.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_warn.obj;
+ lib libtiff /NOIGNO /NOLOGO -+tif_writ.obj;
+
+${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/libtiff/mkg3states.c b/libtiff/mkg3states.c
new file mode 100644
index 00000000..f96a4fba
--- /dev/null
+++ b/libtiff/mkg3states.c
@@ -0,0 +1,425 @@
+/* "$Header: /usr/people/sam/tiff/libtiff/RCS/mkg3states.c,v 1.31 1995/07/17 01:27:30 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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;
+
+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%d,%d,%d", sep, T->State, T->Width, T->Param);
+ if (((i+1) % 12) == 0)
+ sep = ",\n";
+ else
+ sep = ",";
+ T++;
+ }
+ } else {
+ sep = "\n ";
+ for (i = 0; i < Size; i++) {
+ fprintf(fd, "%s%3d,%3d,%4d", sep, T->State, T->Width, T->Param);
+ if (((i+1) % 6) == 0)
+ sep = ",\n ";
+ else
+ sep = ",";
+ T++;
+ }
+ }
+ fprintf(fd, "\n};\n");
+}
+
+/* initialise the huffman code tables */
+main(int argc, char* argv[])
+{
+ FILE* fd;
+ char* outputfile;
+ int c;
+ extern int optind;
+ extern char* optarg;
+
+ while ((c = getopt(argc, argv, "c:s:p")) != -1)
+ switch (c) {
+ case 'c':
+ const_class = optarg;
+ break;
+ case 's':
+ storage_class = optarg;
+ break;
+ case 'p':
+ packoutput = 0;
+ break;
+ case '?':
+ fprintf(stderr, "usage: %s [-c const] [-s storage] [-p] file\n",
+ argv[0]);
+ exit(-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);
+ exit(-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);
+ exit(0);
+}
diff --git a/libtiff/mkspans.c b/libtiff/mkspans.c
new file mode 100644
index 00000000..9ab069e6
--- /dev/null
+++ b/libtiff/mkspans.c
@@ -0,0 +1,72 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/mkspans.c,v 1.9 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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/t4.h b/libtiff/t4.h
new file mode 100644
index 00000000..ff7d1d10
--- /dev/null
+++ b/libtiff/t4.h
@@ -0,0 +1,285 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/t4.h,v 1.14 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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_apple.c b/libtiff/tif_apple.c
new file mode 100644
index 00000000..b8b58ebf
--- /dev/null
+++ b/libtiff/tif_apple.c
@@ -0,0 +1,256 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_apple.c,v 1.19 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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 <Errors.h>
+#include <Files.h>
+#include <Memory.h>
+
+#ifdef 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..0826dca5
--- /dev/null
+++ b/libtiff/tif_atari.c
@@ -0,0 +1,243 @@
+/* "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_atari.c,v 1.4 1995/06/06 23:49:31 sam Exp $" */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library ATARI-specific Routines.
+ */
+#include "tiffiop.h"
+#if defined(__TURBOC__)
+#include <tos.h>
+#include <stdio.h>
+#else
+#include <osbind.h>
+#include <fcntl.h>
+#endif
+
+#ifndef O_ACCMODE
+#define O_ACCMODE 3
+#endif
+
+#include <errno.h>
+
+#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 <stdlib.h>
+
+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..6410916a
--- /dev/null
+++ b/libtiff/tif_aux.c
@@ -0,0 +1,200 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_aux.c,v 1.31 1995/07/18 23:13:19 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Auxiliary Support Routines.
+ */
+#include "tiffiop.h"
+
+#ifdef COLORIMETRY_SUPPORT
+#include <math.h>
+
+static void
+TIFFDefaultTransferFunction(TIFFDirectory* td)
+{
+ uint16 **tf = td->td_transferfunction;
+ long i, n = 1<<td->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->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->td_bitspersample)-1;
+ return (1);
+ case TIFFTAG_INKSET:
+ *va_arg(ap, uint16 *) = td->td_inkset;
+ 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..9240da18
--- /dev/null
+++ b/libtiff/tif_close.c
@@ -0,0 +1,51 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_close.c,v 1.29 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ */
+#include "tiffiop.h"
+
+void
+TIFFClose(TIFF* tif)
+{
+ if (tif->tif_mode != O_RDONLY)
+ /*
+ * Flush buffered data and directory (if dirty).
+ */
+ TIFFFlush(tif);
+ if (tif->tif_cleanup)
+ (*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..f70510a0
--- /dev/null
+++ b/libtiff/tif_codec.c
@@ -0,0 +1,95 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_codec.c,v 1.4 1995/06/30 00:58:51 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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
+
+/*
+ * Compression schemes statically built into the library.
+ */
+TIFFCodec _TIFFBuiltinCODECS[] = {
+ { "Null", 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 Group3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3 },
+ { "CCITT Group4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4 },
+ { "ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG },
+ { "Deflate", COMPRESSION_DEFLATE, TIFFInitZIP },
+ { NULL },
+};
+
+static int
+NotConfigured(TIFF* tif, int scheme)
+{
+ const TIFFCodec* c = TIFFFindCODEC(scheme);
+
+ TIFFError(tif->tif_name,
+ "%s compression support is not configured", c->name);
+ return (0);
+}
diff --git a/libtiff/tif_compress.c b/libtiff/tif_compress.c
new file mode 100644
index 00000000..63e4911b
--- /dev/null
+++ b/libtiff/tif_compress.c
@@ -0,0 +1,205 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_compress.c,v 1.48 1995/07/07 02:30:16 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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);
+ TIFFError(tif->tif_name,
+ "%s %s encoding is not implemented", c->name, 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);
+ TIFFError(tif->tif_name,
+ "%s %s decoding is not implemented", c->name, 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; }
+
+int
+TIFFSetCompressionScheme(TIFF* tif, int scheme)
+{
+ const TIFFCodec *c = TIFFFindCODEC(scheme);
+
+ if (!c) {
+ TIFFError(tif->tif_name,
+ "Unknown data compression algorithm %u (0x%x)",
+ scheme, scheme);
+ return (0);
+ }
+ 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;
+ return ((*c->init)(tif, scheme));
+}
+
+/*
+ * 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 registere compression scheme %s", name);
+ return (cd->info);
+}
+
+void
+TIFFUnRegisterCODEC(TIFFCodec* c)
+{
+ codec_t* cd;
+ codec_t** pcd;
+
+ for (pcd = &registeredCODECS; (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..f32d5147
--- /dev/null
+++ b/libtiff/tif_dir.c
@@ -0,0 +1,981 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dir.c,v 1.151 1995/07/19 00:39:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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 _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);
+}
+
+static int
+_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
+{
+ TIFFDirectory* td = &tif->tif_dir;
+ int status = 1;
+ uint32 v32;
+ int i, v;
+
+ 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->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;
+#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->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:
+ _TIFFsetString(&td->td_inknames, va_arg(ap, char*));
+ break;
+ case TIFFTAG_TARGETPRINTER:
+ _TIFFsetString(&td->td_targetprinter, va_arg(ap, char*));
+ break;
+#endif
+ default:
+ TIFFError(tif->tif_name,
+ "Internal error, tag value botch, tag \"%s\"",
+ _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);
+}
+
+/*
+ * 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)
+{
+ if (tag != TIFFTAG_IMAGELENGTH &&
+ (tif->tif_flags & TIFF_BEENWRITING)) {
+ const TIFFFieldInfo *fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
+ /*
+ * 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.
+ */
+ if (fip && !fip->field_oktochange) {
+ 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;
+#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_TARGETPRINTER:
+ *va_arg(ap, char**) = td->td_targetprinter;
+ break;
+#endif
+ default:
+ TIFFError("_TIFFVGetField",
+ "Internal error, no value returned for tag \"%s\"",
+ _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 && 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
+ 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;
+#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);
+}
+
+/*
+ * 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..cd94c71f
--- /dev/null
+++ b/libtiff/tif_dir.h
@@ -0,0 +1,220 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dir.h,v 1.2 1995/06/30 05:46:47 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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;
+ 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_dotrange[2];
+ char* td_inknames;
+ char* td_targetprinter;
+#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_CODEC 50 /* base of codec-private tags */
+
+#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 (-1 for unknown) */
+ short field_writecount; /* write count (-1 for unknown) */
+ 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 */
+
+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..013daa58
--- /dev/null
+++ b/libtiff/tif_dirinfo.c
@@ -0,0 +1,360 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dirinfo.c,v 1.36 1995/06/30 05:46:47 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Core Directory Tag Support.
+ */
+#include "tiffiop.h"
+#include <stdlib.h>
+
+/*
+ * 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, FALSE, "InkNames" },
+ { 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 */
+};
+#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;
+ int c = ta->field_tag - tb->field_tag;
+ return (c != 0 ? c : tb->field_type - ta->field_type);
+}
+
+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] %5u, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
+ , i
+ , 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 <assert.h>
+#include <stdio.h>
+
+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..a88568ef
--- /dev/null
+++ b/libtiff/tif_dirread.c
@@ -0,0 +1,1373 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dirread.c,v 1.68 1995/06/30 05:46:47 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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*);
+#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);
+}
+
+/*
+ * 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.
+ */
+ if (tif->tif_curdir != (tdir_t) -1)
+ (*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 (short) > 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->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->td_bitspersample)-1);
+ /*
+ * Setup default compression scheme.
+ */
+ if (!TIFFFieldSet(tif, FIELD_COMPRESSION))
+ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+#if STRIPCHOP_SUPPORT
+ /*
+ * 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 &&
+ td->td_tilewidth == td->td_imagewidth)
+ ChopUpSingleUncompressedStrip(tif);
+#endif
+ /*
+ * 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) / 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)
+{
+ float v = (float)
+ TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
+ 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 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 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
+
+#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/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
new file mode 100644
index 00000000..24bcbc2b
--- /dev/null
+++ b/libtiff/tif_dirwrite.c
@@ -0,0 +1,972 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dirwrite.c,v 1.52 1995/06/30 05:46:47 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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
+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 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 <n> 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;
+
+ 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);
+ dir->tdir_count = wc;
+ } 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);
+ dir->tdir_count = wc;
+ } 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);
+ dir->tdir_count = wc;
+ } 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);
+ dir->tdir_count = wc;
+ } 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:
+ { double* dp;
+ if (wc == (u_short) TIFF_VARIABLE) {
+ TIFFGetField(tif, fip->field_tag, &wc, &dp);
+ dir->tdir_count = wc;
+ } else
+ TIFFGetField(tif, fip->field_tag, &dp);
+ TIFFCvtNativeToIEEEDouble(tif, wc, dp);
+ if (!TIFFWriteData(tif, dir, (char*) dp))
+ 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
+ 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->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->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 = 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..9007977c
--- /dev/null
+++ b/libtiff/tif_dumpmode.c
@@ -0,0 +1,114 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dumpmode.c,v 1.39 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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..67bf557d
--- /dev/null
+++ b/libtiff/tif_error.c
@@ -0,0 +1,49 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_error.c,v 1.20 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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..63ff0f22
--- /dev/null
+++ b/libtiff/tif_fax3.c
@@ -0,0 +1,1462 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_fax3.c,v 1.128 1995/07/17 01:27:30 sam Exp $ */
+
+/*
+ * Copyright (c) 1990-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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 <assert.h>
+#include <stdio.h>
+
+/*
+ * 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 */
+ 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)
+
+/*
+ * Write the sequence of codes that describes
+ * the specified span of zero's or one's. The
+ * appropriate table that holds the make-up and
+ * terminating codes is supplied.
+ */
+static void
+putspan(TIFF* tif, int32 span, const tableentry* tab)
+{
+ Fax3EncodeState* sp = EncoderState(tif);
+ int bit = sp->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;
+ _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;
+ _PutBits(tif, code, length);
+ span -= te->runlen;
+ }
+ code = tab[span].code, length = tab[span].length;
+ _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 = (res * .3937f) / 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);
+ }
+ _TIFFfree(tif->tif_data);
+ tif->tif_data = NULL;
+ }
+}
+
+#define FIELD_FAXMODE (FIELD_CODEC+0)
+#define FIELD_OPTIONS (FIELD_CODEC+1)
+#define FIELD_BADFAXLINES (FIELD_CODEC+2)
+#define FIELD_CLEANFAXDATA (FIELD_CODEC+3)
+#define FIELD_BADFAXRUN (FIELD_CODEC+4)
+
+static const TIFFFieldInfo fax3FieldInfo[] = {
+ { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, FIELD_FAXMODE,
+ FALSE, FALSE, "" },
+ { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, FIELD_OPTIONS,
+ FALSE, FALSE, "Group3Options" },
+ { 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" },
+};
+static const TIFFFieldInfo fax4FieldInfo[] = {
+ { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, FIELD_FAXMODE,
+ FALSE, FALSE, "" },
+ { 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;
+ 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;
+ 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);
+}
+
+int
+TIFFInitCCITTFax3(TIFF* tif, int scheme)
+{
+ 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.
+ */
+ switch (scheme) {
+ case COMPRESSION_CCITTFAX3:
+ _TIFFMergeFieldInfo(tif, fax3FieldInfo, N(fax3FieldInfo));
+ break;
+ case COMPRESSION_CCITTFAX4:
+ _TIFFMergeFieldInfo(tif, fax4FieldInfo, N(fax4FieldInfo));
+ break;
+ }
+ 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;
+
+ TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
+ 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);
+}
+
+/*
+ * 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 (TIFFInitCCITTFax3(tif, scheme)) { /* reuse G3 logic */
+ 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 (TIFFInitCCITTFax3(tif, scheme)) { /* reuse G3 compression */
+ 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 (TIFFInitCCITTFax3(tif, scheme)) { /* reuse G3 compression */
+ 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..f09cdbec
--- /dev/null
+++ b/libtiff/tif_fax3.h
@@ -0,0 +1,496 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_fax3.h,v 1.26 1995/07/17 01:27:30 sam Exp $ */
+
+/*
+ * Copyright (c) 1990-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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.
+ */
+#ifndef NeedBits8
+#define NeedBits8(n,eoflab) do { \
+ if (BitsAvail < (n)) { \
+ if (EndOfData()) goto eoflab; \
+ BitAcc |= bitmap[*cp++]<<BitsAvail; \
+ BitsAvail += 8; \
+ } \
+} while (0)
+#endif
+#ifndef NeedBits16
+#define NeedBits16(n,eoflab) do { \
+ if (BitsAvail < (n)) { \
+ if (EndOfData()) goto eoflab; \
+ BitAcc |= bitmap[*cp++]<<BitsAvail; \
+ if ((BitsAvail += 8) < (n)) { \
+ if (EndOfData()) goto eoflab; \
+ BitAcc |= bitmap[*cp++]<<BitsAvail; \
+ BitsAvail += 8; \
+ } \
+ } \
+} while (0)
+#endif
+#define GetBits(n) (BitAcc & ((1<<(n))-1))
+#define ClrBits(n) do { \
+ BitsAvail -= (n); \
+ BitAcc >>= (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(11); \
+ } \
+ } \
+ 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) { \
+ /* 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..a52419f8
--- /dev/null
+++ b/libtiff/tif_flush.c
@@ -0,0 +1,60 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_flush.c,v 1.21 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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..57e6b84c
--- /dev/null
+++ b/libtiff/tif_getimage.c
@@ -0,0 +1,1806 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_getimage.c,v 1.38 1995/07/17 01:27:18 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Read and return a packed RGBA image.
+ */
+#include "tiffiop.h"
+#include <assert.h>
+#include <stdio.h>
+
+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
+ 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;
+ 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_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. */
+ { 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);
+ }
+ 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;
+ u_int 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;
+ u_int 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;
+ u_int 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<<SHIFT) + 0.5))
+#define ONE_HALF ((int32)(1<<(SHIFT-1)))
+
+/*
+ * Initialize the YCbCr->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<<img->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<<img->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<<img->bitspersample)-1; i >= 0; i--) {
+#define CVT(x) ((uint16)(((x) * 255) / ((1L<<16)-1)))
+ 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..f88a13a3
--- /dev/null
+++ b/libtiff/tif_jpeg.c
@@ -0,0 +1,1480 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_jpeg.c,v 1.23 1995/06/30 15:29:02 sam Exp $ */
+
+/*
+ * Copyright (c) 1994-1995 Sam Leffler
+ * Copyright (c) 1994-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.
+ */
+
+#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 <tgl@sss.pgh.pa.us>.
+ */
+#include <assert.h>
+#include <stdio.h>
+#include <setjmp.h>
+#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)
+#define FIELD_JPEGQUALITY (FIELD_CODEC+1)
+#define FIELD_JPEGCOLORMODE (FIELD_CODEC+2)
+#define FIELD_JPEGTABLESMODE (FIELD_CODEC+3)
+
+static const TIFFFieldInfo jpegFieldInfo[] = {
+ { TIFFTAG_JPEGTABLES, -1,-1, TIFF_UNDEFINED, FIELD_JPEGTABLES,
+ FALSE, TRUE, "JPEGTables" },
+ { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, FIELD_JPEGQUALITY,
+ TRUE, FALSE, "" },
+ { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, FIELD_JPEGCOLORMODE,
+ FALSE, FALSE, "" },
+ { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, FIELD_JPEGTABLESMODE,
+ 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 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 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 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_lzw.c b/libtiff/tif_lzw.c
new file mode 100644
index 00000000..23e32cdd
--- /dev/null
+++ b/libtiff/tif_lzw.c
@@ -0,0 +1,1018 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_lzw.c,v 1.69 1995/07/19 00:39:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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 <assert.h>
+#include <stdio.h>
+
+/*
+ * 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 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 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 {
+#ifndef _WINDOWS
+ if ((hp -= disp) < sp->enc_hashtab)
+ hp += HSIZE;
+#else
+ /*
+ * Avoid pointer arithmetic 'cuz of
+ * wraparound problems with segments.
+ */
+ if ((h -= disp) < 0)
+ h += HSIZE;
+ hp = &sp->enc_hashtab[h];
+#endif
+ 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..faa99231
--- /dev/null
+++ b/libtiff/tif_msdos.c
@@ -0,0 +1,179 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_msdos.c,v 1.13 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library MSDOS-specific Routines.
+ */
+#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER)
+#include <io.h> /* for open, close, etc. function prototypes */
+#include <stdio.h>
+#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 <sys/stat.h>
+
+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 <malloc.h>
+#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..9f0732d9
--- /dev/null
+++ b/libtiff/tif_next.c
@@ -0,0 +1,142 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_next.c,v 1.26 1995/06/30 15:29:02 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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 <color><npixels>
+ * 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..8baa9cc1
--- /dev/null
+++ b/libtiff/tif_open.c
@@ -0,0 +1,399 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_open.c,v 1.58 1995/07/17 01:27:01 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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 bit fill order, the
+ * shift & mask tables, and the byte
+ * swapping state according to the file
+ * contents and the machine architecture.
+ */
+static void
+TIFFInitOrder(register TIFF* tif, int magic, int bigendian)
+{
+#ifdef notdef
+ /*
+ * NB: too many applications assume that data is returned
+ * by the library in MSB2LSB bit order to change the
+ * default bit order to reflect the native cpu. This
+ * may change in the future in which case applications
+ * will need to check the value of the FillOrder tag.
+ */
+ tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | HOST_FILLORDER;
+#else
+ tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | FILLORDER_MSB2LSB;
+#endif
+
+ 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;
+
+ 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;
+
+ { union { int i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; }
+#ifdef ENDIANHACK_SUPPORT
+ /*
+ * Numerous vendors, typically on the PC, do not correctly
+ * support TIFF; they only support the Intel little-endian
+ * byte order. If this hack is enabled, then applications
+ * can open a file with a specific byte-order by specifying
+ * either "wl" (for litt-endian byte order) or "wb" for
+ * (big-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.
+ */
+ if ((m&O_CREAT) &&
+ ((bigendian && mode[1] == 'l') || (!bigendian && mode[1] == 'b')))
+ tif->tif_flags |= TIFF_SWAB;
+#endif
+ /*
+ * 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;
+ 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;
+ if (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..a24ec6ef
--- /dev/null
+++ b/libtiff/tif_packbits.c
@@ -0,0 +1,262 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_packbits.c,v 1.47 1995/06/30 15:29:02 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#include "tiffiop.h"
+#ifdef PACKBITS_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * PackBits Compression Algorithm Support
+ */
+#include <assert.h>
+#include <stdio.h>
+
+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;
+
+ (void) s;
+ bp = (char*) tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ while (cc > 0 && (long)occ > 0) {
+ long n;
+ int b;
+
+ 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 */
+ cc--;
+ if (n == -128) /* nop */
+ continue;
+ n = -n + 1;
+ occ -= n;
+ for (b = *bp++; 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_predict.c b/libtiff/tif_predict.c
new file mode 100644
index 00000000..3dcfbb53
--- /dev/null
+++ b/libtiff/tif_predict.c
@@ -0,0 +1,468 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_predict.c,v 1.3 1995/07/01 00:12:45 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Predictor Tag Support (used by multiple codecs).
+ */
+#include "tiffiop.h"
+#include "tif_predict.h"
+
+#include <assert.h>
+
+#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: ; \
+ }
+#define XREPEAT4(n, op) \
+ switch (n) { \
+ default: { int i; for (i = n-4; i > 0; i--) { 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 {
+ XREPEAT4(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..b7be1d6d
--- /dev/null
+++ b/libtiff/tif_predict.h
@@ -0,0 +1,61 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_predict.h,v 1.1 1995/06/29 17:20:19 sam 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.
+ */
+
+#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..5bbbb061
--- /dev/null
+++ b/libtiff/tif_print.c
@@ -0,0 +1,491 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_print.c,v 1.64 1995/07/19 00:39:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Printing Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+
+#include <ctype.h>
+
+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%x\n", 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, " (%u = 0x%x)\n",
+ td->td_subfiletype, 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)) {
+ fprintf(fd, " Compression Scheme: ");
+ switch (td->td_compression) {
+ case COMPRESSION_NONE:
+ fprintf(fd, "none\n");
+ break;
+ case COMPRESSION_CCITTRLE:
+ fprintf(fd, "CCITT modified Huffman encoding\n");
+ break;
+ case COMPRESSION_CCITTFAX3:
+ fprintf(fd, "CCITT Group 3 facsimile encoding\n");
+ break;
+ case COMPRESSION_CCITTFAX4:
+ fprintf(fd, "CCITT Group 4 facsimile encoding\n");
+ break;
+ case COMPRESSION_CCITTRLEW:
+ fprintf(fd, "CCITT modified Huffman encoding %s\n",
+ "w/ word alignment");
+ break;
+ case COMPRESSION_PACKBITS:
+ fprintf(fd, "Macintosh PackBits encoding\n");
+ break;
+ case COMPRESSION_THUNDERSCAN:
+ fprintf(fd, "ThunderScan 4-bit encoding\n");
+ break;
+ case COMPRESSION_LZW:
+ fprintf(fd, "Lempel-Ziv & Welch encoding\n");
+ break;
+ case COMPRESSION_NEXT:
+ fprintf(fd, "NeXT 2-bit encoding\n");
+ break;
+ case COMPRESSION_OJPEG:
+ fprintf(fd, "Old-style JPEG encoding\n");
+ break;
+ case COMPRESSION_JPEG:
+ fprintf(fd, "JPEG encoding\n");
+ break;
+ case COMPRESSION_JBIG:
+ fprintf(fd, "JBIG encoding\n");
+ break;
+ case COMPRESSION_DEFLATE:
+ fprintf(fd, "Deflate encoding (experimental)\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_compression, td->td_compression);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
+ fprintf(fd, " Photometric Interpretation: ");
+ if (td->td_photometric < NPHOTONAMES)
+ fprintf(fd, "%s\n", photoNames[td->td_photometric]);
+ else
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_photometric, td->td_photometric);
+ }
+ 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");
+ }
+#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')) {
+ fprintf(fd, "%s", sep);
+ _TIFFprintAscii(fd, cp);
+ sep = ", ";
+ }
+ }
+ 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->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->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
+#if SUBIFD_SUPPORT
+ if (TIFFFieldSet(tif, FIELD_SUBIFD)) {
+ fprintf(fd, " SubIFD Offsets:");
+ for (i = 0; i < td->td_nsubifd; i++)
+ fprintf(fd, " %5u", 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, " %u %s:\n",
+ 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..ca6bf899
--- /dev/null
+++ b/libtiff/tif_read.c
@@ -0,0 +1,600 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_read.c,v 1.69 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ * Scanline-oriented Read Support
+ */
+#include "tiffiop.h"
+#include <stdio.h>
+#include <assert.h>
+
+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 ? 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)) {
+ 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);
+ }
+ if (!ReadOK(tif, buf, size)) {
+ TIFFError(module, "%s: Read error at scanline %lu",
+ tif->tif_name, (u_long) tif->tif_row);
+ return (-1);
+ }
+ } else {
+ if (td->td_stripoffset[strip] + size > tif->tif_size) {
+ TIFFError(module,
+ "%s: Seek error at scanline %lu, strip %lu",
+ tif->tif_name,
+ (u_long) tif->tif_row, (u_long) strip);
+ 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",
+ tif->tif_name, (u_long) strip);
+ 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)) {
+ 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);
+ }
+ if (!ReadOK(tif, buf, size)) {
+ TIFFError(module, "%s: Read error at row %ld, col %ld",
+ tif->tif_name,
+ (long) tif->tif_row,
+ (long) tif->tif_col);
+ return ((tsize_t) -1);
+ }
+ } else {
+ if (td->td_stripoffset[tile] + size > tif->tif_size) {
+ 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);
+ }
+ _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..33389486
--- /dev/null
+++ b/libtiff/tif_strip.c
@@ -0,0 +1,190 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_strip.c,v 1.23 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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);
+ }
+ 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..c9a83197
--- /dev/null
+++ b/libtiff/tif_swab.c
@@ -0,0 +1,217 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_swab.c,v 1.21 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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[<byte>] gives
+ * the bit reversed value of <byte>. 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..2c6f76b9
--- /dev/null
+++ b/libtiff/tif_thunder.c
@@ -0,0 +1,154 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_thunder.c,v 1.28 1995/06/30 15:29:02 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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..40224c0d
--- /dev/null
+++ b/libtiff/tif_tile.c
@@ -0,0 +1,213 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_tile.c,v 1.24 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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.
+ */
+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;
+}
diff --git a/libtiff/tif_unix.c b/libtiff/tif_unix.c
new file mode 100644
index 00000000..5c4a9010
--- /dev/null
+++ b/libtiff/tif_unix.c
@@ -0,0 +1,209 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_unix.c,v 1.15 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library UNIX-specific Routines.
+ */
+#include "tiffiop.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+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 <sys/stat.h>
+
+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 <sys/mman.h>
+
+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..7ef0b764
--- /dev/null
+++ b/libtiff/tif_version.c
@@ -0,0 +1,34 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_version.c,v 1.15 1995/06/06 23:49:31 sam Exp $ */
+/*
+ * Copyright (c) 1992-1995 Sam Leffler
+ * Copyright (c) 1992-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.
+ */
+#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..79ff8bee
--- /dev/null
+++ b/libtiff/tif_vms.c
@@ -0,0 +1,583 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_vms.c,v 1.19 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library VMS-specific Routines.
+ */
+
+#include <stdlib.h>
+#include <unixio.h>
+#include "tiffiop.h"
+#if !HAVE_IEEEFP
+#include <math.h>
+#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 <sys/stat.h>
+
+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 <starlet.h>
+#include <fab.h>
+#include <secdef.h>
+
+/*
+ * 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 void* 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 mant : 20,
+ exp : 11,
+ sign : 1;
+ u_long mant2;
+} ieeedouble;
+typedef struct ieeefloat {
+ u_long mant : 23,
+ exp : 8,
+ sign : 1;
+} ieeefloat;
+
+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.d = *dp;
+ 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 += 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;
+ }
+ *dp = num.d;
+}
+
+/*
+ * 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, float* f)
+{
+ float_t* fp = (float_t*) f;
+
+ while (n-- > 0) {
+ IEEEDOUBLE2NATIVE(fp);
+ fp++;
+ }
+}
+
+void
+TIFFCvtNativeToIEEEDouble(TIFF* tif, u_int n, float* f)
+{
+ float_t* fp = (float_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..0fb055bd
--- /dev/null
+++ b/libtiff/tif_warning.c
@@ -0,0 +1,49 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_warning.c,v 1.20 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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..fe139079
--- /dev/null
+++ b/libtiff/tif_win3.c
@@ -0,0 +1,225 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_win3.c,v 1.5 1995/06/06 23:49:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library Windows 3.x-specific Routines.
+ */
+#include "tiffiop.h"
+#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_MSC_VER)
+#include <io.h> /* for open, close, etc. function prototypes */
+#endif
+
+#include <windows.h>
+#include <windowsx.h>
+#include <memory.h>
+
+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 <sys/stat.h>
+
+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;
+ 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_write.c b/libtiff/tif_write.c
new file mode 100644
index 00000000..439348f3
--- /dev/null
+++ b/libtiff/tif_write.c
@@ -0,0 +1,592 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_write.c,v 1.70 1995/07/18 17:55:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Scanline-oriented Write Support
+ */
+#include "tiffiop.h"
+#include <assert.h>
+#include <stdio.h>
+
+#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; this
+ * interface does not support automatically growing
+ * the image on each write (as TIFFWriteScanline does).
+ */
+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);
+ if (strip >= td->td_nstrips) {
+ TIFFError(module, "%s: Strip %lu out of range, max %lu",
+ tif->tif_name, (u_long) strip, (u_long) td->td_nstrips);
+ return ((tsize_t) -1);
+ }
+ /*
+ * 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 (-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 (-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
+TIFFWriteRawStrip(TIFF* tif, tstrip_t strip, tdata_t data, tsize_t cc)
+{
+ static const char module[] = "TIFFWriteRawStrip";
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return ((tsize_t) -1);
+ if (strip >= tif->tif_dir.td_nstrips) {
+ TIFFError(module, "%s: Strip %lu out of range, max %lu",
+ tif->tif_name, (u_long) strip,
+ (u_long) tif->tif_dir.td_nstrips);
+ return ((tsize_t) -1);
+ }
+ 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(td, v) \
+ (td->v == (uint32) -1 || (td)->td_imagelength == 0)
+
+static int
+TIFFSetupStrips(TIFF* tif)
+{
+ TIFFDirectory* td = &tif->tif_dir;
+
+ if (isTiled(tif))
+ td->td_stripsperimage = isUnspecified(td, td_tilelength) ?
+ td->td_samplesperpixel : TIFFNumberOfTiles(tif);
+ else
+ td->td_stripsperimage = isUnspecified(td, td_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..42f7b300
--- /dev/null
+++ b/libtiff/tif_zip.c
@@ -0,0 +1,286 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_zip.c,v 1.4 1995/07/17 14:38:12 sam 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.
+ */
+
+#include "tiffiop.h"
+#ifdef ZIP_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ZIP (i.e. Deflate) Compression Support
+ *
+ * This file is simply an interface to the libgz library written by
+ * Jean-loup Gailly and Mark Adler. Use version 0.92 or later of
+ * the library. 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/graphics/png/code/zlib-0.93.tar.gz.
+ */
+#include "tif_predict.h"
+#include "zlib.h"
+#include "zutil.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+/*
+ * State block for each open TIFF
+ * file using ZIP compression/decompression.
+ */
+typedef struct {
+ TIFFPredictorState predict;
+ z_stream stream;
+} ZIPState;
+
+#define DecoderState(tif) ((ZIPState*) (tif)->tif_data)
+#define EncoderState(tif) ((ZIPState*) (tif)->tif_data)
+
+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 char module[] = "ZIPSetupDecode";
+
+ assert(sp != NULL);
+ if (inflateInit2(&sp->stream, -DEF_WBITS) != Z_OK) {
+ TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg);
+ return (0);
+ } else
+ 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 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: libgz 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 char module[] = "ZIPSetupEncode";
+
+ assert(sp != NULL);
+ /*
+ * We use the undocumented feature of a negiatve window
+ * bits to suppress writing the header in the output
+ * stream. This is necessary when the resulting image
+ * is made up of multiple strips or tiles as otherwise
+ * libgz will not write a header for each strip/tile and
+ * the decoder will fail.
+ */
+ if (deflateInit2(&sp->stream, Z_DEFAULT_COMPRESSION,
+ DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0) != Z_OK) {
+ TIFFError(module, "%s: %s", tif->tif_name, sp->stream.msg);
+ return (0);
+ } else
+ 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 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 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: libgz error: %s",
+ tif->tif_name, sp->stream.msg);
+ return (0);
+ }
+ } while (state != Z_STREAM_END);
+ return (1);
+}
+
+static void
+ZIPCleanup(TIFF* tif)
+{
+ ZIPState* sp = (ZIPState*) tif->tif_data;
+ if (sp) {
+ if (tif->tif_mode == O_RDONLY)
+ inflateEnd(&sp->stream);
+ else
+ deflateEnd(&sp->stream);
+ _TIFFfree(sp);
+ tif->tif_data = NULL;
+ }
+}
+
+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 = (ZIPState*) tif->tif_data;
+ sp->stream.zalloc = NULL;
+ sp->stream.zfree = NULL;
+ sp->stream.opaque = NULL;
+ sp->stream.data_type = Z_BINARY;
+
+ /*
+ * 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..2ca4c341
--- /dev/null
+++ b/libtiff/tiff.h
@@ -0,0 +1,331 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tiff.h,v 1.58 1995/06/30 21:08:31 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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
+
+/*
+ * Intrinsic data types required by the file format:
+ *
+ * 8-bit quantities char/unsigned char
+ * 16-bit quantities int16/uint16
+ * 32-bit quantities int32/uint32
+ * strings unsigned char*
+ */
+typedef short int16;
+typedef unsigned short uint16; /* sizeof (uint16) must == 2 */
+#if defined(__alpha) || _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
+
+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 */
+/* compression codes 32908-32911 are reserved for Pixar */
+#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
+#define COMPRESSION_DEFLATE 32946 /* Deflate compression */
+#define COMPRESSION_JBIG 34661 /* ISO JBIG */
+#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 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_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 33432 is listed in the 6.0 spec w/ unknown ownership */
+#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
+/* tag 34750 is a private tag registered to Pixel Magic */
+#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
+
+/*
+ * 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 */
+#endif /* _TIFF_ */
diff --git a/libtiff/tiffcomp.h b/libtiff/tiffcomp.h
new file mode 100644
index 00000000..45b8a6e8
--- /dev/null
+++ b/libtiff/tiffcomp.h
@@ -0,0 +1,149 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tiffcomp.h,v 1.44 1995/06/06 17:00:43 sam Exp $ */
+
+/*
+ * Copyright (c) 1990-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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.
+ */
+#if defined(__MWERKS__) || defined(THINK_C)
+#include <unix.h>
+#include <math.h>
+#endif
+#include <stdio.h>
+#ifdef applec
+#include <types.h>
+#else
+#if !defined(__MWERKS__) && !defined(THINK_C)
+#include <sys/types.h>
+#endif
+#endif
+#ifdef VMS
+#include <file.h>
+#include <unixio.h>
+#else
+#include <fcntl.h>
+#endif
+#if defined(__MWERKS__) || defined(THINK_C) || defined(applec)
+#include <stdlib.h>
+#define BSDTYPES
+#endif
+#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
+#define BSDTYPES
+#endif
+#if defined(OS2_16) || defined(OS2_32)
+#define BSDTYPES
+#endif
+
+/*
+ * The library uses the ANSI C/POSIX SEEK_*
+ * definitions that should be defined in unistd.h
+ * (except on VMS or the Mac, 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 <unistd.h>
+#endif
+#endif
+
+/*
+ * The library uses memset, memcpy, and memcmp.
+ * ANSI C and System V define these in string.h.
+ */
+#include <string.h>
+
+/*
+ * The BSD typedefs are used throughout the library.
+ * If your system doesn't have them in <sys/types.h>,
+ * then define BSDTYPES in your Makefile.
+ */
+#ifdef 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).
+ */
+#ifdef applec
+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.
+ */
+#ifdef __GNUC__
+#ifdef __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)
+#ifdef VAXC
+#define GLOBALDATA(TYPE,NAME) extern noshare TYPE NAME
+#endif
+#ifdef __GNUC__
+#define GLOBALDATA(TYPE,NAME) extern TYPE NAME \
+ asm("_$$PsectAttributes_NOSHR$$" #NAME)
+#endif
+#else /* !VAX/VMS */
+#define GLOBALDATA(TYPE,NAME) extern TYPE NAME
+#endif
+#endif /* _COMPAT_ */
diff --git a/libtiff/tiffconf.h b/libtiff/tiffconf.h
new file mode 100644
index 00000000..c87ee128
--- /dev/null
+++ b/libtiff/tiffconf.h
@@ -0,0 +1,127 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tiffconf.h,v 1.11 1995/06/30 15:29:02 sam Exp $ */
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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
+ */
+#define COLORIMETRY_SUPPORT
+#define YCBCR_SUPPORT
+#define CMYK_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)
+ */
+#define CCITT_SUPPORT
+#define PACKBITS_SUPPORT
+#define LZW_SUPPORT
+#define THUNDER_SUPPORT
+#define NEXT_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_SUPPORT automatically convert single-strip uncompressed images
+ * to mutiple strips of ~8Kb (for reducing memory use)
+ * SUBIFD_SUPPORT enable support for SubIFD tag (thumbnails and such)
+ */
+#ifndef STRIPCHOP_SUPPORT
+#define STRIPCHOP_SUPPORT 1 /* enable strip chopping */
+#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..84668660
--- /dev/null
+++ b/libtiff/tiffio.h
@@ -0,0 +1,298 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tiffio.h,v 1.90 1995/06/27 00:54:10 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#ifndef _TIFFIO_
+#define _TIFFIO_
+
+/*
+ * TIFF I/O Library Definitions.
+ */
+#include "tiff.h"
+
+/*
+ * 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
+ * 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 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 */
+#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
+#include <windows.h>
+typedef HFILE thandle_t; /* client data handle */
+#else
+typedef void* thandle_t; /* client data handle */
+#endif
+typedef void* tdata_t; /* image data ref */
+typedef int32 toff_t; /* file offset */
+
+#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 <stdio.h>
+#include <stdarg.h>
+
+#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 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..af0ef954
--- /dev/null
+++ b/libtiff/tiffiop.h
@@ -0,0 +1,264 @@
+/* $Header: /usr/people/sam/tiff/libtiff/RCS/tiffiop.h,v 1.73 1995/07/07 02:30:23 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+#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 */
+ 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 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 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
+extern TIFFCodec _TIFFBuiltinCODECS[];
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFIOP_ */
diff --git a/man/Makefile.in b/man/Makefile.in
new file mode 100644
index 00000000..c1dbf473
--- /dev/null
+++ b/man/Makefile.in
@@ -0,0 +1,206 @@
+# $Header: /usr/people/sam/tiff/man/RCS/Makefile.in,v 1.4 1995/06/28 04:40:37 sam Exp $
+#
+# @WARNING@
+#
+# Tag Image File Format Library Manual Pages
+#
+# Copyright (c) 1991-1995 Sam Leffler
+# Copyright (c) 1991-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 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@/man
+VPATH = ../@SRCDIR@/man
+
+PORT = ${DEPTH}/port
+
+#
+# VERSION: @VERSION@
+# DATE: @DATE@
+# TARGET: @TARGET@
+# CCOMPILER: @CCOMPILER@
+#
+SHELL = /bin/sh
+NULL =
+ECHO = echo
+MV = mv
+RM = rm -f
+INSTALL = @INSTALL@
+
+MAN = @DIR_MAN@
+
+MANTOOLS=\
+ fax2tiff.1 \
+ fax2ps.1 \
+ gif2tiff.1 \
+ pal2rgb.1 \
+ ppm2tiff.1 \
+ ras2tiff.1 \
+ rgb2ycbcr.1 \
+ sgi2tiff.1 \
+ thumbnail.1 \
+ tiff2bw.1 \
+ tiff2ps.1 \
+ tiffcmp.1 \
+ tiffcp.1 \
+ tiffdither.1 \
+ tiffdump.1 \
+ tiffgt.1 \
+ tiffinfo.1 \
+ tiffmedian.1 \
+ tiffsplit.1 \
+ tiffsv.1 \
+ ${NULL}
+MANDEVLINKS=\
+ TIFFComputeTile.3t \
+ TIFFCheckTile.3t \
+ TIFFNumberOfTiles.3t \
+ TIFFComputeStrip.3t \
+ TIFFNumberOfStrips.3t \
+ TIFFCurrentDirectory.3t \
+ TIFFCurrentRow.3t \
+ TIFFCurrentStrip.3t \
+ TIFFCurrentTile.3t \
+ TIFFFdOpen.3t \
+ TIFFFileName.3t \
+ TIFFFileno.3t \
+ TIFFFlushData.3t \
+ TIFFGetMode.3t \
+ TIFFIsTiled.3t \
+ TIFFReverseBits.3t \
+ TIFFSetErrorHandler.3t \
+ TIFFSetWarningHandler.3t \
+ TIFFSwabArrayOfLong.3t \
+ TIFFSwabArrayOfShort.3t \
+ TIFFSwabLong.3t \
+ TIFFSwabShort.3t \
+ TIFFScanlineSize.3t \
+ TIFFStripSize.3t \
+ TIFFTileSize.3t \
+ TIFFVGetField.3t \
+ TIFFVSetField.3t \
+ ${NULL}
+MANDEV=\
+ TIFFClose.3t \
+ TIFFError.3t \
+ TIFFFlush.3t \
+ TIFFGetField.3t \
+ TIFFOpen.3t \
+ TIFFPrintDirectory.3t \
+ TIFFReadDirectory.3t \
+ TIFFReadEncodedStrip.3t \
+ TIFFReadEncodedTile.3t \
+ TIFFReadRGBAImage.3t \
+ TIFFReadRawStrip.3t \
+ TIFFReadRawTile.3t \
+ TIFFReadScanline.3t \
+ TIFFReadTile.3t \
+ TIFFSetDirectory.3t \
+ TIFFSetField.3t \
+ TIFFWarning.3t \
+ TIFFWriteDirectory.3t \
+ TIFFWriteEncodedStrip.3t \
+ TIFFWriteEncodedTile.3t \
+ TIFFWriteRawStrip.3t \
+ TIFFWriteRawTile.3t \
+ TIFFWriteScanline.3t \
+ intro.3t \
+ query.3t \
+ size.3t \
+ strip.3t \
+ swab.3t \
+ tile.3t \
+ ${NULL}
+TARGETS = ${MANTOOLS} ${MANDEV} ${MANDEVLINKS}
+
+all: ${TARGETS}
+
+install: all
+ ${INSTALL} -m 755 -dir -idb tiff.man.tools ${MAN}
+ ${INSTALL} -m 755 -dir -idb tiff.man.tools ${MAN}/man1
+ for i in ${MANTOOLS}; do \
+ ${INSTALL} -idb tiff.man.tools -m 444 -F ${MAN}/man1 \
+ -src ${SRCDIR}/$$i -O $$i; \
+ done
+ ${INSTALL} -m 755 -dir -idb tiff.man.dev ${MAN}/man3
+ for i in ${MANDEV}; do \
+ ${INSTALL} -idb tiff.man.dev -m 444 -F ${MAN}/man3 \
+ -src ${SRCDIR}/$$i -O $$i; \
+ done
+ ${INSTALL} -idb tiff.man.dev -m 444 -F ${MAN}/man3 -O ${MANDEVLINKS}
+
+clean:
+ ${RM} ${MANDEVLINKS}
+
+TIFFComputeTile.3t:; ${ECHO} ".so tile.3t" > $@
+TIFFCheckTile.3t:; ${ECHO} ".so tile.3t" > $@
+TIFFNumberOfTiles.3t:; ${ECHO} ".so tile.3t" > $@
+TIFFComputeStrip.3t:; ${ECHO} ".so strip.3t" > $@
+TIFFNumberOfStrips.3t:; ${ECHO} ".so strip.3t" > $@
+TIFFCurrentDirectory.3t:; ${ECHO} ".so query.3t" > $@
+TIFFCurrentRow.3t:; ${ECHO} ".so query.3t" > $@
+TIFFCurrentStrip.3t:; ${ECHO} ".so query.3t" > $@
+TIFFCurrentTile.3t:; ${ECHO} ".so query.3t" > $@
+TIFFFdOpen.3t:; ${ECHO} ".so TIFFOpen.3t" > $@
+TIFFFileName.3t:; ${ECHO} ".so query.3t" > $@
+TIFFFileno.3t:; ${ECHO} ".so query.3t" > $@
+TIFFFlushData.3t:; ${ECHO} ".so TIFFFlush.3t" > $@
+TIFFGetMode.3t:; ${ECHO} ".so query.3t" > $@
+TIFFIsTiled.3t:; ${ECHO} ".so query.3t" > $@
+TIFFReverseBits.3t:; ${ECHO} ".so swab.3t" > $@
+TIFFSetErrorHandler.3t:; ${ECHO} ".so TIFFError.3t" > $@
+TIFFSetWarningHandler.3t:; ${ECHO} ".so TIFFWarning.3t" > $@
+TIFFSwabArrayOfLong.3t:; ${ECHO} ".so swab.3t" > $@
+TIFFSwabArrayOfShort.3t:; ${ECHO} ".so swab.3t" > $@
+TIFFSwabLong.3t:; ${ECHO} ".so swab.3t" > $@
+TIFFSwabShort.3t:; ${ECHO} ".so swab.3t" > $@
+TIFFScanlineSize.3t:; ${ECHO} ".so size.3t" > $@
+TIFFStripSize.3t:; ${ECHO} ".so size.3t" > $@
+TIFFTileSize.3t:; ${ECHO} ".so size.3t" > $@
+TIFFVGetField.3t:; ${ECHO} ".so TIFFGetField.3t" > $@
+TIFFVSetField.3t:; ${ECHO} ".so TIFFSetField.3t" > $@
+
+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} TIFFReadScanline.3t readline.3t
+ ${MV} TIFFReadTile.3t readtile.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
diff --git a/man/TIFFClose.3t b/man/TIFFClose.3t
new file mode 100644
index 00000000..cda9983b
--- /dev/null
+++ b/man/TIFFClose.3t
@@ -0,0 +1,51 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFClose.3t,v 1.9 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFClose 3T "May 2, 1990"
+.SH NAME
+TIFFClose \- close a previously opened
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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 intro (3T),
+.IR TIFFOpen (3T)
diff --git a/man/TIFFError.3t b/man/TIFFError.3t
new file mode 100644
index 00000000..7c1a78c7
--- /dev/null
+++ b/man/TIFFError.3t
@@ -0,0 +1,69 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFError.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFError 3T "December 2, 1991"
+.SH NAME
+TIFFError, TIFFSetErrorHandler \- library error handling interface
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "void TIFFError(const char* module, const char* fmt, ...)"
+.sp .5
+.B "#include <stdargh.h>"
+.br
+.B "typedef void (*TIFFErrorHandler)(char* module, 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 intro (3T),
+.IR TIFFWarning (3T),
+.IR printf (3S)
diff --git a/man/TIFFFlush.3t b/man/TIFFFlush.3t
new file mode 100644
index 00000000..210391c3
--- /dev/null
+++ b/man/TIFFFlush.3t
@@ -0,0 +1,64 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFFlush.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (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..4725cc88
--- /dev/null
+++ b/man/TIFFGetField.3t
@@ -0,0 +1,196 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFGetField.3t,v 1.13 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFGetField 3T "February 14, 1992"
+.SH NAME
+TIFFGetField, TIFFVGetField \- get the value(s) of a tag in an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "int TIFFGetField(TIFF* tif, ttag_t tag, ...)"
+.sp 5p
+.B "#include <stdarg.h>"
+.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 in the current directory associated with
+the open
+.SM TIFF
+file
+.IR tif .
+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 (\c
+or, on some machines, the
+.IR varargs (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'uint16*,uint16**'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<<BitsPerSample arrays
+TIFFTAG_COMPRESSION 1 uint16*
+TIFFTAG_CONSECUTIVEBADFAXLINES 1 uint32*
+TIFFTAG_DATATYPE 1 uint16*
+TIFFTAG_DATETIME 1 char**
+TIFFTAG_DOCUMENTNAME 1 char**
+TIFFTAG_DOTRANGE 2 uint16*
+TIFFTAG_EXTRASAMPLES 2 uint16*,uint16** count & types array
+TIFFTAG_FILLORDER 1 uint16*
+TIFFTAG_GROUP3OPTIONS 1 uint32*
+TIFFTAG_GROUP4OPTIONS 1 uint32*
+TIFFTAG_HALFTONEHINTS 2 uint16*
+TIFFTAG_HOSTCOMPUTER 1 char**
+TIFFTAG_IMAGEDEPTH 1 uint32*
+TIFFTAG_IMAGEDESCRIPTION 1 char**
+TIFFTAG_IMAGELENGTH 1 uint32*
+TIFFTAG_IMAGEWIDTH 1 uint32*
+TIFFTAG_INKNAMES 1 char**
+TIFFTAG_INKSET 1 uint16*
+TIFFTAG_JPEGACTABLES 1 u_char*** SamplesPerPixel arrays
+TIFFTAG_JPEGDCTABLES 1 u_char*** SamplesPerPixel arrays
+TIFFTAG_JPEGPROC 1 uint16*
+TIFFTAG_JPEGRESTARTINTERVAL 1 uint16*
+TIFFTAG_JPEGQTABLES 1 u_char*** SamplesPerPixel 64-entry arrays
+TIFFTAG_MAKE 1 char**
+TIFFTAG_MATTEING 1 uint16*
+TIFFTAG_MAXSAMPLEVALUE 1 uint16*
+TIFFTAG_MINSAMPLEVALUE 1 uint16*
+TIFFTAG_MODEL 1 char**
+TIFFTAG_ORIENTATION 1 uint16*
+TIFFTAG_PAGENAME 1 char**
+TIFFTAG_PAGENUMBER 2 uint16*
+TIFFTAG_PHOTOMETRIC 1 uint16*
+TIFFTAG_PLANARCONFIG 1 uint16*
+TIFFTAG_PREDICTOR 1 uint16*
+TIFFTAG_PRIMARYCHROMATICITIES 1 float** 6-entry array
+TIFFTAG_REFERENCEBLACKWHITE 1 float** 2*SamplesPerPixel array
+TIFFTAG_RESOLUTIONUNIT 1 uint16*
+TIFFTAG_ROWSPERSTRIP 1 uint32*
+TIFFTAG_SAMPLEFORMAT 1 uint16*
+TIFFTAG_SAMPLESPERPIXEL 1 uint16*
+TIFFTAG_SOFTWARE 1 char**
+TIFFTAG_STRIPBYTECOUNTS 1 uint32**
+TIFFTAG_STRIPOFFSETS 1 uint32**
+TIFFTAG_SUBFILETYPE 1 uint32*
+TIFFTAG_TARGETPRINTER 1 char**
+TIFFTAG_THRESHHOLDING 1 uint16*
+TIFFTAG_TILEBYTECOUNTS 1 uint32**
+TIFFTAG_TILEDEPTH 1 uint32*
+TIFFTAG_TILELENGTH 1 uint32*
+TIFFTAG_TILEOFFSETS 1 uint32**
+TIFFTAG_TILEWIDTH 1 uint32*
+TIFFTAG_TRANSFERFUNCTION 1 or 3\(dg uint16** 1<<BitsPerSample entry arrays
+TIFFTAG_WHITEPOINT 1 float** 2-entry array
+TIFFTAG_XPOSITION 1 float*
+TIFFTAG_XRESOLUTION 1 float*
+TIFFTAG_YCBCRCOEFFICIENTS 1 float** 3-entry array
+TIFFTAG_YCBCRPOSITIONING 1 uint16*
+TIFFTAG_YCBCRSUBSAMPLING 2 uint16*
+TIFFTAG_YPOSITION 1 float*
+TIFFTAG_YRESOLUTION 1 float*
+.fi
+(\(dg If
+.I SamplesPerPixel
+is one, then a single array is returned; otherwise three arrays are
+returned.)
+.SH "RETURN VALUES"
+1 is returned if the tag is defined in the current
+directory; otherwise a 0 is returned.
+.SH DIAGNOSTICS
+All error messages are directed to the
+.IR TIFFError (3T)
+routine.
+.PP
+.BR "Unknown field, tag 0x%x" .
+An unknown tag was supplied.
+.SH "SEE ALSO"
+.IR intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFSetField (3T),
+.IR TIFFSetDirectory (3T),
+.IR TIFFReadDirectory (3T),
+.IR TIFFWriteDirectory (3T)
diff --git a/man/TIFFOpen.3t b/man/TIFFOpen.3t
new file mode 100644
index 00000000..9606b00e
--- /dev/null
+++ b/man/TIFFOpen.3t
@@ -0,0 +1,189 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFOpen.3t,v 1.11 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFOpen 3T "February 14, 1992"
+.SH NAME
+TIFFOpen, TIFFFdOpen, TIFFClientOpen \- open a
+.SM TIFF
+file for reading or writing
+.SH SYNOPSIS
+.nf
+.B "#include <tiffio.h>"
+.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'').
+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
+It is not possible to append data to a file that has a
+byte ordering opposite to the native byte ordering of a machine.
+That is, for example, the library will not allow
+a file with little-endian byte ordering to be appended to
+on a machine that has a native big-endian byte ordering.
+.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 "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 intro (3T),
+.IR TIFFClose (3T)
diff --git a/man/TIFFPrintDirectory.3t b/man/TIFFPrintDirectory.3t
new file mode 100644
index 00000000..395a7fbb
--- /dev/null
+++ b/man/TIFFPrintDirectory.3t
@@ -0,0 +1,71 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFPrintDirectory.3t,v 1.5 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFReadDirectory (3T),
+.IR TIFFSetDirectory (3T)
diff --git a/man/TIFFReadDirectory.3t b/man/TIFFReadDirectory.3t
new file mode 100644
index 00000000..b0fe4ba6
--- /dev/null
+++ b/man/TIFFReadDirectory.3t
@@ -0,0 +1,159 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadDirectory.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFReadDirectory 3T "December 16, 1991"
+.SH NAME
+TIFFReadDirectory \- get the contents of the next directory in an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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.
+.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 intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFWriteDirectory (3T),
+.IR TIFFSetDirectory (3T)
diff --git a/man/TIFFReadEncodedStrip.3t b/man/TIFFReadEncodedStrip.3t
new file mode 100644
index 00000000..0f51f8dd
--- /dev/null
+++ b/man/TIFFReadEncodedStrip.3t
@@ -0,0 +1,73 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadEncodedStrip.3t,v 1.12 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFReadEncodedStrip 3T "December 16, 1991"
+.SH NAME
+TIFFReadEncodedStrip \- read and decode a strip of data from an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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
+.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 intro (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..c42474ec
--- /dev/null
+++ b/man/TIFFReadEncodedTile.3t
@@ -0,0 +1,76 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadEncodedTile.3t,v 1.8 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFReadEncodedTile 3T "December 16, 1991"
+.SH NAME
+TIFFReadEncodedTile \- read and decode a tile of data from an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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
+.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 intro (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..f215aa92
--- /dev/null
+++ b/man/TIFFReadRGBAImage.3t
@@ -0,0 +1,177 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadRGBAImage.3t,v 1.6 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.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 <tiffio.h>"
+.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, CMYK, 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.
+Samples/pixel must be either 1, 3, or 4.
+.PP
+Palettte image colormaps that appear to be incorrectly written
+as 8-bit values are automatically scaled to 16-bits.
+.SH "RETURN VALUES"
+1 is returned 1 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
+Alpha is not currently returned or set to 1.0.
+Orientations other than bottom-left, or top-left are
+not handled correctly.
+The pixel packing organization is optimized for a specific machine
+architecture.
+.SH "SEE ALSO"
+.IR intro (3T),
+.IR TIFFOpen (3T)
diff --git a/man/TIFFReadRawStrip.3t b/man/TIFFReadRawStrip.3t
new file mode 100644
index 00000000..41209ce3
--- /dev/null
+++ b/man/TIFFReadRawStrip.3t
@@ -0,0 +1,62 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadRawStrip.3t,v 1.9 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFReadRawStrip 3T "December 16, 1991"
+.SH NAME
+TIFFReadRawStrip \- return the undecoded contents
+of a strip of data from an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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 intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFReadEncodedStrip (3T),
+.IR TIFFReadScanline (3T)
diff --git a/man/TIFFReadRawTile.3t b/man/TIFFReadRawTile.3t
new file mode 100644
index 00000000..5cdec031
--- /dev/null
+++ b/man/TIFFReadRawTile.3t
@@ -0,0 +1,64 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadRawTile.3t,v 1.8 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFReadRawTile 3T "December 16, 1991"
+.SH NAME
+TIFFReadRawTile \- return an undecoded tile of data from an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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).
+.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 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 intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFReadEncodedTile (3T),
+.IR TIFFReadTile (3T)
diff --git a/man/TIFFReadScanline.3t b/man/TIFFReadScanline.3t
new file mode 100644
index 00000000..2466af88
--- /dev/null
+++ b/man/TIFFReadScanline.3t
@@ -0,0 +1,98 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadScanline.3t,v 1.12 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFReadScanline 3T "December 16, 1991"
+.SH NAME
+TIFFReadScanline \- read and decode a scanline of data from an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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.
+.SH "SEE ALSO"
+.IR intro (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..4e2e4200
--- /dev/null
+++ b/man/TIFFReadTile.3t
@@ -0,0 +1,85 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFReadTile.3t,v 1.9 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (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..35711a58
--- /dev/null
+++ b/man/TIFFSetDirectory.3t
@@ -0,0 +1,65 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFSetDirectory.3t,v 1.9 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFSetDirectory 3T "December 16, 1991"
+.SH NAME
+TIFFSetDirectory \- set the current directory for an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "int TIFFSetDirectory(TIFF* tif, tdir_t dirnum)"
+.SH DESCRIPTION
+Set the specified directory to be the current directory
+and read the directory's contents with
+.IR TIFFReadDirectory .
+The parameter
+.I dirnum
+specifies the subfile/directory as an integer number, with
+the first directory numbered zero.
+.SH "RETURN VALUES"
+On successful return 1 is returned.
+Otherwise, 0 is returned if
+.I dirnum
+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 intro (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..973ffeaf
--- /dev/null
+++ b/man/TIFFSetField.3t
@@ -0,0 +1,184 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFSetField.3t,v 1.12 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFSetField 3T "February 14, 1992"
+.SH NAME
+TIFFSetField \- set the value(s) of a tag in a
+.SM TIFF
+file open for writing
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "int TIFFSetField(TIFF* tif, ttag_t tag, ...)"
+.br
+.B "#include <stdarg.h>"
+.br
+.B "int TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)"
+.SH DESCRIPTION
+.IR TIFFSetField
+sets the value of a field in the current directory associated with
+the open
+.SM TIFF
+file
+.IR tif .
+The file must have been previously opened for writing with
+.IR TIFFOpen (3T).
+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.
+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'uint16,uint16* \(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<<BitsPerSample arrays
+TIFFTAG_COMPRESSION 1 uint16 \(dg
+TIFFTAG_CONSECUTIVEBADFAXLINES 1 uint32
+TIFFTAG_DATETIME 1 char*
+TIFFTAG_DOCUMENTNAME 1 char*
+TIFFTAG_DOTRANGE 2 uint16
+TIFFTAG_EXTRASAMPLES 2 uint16,uint16* \(dg count & types array
+TIFFTAG_FILLORDER 1 uint16 \(dg
+TIFFTAG_GROUP3OPTIONS 1 uint32 \(dg
+TIFFTAG_GROUP4OPTIONS 1 uint32 \(dg
+TIFFTAG_HALFTONEHINTS 2 uint16
+TIFFTAG_HOSTCOMPUTER 1 char*
+TIFFTAG_IMAGEDESCRIPTION 1 char*
+TIFFTAG_IMAGEDEPTH 1 uint32 \(dg
+TIFFTAG_IMAGELENGTH 1 uint32
+TIFFTAG_IMAGEWIDTH 1 uint32 \(dg
+TIFFTAG_INKNAMES 1 char*
+TIFFTAG_INKSET 1 uint16 \(dg
+TIFFTAG_JPEGPROC 1 uint16 \(dg
+TIFFTAG_JPEGRESTARTINTERVAL 1 uint16 \(dg
+TIFFTAG_JPEGACTABLES 1 u_char** \(dg SamplesPerPixel arrays
+TIFFTAG_JPEGDCTABLES 1 u_char** \(dg SamplesPerPixel arrays
+TIFFTAG_JPEGQTABLES 1 uint16** \(dg SamplesPerPixel 64-entry arrays
+TIFFTAG_MAKE 1 char*
+TIFFTAG_MATTEING 1 uint16 \(dg
+TIFFTAG_MAXSAMPLEVALUE 1 uint16
+TIFFTAG_MINSAMPLEVALUE 1 uint16
+TIFFTAG_MODEL 1 char*
+TIFFTAG_ORIENTATION 1 uint16
+TIFFTAG_PAGENAME 1 char*
+TIFFTAG_PAGENUMBER 2 uint16
+TIFFTAG_PHOTOMETRIC 1 uint16
+TIFFTAG_PLANARCONFIG 1 uint16 \(dg
+TIFFTAG_PREDICTOR 1 uint16 \(dg
+TIFFTAG_PRIMARYCHROMATICITIES 1 float 6-entry array
+TIFFTAG_REFERENCEBLACKWHITE 1 float* \(dg 2*SamplesPerPixel array
+TIFFTAG_RESOLUTIONUNIT 1 uint16
+TIFFTAG_ROWSPERSTRIP 1 uint32 \(dg must be > 0
+TIFFTAG_SAMPLEFORMAT 1 uint16 \(dg
+TIFFTAG_SAMPLESPERPIXEL 1 uint16 \(dg value must be <= 4
+TIFFTAG_SOFTWARE 1 char*
+TIFFTAG_SUBFILETYPE 1 uint32
+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<<BitsPerSample entry arrays
+TIFFTAG_XPOSITION 1 float
+TIFFTAG_XRESOLUTION 1 float
+TIFFTAG_WHITEPOINT 1 float 2-entry array
+TIFFTAG_YCBCRCOEFFICIENTS 1 float* \(dg 3-entry array
+TIFFTAG_YCBCRPOSITIONING 1 uint16 \(dg
+TIFFTAG_YCBCRSAMPLING 2 uint16 \(dg
+TIFFTAG_YPOSITION 1 float
+TIFFTAG_YRESOLUTION 1 float
+.fi
+.sp 5p
+(\(dg Tag may not have its values changed once data is written.)
+(\(dd
+If
+.I SamplesPerPixel
+is one, then a single array is passed; otherwise three arrays should be
+passed.)
+.SH "RETURN VALUES"
+1 is returned if the operation was successful.
+Otherwise, 0 is returned if an error was detected.
+.SH DIAGNOSTICS
+All error messages are directed to the
+.IR TIFFError (3T)
+routine.
+.PP
+\fB%s: Cannot modify tag "%s" while writing\fP.
+Data has already been written to the file, so the
+specified tag's value can not be changed.
+This restriction is applied to all tags that affect
+the format of written data.
+.PP
+\fB%d: Bad value for "%s"\fP.
+An invalid value was supplied for the named tag.
+.SH "SEE ALSO"
+.IR intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFGetField (3T),
+.IR TIFFSetDirectory (3T),
+.IR TIFFWriteDirectory (3T),
+.IR TIFFReadDirectory (3T)
diff --git a/man/TIFFWarning.3t b/man/TIFFWarning.3t
new file mode 100644
index 00000000..344a6899
--- /dev/null
+++ b/man/TIFFWarning.3t
@@ -0,0 +1,70 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWarning.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFWarning 3T "December 16, 1991"
+.SH NAME
+TIFFWarning, TIFFSetWarningHandler \- library warning interface
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "void TIFFWarning(const char* module, const char* fmt, ...)"
+.sp .5
+.B "#include <stdargh.h>"
+.br
+.B "typedef void (*TIFFWarningHandler)(char* module, 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 intro (3T),
+.IR TIFFError (3T),
+.IR printf (3S)
diff --git a/man/TIFFWriteDirectory.3t b/man/TIFFWriteDirectory.3t
new file mode 100644
index 00000000..61c94be8
--- /dev/null
+++ b/man/TIFFWriteDirectory.3t
@@ -0,0 +1,104 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWriteDirectory.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (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..a7a24e73
--- /dev/null
+++ b/man/TIFFWriteEncodedStrip.3t
@@ -0,0 +1,95 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWriteEncodedStrip.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFWriteEncodedStrip 3T "December 16, 1991"
+.SH NAME
+TIFFWritedEncodedStrip \- compress and write a strip of data to an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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
+.B append
+the result to the end of the specified strip.
+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.
+.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 intro (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..e256bb29
--- /dev/null
+++ b/man/TIFFWriteEncodedTile.3t
@@ -0,0 +1,98 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWriteEncodedTile.3t,v 1.8 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (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..920534bc
--- /dev/null
+++ b/man/TIFFWriteRawStrip.3t
@@ -0,0 +1,83 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWriteRawStrip.3t,v 1.9 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFWriteRawstrip 3T "December 16, 1991"
+.SH NAME
+TIFFWriteRawStrip \- write a strip of raw data to an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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 "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 intro (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..a3149f7f
--- /dev/null
+++ b/man/TIFFWriteRawTile.3t
@@ -0,0 +1,83 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWriteRawTile.3t,v 1.8 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (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..6fc8fb4a
--- /dev/null
+++ b/man/TIFFWriteScanline.3t
@@ -0,0 +1,162 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/TIFFWriteScanline.3t,v 1.11 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFWriteEncodedStrip (3T),
+.IR TIFFWriteRawStrip (3T)
diff --git a/man/fax2ps.1 b/man/fax2ps.1
new file mode 100644
index 00000000..9cd1bf4c
--- /dev/null
+++ b/man/fax2ps.1
@@ -0,0 +1,158 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/fax2ps.1,v 1.9 1995/07/05 18:52:42 sam Exp $
+.\"
+.\" Copyright (c) 1991-1995 Sam Leffler
+.\" Copyright (c) 1991-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
+.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..6596d19b
--- /dev/null
+++ b/man/fax2tiff.1
@@ -0,0 +1,205 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/fax2tiff.1,v 1.16 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.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..0e260749
--- /dev/null
+++ b/man/gif2tiff.1
@@ -0,0 +1,76 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/gif2tiff.1,v 1.6 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH GIF2TIFF 1 "September 26, 1994"
+.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),
+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/intro.3t b/man/intro.3t
new file mode 100644
index 00000000..85b2c1a2
--- /dev/null
+++ b/man/intro.3t
@@ -0,0 +1,359 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/intro.3t,v 1.17 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH INTRO 3T "February 14, 1992"
+.SH NAME
+intro \- introduction to
+.IR libtiff ,
+a library for reading and writing
+.SM TIFF
+files
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.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),
+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),
+and NeXT's 2-bit compression algorithm (32766) (decompression only).
+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 <thing> uint32; 'u
+.nf
+typedef unsigned short uint16; 16-bit unsigned integer
+typedef unsigned <thing> 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 available.
+Consult specific manual pages for details on their operation.
+(The manual page names give here 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
+TIFFScanlineSize size.3t return size of a scanline
+TIFFSetDirectory 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.
+.sp 5p
+.nf
+.ta \w'PhotometricInterpretation'u+2n +\w'Value'u+2n +\w'R/W'u+2n
+\fITag Name\fP \fIValue\fP \fIR/W\fP \fILibrary's Use\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 compression routines
+ConsecutiveBadFaxLines 328 R/W
+DataType 32996 R
+DateTime 306 R/W
+DocumentName 269 R/W
+DotRange 336 R/W
+ExtraSamples 338 R/W lots
+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 code
+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
+JPEGACTables 521 R/W JPEG code
+JPEGDCTables 520 R/W JPEG code
+JPEGProc 512 R/W JPEG code
+JPEGQRestartInterval 515 R/W JPEG code
+JPEGQTables 519 R/W JPEG code
+Make 271 R/W
+Matteing 32995 R
+MaxSampleValue 281 R/W
+MinSampleValue 280 R/W
+Model 272 R/W
+NewSubFileType 254 R/W (called SubFileType)
+Orientation 274 R/W
+PageName 285 R/W
+PageNumber 297 R/W
+PhotometricInterpretation 262 R/W Group 3 and JPEG code
+PlanarConfiguration 284 R/W data i/o
+Predictor 317 R/W used by LZW code
+PrimaryChromacities 319 R/W
+ReferenceBlackWhite 532 R/W
+ResolutionUnit 296 R/W
+RowsPerStrip 278 R/W data i/o
+SampleFormat 339 R/W
+SamplesPerPixel 277 R/W lots
+Software 305 R/W
+StripByteCounts 279 R/W data i/o
+StripOffsets 273 R/W data i/o
+SubFileType 255 R/W (called OSubFileType)
+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 TIFFReadRGBAImage
+YCbCrPositioning 531 R/W tile/strip size calulcations
+YCbCrSubsampling 530 R/W
+YPosition 286 R/W
+YResolution 283 R/W used by Group 3 2d encoding
+.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,
+to be released.
+.PP
+.IR "The Spirit of TIFF Class F" ,
+an appendix to the TIFF 5.0 specification prepared by Cygnet Technologies.
+.PP
+.IR "Appendix ALPHA: Associated Alpha Information" ,
+a proposed appendix to the TIFF 6.0 specification.
+.SH BUGS
+The library does not support multi-sample images
+where some samples have different bits/sample.
+.PP
+It is not possible to overwrite the contents of a strip with
+.IR TIFFWriteEncodedStrip
+or
+.IR TIFFWriteRawStrip
+since they
+.I append
+to a strip.
+Likewise,
+.IR TIFFWriteEncodedTile
+and
+.IR TIFFWriteRawTile
+append to a tile.
+.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..2ea5008c
--- /dev/null
+++ b/man/pal2rgb.1
@@ -0,0 +1,106 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/pal2rgb.1,v 1.11 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH PAL2RGB 1 "September 26, 1994"
+.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 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..8554cb74
--- /dev/null
+++ b/man/ppm2tiff.1
@@ -0,0 +1,94 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/ppm2tiff.1,v 1.7 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH PPM2TIFF 1 "September 26, 1994"
+.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),
+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
+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/query.3t b/man/query.3t
new file mode 100644
index 00000000..33faf544
--- /dev/null
+++ b/man/query.3t
@@ -0,0 +1,114 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/query.3t,v 1.11 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH QUERY 3T "December 16, 1991"
+.SH NAME
+TIFFCurrentRow, TIFFCurrentStrip, TIFFCurrentTile, TIFFCurrentDirectory, TIFFFileno, TIFFFileName, TIFFGetMode, TIFFIsTiled, TIFFIsByteSwapped \- query routines
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "uint32 TIFFCurrentRow(TIFF* tif)"
+.br
+.B "tstrip_t TIFFCurrentStrip(TIFF* tif)"
+.br
+.B "ttile_t TIFFCurrentTile(TIFF* tif)"
+.br
+.B "tdir_t TIFFCurrentDirectory(TIFF* tif)"
+.br
+.B "int TIFFFileno(TIFF* tif)"
+.br
+.B "char* TIFFFileName(TIFF* tif)"
+.br
+.B "int TIFFGetMode(TIFF* tif)"
+.br
+.B "int TIFFIsTiled(TIFF* tif)"
+.br
+.B "int TIFFIsByteSwapped(TIFF* tif)"
+.br
+.B "const char* TIFFGetVersion(void)"
+.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 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
+.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 intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFFdOpen (3T)
diff --git a/man/ras2tiff.1 b/man/ras2tiff.1
new file mode 100644
index 00000000..05758c50
--- /dev/null
+++ b/man/ras2tiff.1
@@ -0,0 +1,87 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/ras2tiff.1,v 1.11 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH RAS2TIFF 1 "May 2, 1989"
+.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),
+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..7b5087de
--- /dev/null
+++ b/man/rgb2ycbcr.1
@@ -0,0 +1,99 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/rgb2ycbcr.1,v 1.5 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH RGB2YCBCR 1 "September 26, 1994"
+.SH NAME
+rgb2ycbcr \- convert non-YCbCr
+.SM TIFF
+images to a YCbCr
+.SM TIFF
+image
+.SH SYNOPSIS
+.B rgb2ycbcr
+[
+.B \-c
+.I compression
+] [
+.B \-h
+.I hsample
+] [
+.B \-v
+.I vsample
+] [
+.B \-r
+.I rows/strip
+]
+.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,
+.I rgb2ycbcr
+converts all but the last file, writing a
+separate directory for each source
+in the destination file.
+.PP
+By default, chrominance samples are created by sampling
+2 by 2 blocks of luminance values.
+The
+.B \-h
+and
+.B \-v
+options can be used to specify alternate horizontal
+and vertical sampling dimensions, respectively.
+Note that only 1, 2, and 4 should be used for portability.
+.PP
+By default, output data are compressed with the
+.SM LZW
+compression scheme.
+A different scheme can be selected with the
+.B \-c
+option; one of:
+.I none
+(for no compression),
+.I packbits
+(for PackBits compression),
+and
+.I lzw
+(for
+.SM LZW
+compression).
+.PP
+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 "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..e7eab097
--- /dev/null
+++ b/man/sgi2tiff.1
@@ -0,0 +1,86 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/sgi2tiff.1,v 1.6 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH SGI2TIFF 1 "September 26, 1994"
+.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),
+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/size.3t b/man/size.3t
new file mode 100644
index 00000000..cfe705af
--- /dev/null
+++ b/man/size.3t
@@ -0,0 +1,83 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/size.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH SIZE 3T "December 16, 1991"
+.SH NAME
+TIFFScanlineSize, TIFFStripSize, TIFFTileSize \- return the size (in bytes) of a scanline, strip, or tile for an open
+.SM TIFF
+file
+.SH SYNOPSIS
+.nf
+.B "#include <tiffio.h>"
+.B "tsize_t TIFFScanlineSize(TIFF* tif)"
+.B "tsize_t TIFFStripSize(TIFF* tif)"
+.B "tsize_t TIFFVStripSize(TIFF* tif, uint32 nrows)"
+.B "tsize_t TIFFTileSize(TIFF* tif)"
+.B "tsize_t TIFFVTileSize(TIFF* tif, uint32 nrows)"
+.SH DESCRIPTION
+.IR 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
+.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
+.IR TIFFTileSize
+returns the equivalent size for a tile of data as it would
+be returned in a call to
+.IR TIFFReadTile
+or as it would be expected in a call to
+.IR TIFFWriteTile .
+.PP
+.IR TIFFVStripSize
+returns the number of bytes in a strip with
+.I nrows
+rows of data.
+Likewise,
+.IR TIFFVTileSize
+returns the number of bytes in a row-aligned tile with
+.I nrows
+of data.
+.PP
+These sizes are typically used when dynamically allocating
+I/O buffers.
+.SH DIAGNOSTICS
+None.
+.SH "SEE ALSO"
+.IR intro (3T),
+.IR TIFFOpen (3T),
+.IR TIFFReadScanline (3T),
+.IR TIFFReadEncodedStrip (3T),
+.IR TIFFReadTile (3T),
+.IR TIFFWriteScanline (3T),
+.IR TIFFWriteEncodedStrip (3T),
+.IR TIFFWriteTile (3T)
diff --git a/man/strip.3t b/man/strip.3t
new file mode 100644
index 00000000..44b8672e
--- /dev/null
+++ b/man/strip.3t
@@ -0,0 +1,57 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/strip.3t,v 1.4 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 1992, 1993, 1994 Sam Leffler
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH TIFFComputeStrip 3T "February 14, 1992"
+.SH NAME
+TIFFComputeStrip, TIFFNumberOfStrips \- strip-related utility routines
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "tstrip_t TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample)"
+.br
+.B "tstrip_t TIFFNumberOfStrips(TIFF* tif)"
+.SH DESCRIPTION
+.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 intro (3T),
+.IR TIFFReadEncodedStrip (3T),
+.IR TIFFReadRawStrip (3T),
+.IR TIFFWriteEncodedStrip (3T),
+.IR TIFFWriteRawStrip (3T)
diff --git a/man/swab.3t b/man/swab.3t
new file mode 100644
index 00000000..8f4f81e9
--- /dev/null
+++ b/man/swab.3t
@@ -0,0 +1,73 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/swab.3t,v 1.8 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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 <tiffio.h>"
+.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 intro (3T),
diff --git a/man/thumbnail.1 b/man/thumbnail.1
new file mode 100644
index 00000000..5a22ab55
--- /dev/null
+++ b/man/thumbnail.1
@@ -0,0 +1,87 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/thumbnail.1,v 1.2 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 1994 Sam Leffler
+.\" Copyright (c) 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.
+.\"
+.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..0bf3cb40
--- /dev/null
+++ b/man/tiff2bw.1
@@ -0,0 +1,85 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiff2bw.1,v 1.12 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFF2BW 1 "September 26, 1994"
+.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),
+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..12015ce3
--- /dev/null
+++ b/man/tiff2ps.1
@@ -0,0 +1,169 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiff2ps.1,v 1.16 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFF2PS 1 "September 26, 1994"
+.SH NAME
+tiff2ps \- convert a
+.SM TIFF
+image to PostScript\(tm
+.SH SYNOPSIS
+.B tiff2ps
+[
+.I options
+]
+.I input.tif
+.SH DESCRIPTION
+.I tiff2ps
+reads a
+.SM TIFF
+image and writes PostScript or Encapsulated PostScript (EPS)
+on the standard output.
+By default,
+.I tiff2ps
+writes Encapsulated PostScript for the first image in the specified
+.SM TIFF
+image file.
+.PP
+By default,
+.I tiff2ps
+will generate PostScript 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 PostScript generated for
+.SM RGB,
+palette, and
+.SM CMYK
+images uses the
+.I colorimage
+operator.
+The PostScript generated for
+greyscale and bilevel images
+uses the
+.I image
+operator.
+When the
+.I colorimage
+operator is used, PostScript code to emulate this operator
+on older PostScript 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 PostScript Level I (the default).
+.TP
+.B \-2
+Generate PostScript 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 PostScript.
+.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) PostScript.
+.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).
+.SH EXAMPLES
+The following generates PostScript 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 PostScript 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 PostScript does not support the notion of a colormap,
+8-bit palette images produce 24-bit PostScript 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 use PostScript Level II support for printing color images
+(only bilevel and greyscale images).
+Does not handle tiled images.
+.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..568a94ef
--- /dev/null
+++ b/man/tiffcmp.1
@@ -0,0 +1,74 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffcmp.1,v 1.17 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.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..c3150e5c
--- /dev/null
+++ b/man/tiffcp.1
@@ -0,0 +1,199 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffcp.1,v 1.20 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFCP 1 "September 26, 1994"
+.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 \-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 g3
+for CCITT Group 3 (T.4) compression,
+.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 \-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..43f546d6
--- /dev/null
+++ b/man/tiffdither.1
@@ -0,0 +1,122 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffdither.1,v 1.14 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH TIFFDITHER 1 "September 26, 1994"
+.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 g3
+for CCITT Group 3 (T.4) compression,
+.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..3475a4b0
--- /dev/null
+++ b/man/tiffdump.1
@@ -0,0 +1,74 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffdump.1,v 1.12 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFDUMP 1 "September 26, 1994"
+.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..52bd0e61
--- /dev/null
+++ b/man/tiffgt.1
@@ -0,0 +1,143 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffgt.1,v 1.18 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFGT 1 "September 26, 1994"
+.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 an image stored in a file with the
+Tag Image File Format, Revision 6.0.
+The image is placed in a fixed size window that the
+user must position on the display.
+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 .
+.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 \-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 \-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 \-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..f9929de6
--- /dev/null
+++ b/man/tiffinfo.1
@@ -0,0 +1,82 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffinfo.1,v 1.15 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFINFO 1 "May 2, 1990"
+.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.
+.PP
+.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..81ac0872
--- /dev/null
+++ b/man/tiffmedian.1
@@ -0,0 +1,106 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffmedian.1,v 1.16 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 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.
+.\"
+.if n .po 0
+.TH TIFFMEDIAN 1 "September 26, 1994"
+.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,
+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..8eff671b
--- /dev/null
+++ b/man/tiffsplit.1
@@ -0,0 +1,66 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffsplit.1,v 1.4 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" Copyright (c) 1992, 1993, 1994 Sam Leffler
+.\" Copyright (c) 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.
+.\"
+.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..6b540303
--- /dev/null
+++ b/man/tiffsv.1
@@ -0,0 +1,134 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tiffsv.1,v 1.14 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFSV 1 "September 26, 1994"
+.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 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/man/tile.3t b/man/tile.3t
new file mode 100644
index 00000000..b282620b
--- /dev/null
+++ b/man/tile.3t
@@ -0,0 +1,91 @@
+.\" $Header: /usr/people/sam/tiff/man/RCS/tile.3t,v 1.10 1995/07/07 23:29:04 sam Exp $
+.\"
+.\" 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.
+.\"
+.if n .po 0
+.TH TIFFComputeTile 3T "February 14, 1992"
+.SH NAME
+TIFFComputeTile, TIFFCheckTile, TIFFNumberOfTiles \- tile-related utility routines
+.SH SYNOPSIS
+.B "#include <tiffio.h>"
+.br
+.B "ttile_t TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t sample)"
+.br
+.B "int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, tsample_t sample)"
+.br
+.B "ttile_t TIFFNumberOfTiles(TIFF* tif)"
+.SH DESCRIPTION
+.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 intro (3T),
+.IR TIFFReadEncodedTile (3T),
+.IR TIFFReadRawTile (3T),
+.IR TIFFReadTile (3T),
+.IR TIFFWriteEncodedTile (3T),
+.IR TIFFWriteRawTile (3T),
+.IR TIFFWriteTile (3T)
diff --git a/port/Makefile.in b/port/Makefile.in
new file mode 100644
index 00000000..8f37bb98
--- /dev/null
+++ b/port/Makefile.in
@@ -0,0 +1,69 @@
+#! smake
+# $Header: /usr/people/sam/tiff/port/RCS/Makefile.in,v 1.2 1995/05/24 01:54:38 sam Exp $
+#
+# @WARNING@
+#
+# 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 = ${DEPTH}/${TOPSRCDIR}/port
+VPATH = ../@SRCDIR@/port
+
+#
+# VERSION: @VERSION@
+# DATE: @DATE@
+# TARGET: @TARGET@
+# CCOMPILER: @CCOMPILER@
+#
+
+SHELL = /bin/sh
+NULL =
+CC = @CCOMPILER@
+AR = @AR@
+AROPTS = @AROPTS@
+RANLIB = @RANLIB@
+
+IPATH = -I. -I${DEPTH} -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 <stdio.h>
+#include <string.h>
+
+/*
+ * 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.in b/port/install.sh.in
new file mode 100644
index 00000000..95f4cf9e
--- /dev/null
+++ b/port/install.sh.in
@@ -0,0 +1,246 @@
+#! @SCRIPT_SH@
+# $Header: /usr/people/sam/tiff/port/RCS/install.sh.in,v 1.18 1995/04/17 23:52:02 sam Exp $
+#
+# @WARNING@
+#
+# HylaFAX Facsimile Software
+#
+# Copyright (c) 1990-1995 Sam Leffler
+# Copyright (c) 1991-1995 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..d95b78d8
--- /dev/null
+++ b/port/strcasecmp.c
@@ -0,0 +1,99 @@
+#include "port.h"
+/*
+ * 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 <string.h>
+
+#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 u_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 u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_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 u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_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 <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/*
+ * 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/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 00000000..83273541
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,243 @@
+# $Header: /usr/people/sam/tiff/tools/RCS/Makefile.in,v 1.13 1995/07/05 21:09:52 sam Exp $
+#
+# @WARNING@
+#
+# TIFF Library Tools
+#
+# Copyright (c) 1988-1995 Sam Leffler
+# Copyright (c) 1991-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 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@/tools
+
+JPEGDIR = ${DEPTH}/@DIR_JPEG@
+ZIPDIR = ${DEPTH}/@DIR_LIBGZ@
+PORT = ${DEPTH}/port
+
+#
+# VERSION: @VERSION@
+# DATE: @DATE@
+# TARGET: @TARGET@
+# CCOMPILER: @CCOMPILER@
+#
+SHELL = /bin/sh
+NULL =
+CC = @CCOMPILER@
+INSTALL = @INSTALL@
+#
+COPTS = @GCOPTS@
+OPTIMIZER=-O
+IPATH = -I. -I${DEPTH} -I${SRCDIR} -I${DEPTH}/@SRCDIR@/libtiff
+CFLAGS = @ENVOPTS@ ${COPTS} ${OPTIMIZER} ${IPATH}
+#
+LIBTIFF = ../libtiff/libtiff.@DSOSUF@
+LIBJPEG = @LIBJPEG@
+LIBGZ = @LIBGZ@
+LIBS = ${LIBTIFF} ${LIBJPEG} ${LIBGZ} @LIBPORT@ @MACHDEPLIBS@
+#
+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; \
+ fi
+ @if [ "@LIBGL@" = yes ]; then \
+ ${MAKE} tiffgt tiffsv; \
+ 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; \
+ fi
+ @if [ "@LIBGL@" = yes ]; then \
+ ${INSTALL} -idb tiff.sw.tools -m 755 -F @DIR_BIN@ -O tiffgt tiffsv;\
+ 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 ${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 ${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/tools/Makefile.lcc b/tools/Makefile.lcc
new file mode 100644
index 00000000..ad7e4a68
--- /dev/null
+++ b/tools/Makefile.lcc
@@ -0,0 +1,132 @@
+# $Header: /usr/people/sam/tiff/tools/RCS/Makefile.lcc,v 1.3 1994/12/15 23:51:55 sam Exp $
+#
+# TIFF Library Tools
+#
+# 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.
+#
+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..707848d2
--- /dev/null
+++ b/tools/fax2ps.c
@@ -0,0 +1,409 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/fax2ps.c,v 1.2 1995/06/06 23:21:41 sam Exp $" */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include "tiffio.h"
+
+float defxres = 204.; /* default x resolution (pixels/inch) */
+float defyres = 98.; /* default y resolution (lines/inch) */
+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("gsave\n");
+ if (scaleToPage) {
+ float yscale = pageHeight / (h/yres);
+ float xscale = pageWidth / (w/xres);
+ printf("0 %d translate\n", (int)(yscale*(h/yres)*72.));
+ printf("%g %g scale\n", (72.*xscale)/xres, -(72.*yscale)/yres);
+ } else {
+ printf("0 %d translate\n", (int)(72.*h/yres));
+ 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\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(void* va, void* vb)
+{
+ int* pa = (int*) va;
+ int* pb = (int*) vb;
+ return (*pa - *pb);
+}
+
+extern double atof();
+static void usage(int code);
+
+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 */
+ long 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, fd;
+ char temp[1024], buf[16*1024];
+
+ strcpy(temp, "/tmp/fax2psXXXXXX");
+ fd = mkstemp(temp);
+ if (fd == -1) {
+ fprintf(stderr, "Could not create temp file \"%s\"\n", temp);
+ exit(-2);
+ }
+ while ((n = read(fileno(stdin), buf, sizeof (buf))) > 0)
+ write(fd, buf, n);
+ tif = TIFFOpen(temp, "r");
+ unlink(temp);
+ if (tif) {
+ fax2ps(tif, npages, pages, "<stdin>");
+ TIFFClose(tif);
+ } else
+ fprintf(stderr, "%s: Can not open, or not a TIFF file.\n", temp);
+ close(fd);
+ }
+ printf("%%%%Trailer\n");
+ printf("%%%%Pages: %u\n", totalPages);
+ printf("%%%%EOF\n");
+
+ exit(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..582ccb3a
--- /dev/null
+++ b/tools/fax2tiff.c
@@ -0,0 +1,361 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/fax2tiff.c,v 1.37 1995/07/17 01:36:52 sam Exp $ */
+
+/*
+ * Copyright (c) 1990-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * Convert a CCITT Group 3 FAX file to TIFF Group 3 format.
+ */
+#if defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h> /* should have atof & getopt */
+#endif
+#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
+u_char rowbuf[TIFFhowmany(XSIZE,8)];
+u_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, "%d total bad rows\n", 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, row);
+ break;
+ }
+ row++;
+ if (stretch) {
+ if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
+ fprintf(stderr, "%s: Write error at row %ld.\n",
+ tifout->tif_name, 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..052b66a2
--- /dev/null
+++ b/tools/gif2tiff.c
@@ -0,0 +1,517 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/gif2tiff.c,v 1.24 1995/06/30 00:27:07 sam Exp $ */
+
+/*
+ * Copyright (c) 1990-1995 Sam Leffler
+ * Copyright (c) 1991-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.
+ */
+
+/*
+ * 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
+ *
+ */
+#if defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <math.h>
+
+#include "tiffio.h"
+
+#ifdef _WINDOWS
+#define BINMODE "w"
+#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<<globalbits,infile);
+ }
+}
+
+int
+readgifimage(char* mode)
+{
+ unsigned char buf[9];
+ int local, interleaved;
+ unsigned char localmap[256][3];
+ int localbits;
+ int status;
+
+ if (fread(buf, 1, 9, infile) == 0) {
+ perror(filename);
+ return (0);
+ }
+ width = buf[4] + (buf[5] << 8);
+ height = buf[6] + (buf[7] << 8);
+ local = buf[8] & 0x80;
+ interleaved = buf[8] & 0x40;
+
+ if (local == 0 && global == 0) {
+ fprintf(stderr, "no colormap present for image\n");
+ return (0);
+ }
+ if ((raster = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) {
+ fprintf(stderr, "not enough memory for image\n");
+ return (0);
+ }
+ if (local) {
+ localbits = (buf[8] & 0x7) + 1;
+
+ fprintf(stderr, " local colors: %d\n", 1<<localbits);
+
+ fread(localmap, 3, 1<<localbits, infile);
+ initcolors(localmap, 1<<localbits);
+ } else if (global) {
+ initcolors(globalmap, 1<<globalbits);
+ }
+ if (status = readraster())
+ rasterize(interleaved, mode);
+ _TIFFfree(raster);
+ return status;
+}
+
+/*
+ * readextension -
+ * Read a GIF extension block (and do nothing with it).
+ *
+ */
+void
+readextension(void)
+{
+ int count;
+ char buf[255];
+
+ (void) getc(infile);
+ while (count = getc(infile))
+ fread(buf, 1, count, infile);
+}
+
+/*
+ * readraster -
+ * Decode a raster image
+ *
+ */
+int
+readraster(void)
+{
+ unsigned char *fill = raster;
+ unsigned char buf[255];
+ register int bits=0;
+ register unsigned long datum=0;
+ register unsigned char *ch;
+ register int count, code;
+ int status = 1;
+
+ datasize = getc(infile);
+ clear = 1 << datasize;
+ eoi = clear + 1;
+ avail = clear + 2;
+ oldcode = -1;
+ codesize = datasize + 1;
+ codemask = (1 << codesize) - 1;
+ for (code = 0; code < clear; code++) {
+ prefix[code] = 0;
+ suffix[code] = code;
+ }
+ stackp = stack;
+ for (count = getc(infile); count > 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;
+ register unsigned char *rr;
+ unsigned char *newras;
+ 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) { \
+ register unsigned char* ras = raster; \
+ for (row = offset; row < height; row += step) { \
+ rr = newras + row*width; \
+ _TIFFmemcpy(rr, ras, width); \
+ ras += width; \
+ } \
+ }
+ 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<height; row += rowsperstrip) {
+ if (TIFFWriteEncodedStrip(tif, strip, newras+row*width, stripsize) < 0)
+ break;
+ strip++;
+ }
+ TIFFClose(tif);
+
+ _TIFFfree(newras);
+}
diff --git a/tools/pal2rgb.c b/tools/pal2rgb.c
new file mode 100644
index 00000000..b18d7c02
--- /dev/null
+++ b/tools/pal2rgb.c
@@ -0,0 +1,389 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/pal2rgb.c,v 1.27 1995/06/30 00:27:07 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#endif
+#include <ctype.h>
+
+#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<<bitspersample, rmap, gmap, bmap);
+ if (cmap == 16) {
+ /*
+ * Convert 16-bit colormap to 8-bit.
+ */
+ int i;
+
+ for (i = (1<<bitspersample)-1; i > 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..0eb422cc
--- /dev/null
+++ b/tools/ppm2tiff.c
@@ -0,0 +1,245 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/ppm2tiff.c,v 1.22 1995/07/01 01:16:55 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <ctype.h>
+
+#include "tiffio.h"
+
+#ifdef _WINDOWS
+#define BINMODE "w"
+#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 = (uint16) -1;
+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 = "<stdin>";
+ 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 %d %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..7794bf9d
--- /dev/null
+++ b/tools/ras2tiff.c
@@ -0,0 +1,267 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/ras2tiff.c,v 1.26 1995/07/01 01:16:55 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <ctype.h>
+
+#include "rasterfile.h"
+#include "tiffio.h"
+
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#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<<h.ras_depth;
+ if (h.ras_maplength > 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 = linebytes;
+ 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..30c09a7c
--- /dev/null
+++ b/tools/rasterfile.h
@@ -0,0 +1,41 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/rasterfile.h,v 1.1 1990/10/08 17:24:23 sam 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..a0786ec2
--- /dev/null
+++ b/tools/rgb2ycbcr.c
@@ -0,0 +1,342 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/rgb2ycbcr.c,v 1.25 1995/06/06 23:45:26 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#endif
+
+#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 howmany(x, y) (((x)+((y)-1))/(y))
+#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..a4fa16fa
--- /dev/null
+++ b/tools/sgi2tiff.c
@@ -0,0 +1,291 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/sgi2tiff.c,v 1.23 1995/07/01 01:16:55 sam Exp $ */
+
+/*
+ * Copyright (c) 1991-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <gl/image.h>
+#include <ctype.h>
+
+#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);
+ 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)
+{
+ unsigned char *buf = (unsigned char *)_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--) {
+ unsigned char* pp = buf;
+
+ getrow(in, r, y, 0);
+ getrow(in, g, y, 1);
+ getrow(in, b, y, 2);
+ for (x = 0; x < in->xsize; x++) {
+ *pp++ = r[x];
+ *pp++ = g[x];
+ *pp++ = b[x];
+ }
+ if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
+ goto bad;
+ }
+ } else {
+ r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
+ for (y = in->ysize-1; y >= 0; y--) {
+ getrow(in, r, y, 0);
+ for (x = 0; x < in->xsize; x++)
+ buf[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)
+{
+ unsigned char *buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
+ short *r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
+ 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++)
+ buf[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..5ebc7e24
--- /dev/null
+++ b/tools/sgigt.c
@@ -0,0 +1,979 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/sgigt.c,v 1.64 1995/06/21 15:40:54 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef unsigned char u_char;
+#endif
+#include <gl.h>
+#include <device.h>
+
+#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);
+
+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));
+ /*
+ * 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 == 0) {
+ 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
+ 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(x, y-(h-1), w-1, y, raster-x-(h-1)*w);
+ else
+ lrectwrite(x, 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;
+ u_int 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:
+ 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..8bc1dc80
--- /dev/null
+++ b/tools/sgisv.c
@@ -0,0 +1,314 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/sgisv.c,v 1.22 1995/06/06 23:45:26 sam Exp $ */
+
+/*
+ * Copyright (c) 1990-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef unsigned char u_char;
+typedef unsigned long u_long;
+#endif
+#include <gl.h>
+#include <ctype.h>
+
+#include "tiffio.h"
+
+#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 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",
+"",
+"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..1eb0c152
--- /dev/null
+++ b/tools/thumbnail.c
@@ -0,0 +1,575 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/thumbnail.c,v 1.8 1995/06/06 23:45:26 sam Exp $ */
+
+/*
+ * Copyright (c) 1994-1995 Sam Leffler
+ * Copyright (c) 1994-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <math.h>
+
+#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 u_char* thumbnail;
+
+static int cpIFD(TIFF*, TIFF*);
+static int generateThumbnail(TIFF*, TIFF*);
+static void initScale();
+static void usage(void);
+
+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 = (u_char*) _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 u_short filterWidth; /* filter width in pixels */
+static u_short stepSrcWidth; /* src image stepping width */
+static u_short stepDstWidth; /* dest stepping width */
+static u_char* src0; /* horizontal bit stepping (start) */
+static u_char* src1; /* horizontal bit stepping (middle) */
+static u_char* src2; /* horizontal bit stepping (end) */
+static u_short* rowoff; /* row offset for stepping */
+static u_char cmap[256]; /* colormap indexes */
+static u_char 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[], u_int p, u_int n)
+{
+ u_int i;
+ u_int 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 */
+ u_int 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 = (u_char*) _TIFFmalloc(sizeof (u_char) * tnw);
+ src1 = (u_char*) _TIFFmalloc(sizeof (u_char) * tnw);
+ src2 = (u_char*) _TIFFmalloc(sizeof (u_char) * tnw);
+ rowoff = (u_short*) _TIFFmalloc(sizeof (u_short) * 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(u_short sw)
+{
+ if (stepSrcWidth != sw || stepDstWidth != tnw) {
+ int step = sw;
+ int limit = tnw;
+ int err = 0;
+ u_int sx = 0;
+ u_int x;
+ int fw;
+ u_char b;
+ for (x = 0; x < tnw; x++) {
+ u_int 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(u_char* row, int nrows, const u_char* rows[])
+{
+ u_int x;
+ u_int area = nrows * filterWidth;
+ for (x = 0; x < tnw; x++) {
+ u_int mask0 = src0[x];
+ u_int fw = src1[x];
+ u_int mask1 = src1[x];
+ u_int off = rowoff[x];
+ u_int acc = 0;
+ u_int y, i;
+ for (y = 0; y < nrows; y++) {
+ const u_char* 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 u_char* br, u_int rw, u_int rh)
+{
+ int step = rh;
+ int limit = tnh;
+ int err = 0;
+ int bpr = howmany(rw,8);
+ u_int sy = 0;
+ u_char* row = thumbnail;
+ u_int dy;
+ for (dy = 0; dy < tnh; dy++) {
+ const u_char* 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 u_char* br, u_int rw, u_int rh)
+{
+ filterWidth = (u_short) 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..87d503eb
--- /dev/null
+++ b/tools/tiff2bw.c
@@ -0,0 +1,404 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiff2bw.c,v 1.19 1995/07/19 00:39:51 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+#include <ctype.h>
+#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<<bitspersample, red, green, blue) == 16) {
+ int i;
+#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
+ for (i = (1<<bitspersample)-1; i >= 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..389dd4f7
--- /dev/null
+++ b/tools/tiff2ps.c
@@ -0,0 +1,935 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiff2ps.c,v 1.45 1995/06/06 23:45:26 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h> /* for atof */
+#endif
+#include <math.h>
+#include <time.h>
+
+#include "tiffio.h"
+
+/*
+ * NB: this code assumes uint32 works with printf's %l[ud].
+ */
+#define TRUE 1
+#define FALSE 0
+
+int ascii85 = FALSE; /* use ASCII85 encoding */
+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 */
+char *filename; /* input filename */
+
+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:aeps128DT")) != -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 '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 (bitspersample) {
+ case 1: case 2:
+ case 4: case 8:
+ break;
+ default:
+ TIFFError(filename, "Can not handle %d-bit/sample image",
+ bitspersample);
+ return (0);
+ }
+ 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 {
+ TIFFError(filename,
+ "Can not handle image with 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;
+ default:
+ TIFFError(filename,
+ "Can not handle image with PhotometricInterpretation=%d",
+ photometric);
+ 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: <cols> <rows> <depth> <main channels> <pad channels>
+ * <block size> <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 \"",
+ w, 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 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;
+ 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);
+ TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &tf_rowsperstrip);
+ setupPageState(tif, &w, &h, &prw, &prh);
+ if (!npages)
+ PSHead(fd, tif, w, h, prw, prh, ox, oy);
+ tf_bytesperrow = TIFFScanlineSize(tif);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE,
+ &bitspersample);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL,
+ &samplesperpixel);
+ TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfiguration);
+ TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
+ TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
+ &extrasamples, &sampleinfo);
+ alpha = (extrasamples == 1 &&
+ sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+ if (checkImage(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)
+ fprintf(fd, "%f %f scale\n",
+ pw*PS_UNIT_SIZE, ph*PS_UNIT_SIZE);
+ 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\
+";
+
+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, "%%%%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, "%%%%Pages: (atend)\n");
+ fprintf(fd, "%%%%EndComments\n");
+ fprintf(fd, "%%%%BeginSetup\n");
+ if (PSduplex)
+ fprintf(fd, "%s", DuplexPreamble);
+ if (PStumble)
+ fprintf(fd, "%s", TumblePreamble);
+ fprintf(fd, "%%%%EndSetup\n");
+}
+
+void
+PSTail(FILE *fd, int npages)
+{
+ fprintf(fd, "%%%%Pages: %d\n", npages);
+ fprintf(fd, "%%%%Trailer\n%%%%EOF\n");
+}
+
+static int
+emitPSLevel2FilterFunction(FILE* fd, TIFF* tif, uint32 w, uint32 h)
+{
+ uint32 group3opts;
+ int K;
+
+#define P(a,b) (((a)<<4)|((b)&0xf))
+ switch (P(compression, photometric)) {
+ case P(COMPRESSION_CCITTRLE, PHOTOMETRIC_MINISBLACK):
+ case P(COMPRESSION_CCITTRLE, PHOTOMETRIC_MINISWHITE):
+ K = 0;
+ break;
+ case P(COMPRESSION_CCITTFAX3, PHOTOMETRIC_MINISBLACK):
+ case P(COMPRESSION_CCITTFAX3, PHOTOMETRIC_MINISWHITE):
+ TIFFGetField(tif, TIFFTAG_GROUP3OPTIONS, &group3opts);
+ K = group3opts&GROUP3OPT_2DENCODING;
+ break;
+ case P(COMPRESSION_CCITTFAX4, PHOTOMETRIC_MINISBLACK):
+ case P(COMPRESSION_CCITTFAX4, PHOTOMETRIC_MINISWHITE):
+ K = -1;
+ break;
+ case P(COMPRESSION_LZW, PHOTOMETRIC_MINISBLACK):
+ fprintf(fd, " /LZWDecode filter\n");
+ return (TRUE);
+ default:
+ return (FALSE);
+ }
+#undef P
+ fprintf(fd, " <<");
+ fprintf(fd, "/K %d", K);
+ fprintf(fd, " /Columns %d /Rows %d", w, h);
+ fprintf(fd, " /EndOfBlock false /BlackIs1 %s",
+ (photometric == PHOTOMETRIC_MINISBLACK) ? "true" : "false");
+ fprintf(fd, ">>\n /CCITTFaxDecode filter\n");
+ return (TRUE);
+}
+
+void
+PSpage(FILE* fd, TIFF* tif, uint32 w, uint32 h)
+{
+ 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 %d string def\n", ps_bytesperrow);
+ fprintf(fd, "%lu %lu 8\n", w, h);
+ fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", w, h, 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:
+ if (level2) {
+ int rawdata;
+ fprintf(fd, "{ %lu { %lu %lu %d\n", tf_numberstrips,
+ w, tf_rowsperstrip, bitspersample);
+ fprintf(fd, " [%lu 0 0 -%lu 0 %lu]\n", w, h, h);
+ fprintf(fd, " currentfile /ASCII%sDecode filter\n",
+ ascii85 ? "85" : "Hex");
+ rawdata = emitPSLevel2FilterFunction(fd, tif, w, h);
+ fprintf(fd, " image\n");
+ fprintf(fd, " 0 -%f translate\n",
+ (float)tf_rowsperstrip/(float)h);
+ fprintf(fd, " } repeat\n}\n");
+ PhotoshopBanner(fd, w, h, 1, 1, "image");
+ fprintf(fd, "%%%%BeginData\nexec\n");
+ if (ascii85) {
+ if (rawdata)
+ PSRawDataBW(fd, tif, w, tf_rowsperstrip);
+ else
+ PSDataBW(fd, tif, w, h);
+ } else {
+ if (rawdata)
+ PSRawDataBW(fd, tif, w, h);
+ else
+ PSDataBW(fd, tif, w, h);
+ }
+ fprintf(fd, "%%%%EndData\n");
+ } else {
+ PhotoshopBanner(fd, w, h, 1, 1, "image");
+ fprintf(fd, "/scanLine %d string def\n",ps_bytesperrow);
+ fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
+ fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", w, h, 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 %d string def\n", ps_bytesperrow);
+ fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
+ fprintf(fd, "[%lu 0 0 -%lu 0 %lu]\n", w, h, 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 %d string def\n", i, ps_bytesperrow);
+ fprintf(fd, "%lu %lu %d\n", w, h, bitspersample);
+ fprintf(fd, "[%lu 0 0 -%lu 0 %lu] \n", w, h, 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)
+
+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);
+}
+
+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<<bitspersample, rmap, gmap, bmap) == 16) {
+ int i;
+#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
+ for (i = (1<<bitspersample)-1; i >= 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;
+ TIFFGetField(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);
+}
+
+/*
+ * ASCII85 Encoding Support.
+ */
+unsigned char ascii85buf[10];
+int ascii85count;
+int ascii85breaklen;
+
+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;
+ }
+ }
+ p += 4;
+ }
+ _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)",
+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..a6a4cfde
--- /dev/null
+++ b/tools/tiffcmp.c
@@ -0,0 +1,486 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffcmp.c,v 1.27 1995/07/19 00:39:51 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#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 = (8-bps);
+ mask2 = mask1<<s;
+ for (; mask2; mask2 >>= bps, s -= bps, pix++) {
+ if ((w1 & mask2) ^ (w2 & mask2)) {
+ printf(
+ "Scanline %lu, pixel %lu, sample %d: %01x %01x\n",
+ row, 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",
+ row, pix, sample, w1, w2);
+ if (--stopondiff)
+ exit(1);
+ break;
+ case 16:
+ printf("Scanline %lu, pixel %lu, sample %d: %04x %04x\n",
+ row, 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 %d: ",
+ row, pixel, 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..b8d01eef
--- /dev/null
+++ b/tools/tiffcp.c
@@ -0,0 +1,1230 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffcp.c,v 1.43 1995/06/30 05:37:07 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef unsigned char u_char;
+#endif
+#include <ctype.h>
+
+#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;
+ const char* mode = "w";
+ int c;
+ extern int optind;
+ extern char* optarg;
+
+ while ((c = getopt(argc, argv, "c:f:l:o:p:r:w:aist")) != -1)
+ switch (c) {
+ case 'a': /* append to output */
+ mode = "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 '?':
+ usage();
+ /*NOTREACHED*/
+ }
+ if (argc - optind < 2)
+ usage();
+ out = TIFFOpen(argv[argc-1], mode);
+ if (out == NULL)
+ return (-2);
+ for (; optind < argc-1 ; optind++) {
+ in = TIFFOpen(argv[optind], "r");
+ 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 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_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 },
+ { TIFFTAG_SMINSAMPLEVALUE, 1, TIFF_DOUBLE },
+ { TIFFTAG_SMAXSAMPLEVALUE, 1, TIFF_DOUBLE },
+};
+#define NTAGS (sizeof (tags) / sizeof (tags[0]))
+
+static void
+cpOtherTags(TIFF* in, TIFF* out)
+{
+ struct cpTag *p;
+
+ for (p = tags; p < &tags[NTAGS]; p++)
+ switch (p->type) {
+ case TIFF_SHORT:
+ if (p->count == 1) {
+ uint16 shortv;
+ CopyField(p->tag, shortv);
+ } else if (p->count == 2) {
+ uint16 shortv1, shortv2;
+ CopyField2(p->tag, shortv1, shortv2);
+ } else if (p->count == (uint16) -1) {
+ uint16 shortv1;
+ uint16* shortav;
+ CopyField2(p->tag, shortv1, shortav);
+ }
+ break;
+ case TIFF_LONG:
+ { uint32 longv;
+ CopyField(p->tag, longv);
+ }
+ break;
+ case TIFF_RATIONAL:
+ if (p->count == 1) {
+ float floatv;
+ CopyField(p->tag, floatv);
+ } else if (p->count == (uint16) -1) {
+ float* floatav;
+ CopyField(p->tag, floatav);
+ }
+ break;
+ case TIFF_ASCII:
+ { char* stringv;
+ CopyField(p->tag, stringv);
+ }
+ break;
+ case TIFF_DOUBLE:
+ if (p->count == 1) {
+ double doublev;
+ CopyField(p->tag, doublev);
+ } else if (p->count == (uint16) -1) {
+ double* doubleav;
+ CopyField(p->tag, doubleav);
+ }
+ break;
+ }
+}
+
+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, shortv;
+ copyFunc cf;
+ uint32 w, l;
+
+ CopyField(TIFFTAG_IMAGEWIDTH, w);
+ CopyField(TIFFTAG_IMAGELENGTH, l);
+ CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
+ 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
+ CopyField(TIFFTAG_PHOTOMETRIC, shortv);
+ if (fillorder != 0)
+ TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
+ else
+ CopyField(TIFFTAG_FILLORDER, shortv);
+ CopyField(TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+ /*
+ * 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 (g3opts != (uint32) -1)
+ TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
+ else
+ CopyField(TIFFTAG_GROUP3OPTIONS, g3opts);
+ if (samplesperpixel <= 4) {
+ uint16 *tr, *tg, *tb, *ta;
+ CopyField4(TIFFTAG_TRANSFERFUNCTION, tr, tg, tb, ta);
+ }
+ { uint16 *red, *green, *blue;
+ if (TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue)) {
+ CheckAndCorrectColormap(in, 1<<bitspersample, red, green, blue);
+ TIFFSetField(out, TIFFTAG_COLORMAP, red, green, blue);
+ }
+ }
+/* 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;
+ }
+ cpOtherTags(in, out);
+
+ 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, \
+ u_char* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
+typedef void (*readFunc)(TIFF*, u_char*, uint32, uint32, tsample_t);
+
+#define DECLAREwriteFunc(x) \
+static int x(TIFF* out, \
+ u_char* buf, uint32 imagelength, uint32 imagewidth, tsample_t spp)
+typedef int (*writeFunc)(TIFF*, u_char*, uint32, uint32, tsample_t);
+
+/*
+ * Contig -> contig by scanline for rows/strip change.
+ */
+DECLAREcpFunc(cpContig2ContigByRow)
+{
+ u_char *buf = (u_char *)_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);
+ u_char *buf = (u_char *)_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)
+{
+ u_char *buf = (u_char *)_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)
+{
+ u_char *inbuf = (u_char *)_TIFFmalloc(TIFFScanlineSize(in));
+ u_char *outbuf = (u_char *)_TIFFmalloc(TIFFScanlineSize(out));
+ register u_char *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 = inbuf + s;
+ outp = 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)
+{
+ u_char *inbuf = (u_char *)_TIFFmalloc(TIFFScanlineSize(in));
+ u_char *outbuf = (u_char *)_TIFFmalloc(TIFFScanlineSize(out));
+ register u_char *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 = inbuf;
+ outp = 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(u_char* out, u_char* 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(u_char* out, u_char* 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(u_char* out, u_char* 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;
+ u_char* buf = (u_char *)
+ _TIFFmalloc(TIFFRasterScanlineSize(in) * imagelength);
+ if (buf) {
+ (*fin)(in, buf, imagelength, imagewidth, spp);
+ status = (fout)(out, buf, imagelength, imagewidth, spp);
+ _TIFFfree(buf);
+ }
+ return (status);
+}
+
+DECLAREreadFunc(readContigStripsIntoBuffer)
+{
+ tsize_t scanlinesize = TIFFScanlineSize(in);
+ u_char *bufp = buf;
+ uint32 row;
+
+ (void) imagewidth; (void) spp;
+ for (row = 0; row < imagelength; row++) {
+ if (TIFFReadScanline(in, bufp, row, 0) < 0 && !ignore)
+ break;
+ bufp += scanlinesize;
+ }
+}
+
+DECLAREreadFunc(readSeparateStripsIntoBuffer)
+{
+ tsize_t scanlinesize = TIFFScanlineSize(in);
+ u_char* scanline = (u_char *) _TIFFmalloc(scanlinesize);
+
+ (void) imagewidth;
+ if (scanline) {
+ u_char *bufp = buf;
+ uint32 row;
+ tsample_t s;
+
+ for (row = 0; row < imagelength; row++) {
+ /* merge channels */
+ for (s = 0; s < spp; s++) {
+ u_char* sp = scanline;
+ u_char* bp = bufp + s;
+ tsize_t n = scanlinesize;
+
+ if (TIFFReadScanline(in, sp, row, s) < 0 && !ignore)
+ goto done;
+ while (n-- > 0)
+ *bp = *bufp++, bp += spp;
+ }
+ bufp += scanlinesize;
+ }
+done:
+ _TIFFfree(scanline);
+ }
+}
+
+DECLAREreadFunc(readContigTilesIntoBuffer)
+{
+ u_char* tilebuf = (u_char *) _TIFFmalloc(TIFFTileSize(in));
+ uint32 imagew = TIFFScanlineSize(in);
+ uint32 tilew = TIFFTileRowSize(in);
+ int iskew = imagew - tilew;
+ u_char *bufp = 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;
+ u_char* tilebuf = (u_char *) _TIFFmalloc(TIFFTileSize(in));
+ u_char *bufp = 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)
+{
+ tsize_t scanline = TIFFScanlineSize(out);
+ uint32 row;
+
+ (void) imagewidth; (void) spp;
+ for (row = 0; row < imagelength; row++) {
+ if (TIFFWriteScanline(out, buf, row, 0) < 0)
+ return (FALSE);
+ buf += scanline;
+ }
+ return (TRUE);
+}
+
+DECLAREwriteFunc(writeBufferToSeparateStrips)
+{
+ u_char *obuf = (u_char *) _TIFFmalloc(TIFFScanlineSize(out));
+ tsample_t s;
+
+ if (obuf == NULL)
+ return (0);
+ for (s = 0; s < spp; s++) {
+ uint32 row;
+ for (row = 0; row < imagelength; row++) {
+ u_char* inp = buf + s;
+ u_char* outp = obuf;
+ uint32 n = imagewidth;
+
+ while (n-- > 0)
+ *outp++ = *inp, inp += spp;
+ if (TIFFWriteScanline(out, obuf, row, s) < 0) {
+ _TIFFfree(obuf);
+ return (FALSE);
+ }
+ }
+ }
+ _TIFFfree(obuf);
+ return (TRUE);
+
+}
+
+DECLAREwriteFunc(writeBufferToContigTiles)
+{
+ uint32 imagew = TIFFScanlineSize(out);
+ uint32 tilew = TIFFTileRowSize(out);
+ int iskew = imagew - tilew;
+ u_char* obuf = (u_char *) _TIFFmalloc(TIFFTileSize(out));
+ u_char* bufp = 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);
+ int iskew = imagew - tilew;
+ u_char *obuf = (u_char*) _TIFFmalloc(TIFFTileSize(out));
+ u_char *bufp = 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 + s,
+ nrow, width,
+ oskew/spp, oskew + imagew, spp);
+ } else
+ cpContigBufToSeparateBuf(obuf,
+ bufp + colb + s,
+ nrow, tilewidth,
+ 0, iskew, spp);
+ if (TIFFWriteTile(out, obuf, col, row, 0, s) < 0) {
+ _TIFFfree(obuf);
+ return (FALSE);
+ }
+ }
+ colb += tilew;
+ }
+ bufp += nrow * imagew;
+ }
+ _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..6634b1b8
--- /dev/null
+++ b/tools/tiffdither.c
@@ -0,0 +1,317 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffdither.c,v 1.24 1995/06/30 00:27:07 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#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..28db9651
--- /dev/null
+++ b/tools/tiffdump.c
@@ -0,0 +1,725 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffdump.c,v 1.44 1995/07/19 00:39:51 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#if defined(VMS)
+#include <unixio.h>
+#include <file.h>
+#elif defined(_WINDOWS)
+#include <io.h>
+#define off_t toff_t
+#include "tiffio.h"
+#include <fcntl.h>
+#elif defined(applec)
+#define open _open_ /* to avoid conflicts */
+#include <fcntl.h>
+#undef open
+int open(const char*, int, int);
+typedef unsigned int off_t;
+#else /* !VMS && !_WINDOWS */
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+#if defined(MSDOS)
+#include <malloc.h>
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "tiffio.h"
+
+char *curfile;
+int swabflag;
+int bigendian;
+int typeshift[13]; /* data type shift counts */
+long typemask[13]; /* data type masks */
+
+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;
+
+int
+main(int argc, char* argv[])
+{
+ int one = 1, fd;
+ int multiplefiles = (argc > 1);
+ int c;
+ uint32 diroff = (uint32) 0;
+ bigendian = (*(char *)&one == 0);
+
+ while ((c = getopt(argc, argv, "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;
+ default:
+ fprintf(stderr, "usage: %s [-h] [files]\n", argv[0]);
+ return (-1);
+ }
+ }
+ 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,
+ off, off, nextdiroff, 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("%u<", 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_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))
+ 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_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_JBIGOPTIONS, "JBIG Options" },
+};
+#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 <ctype.h>
+
+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
+ fprintf(fd, "\\%03o", *cp);
+ }
+}
+
+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,
+ lp[0], 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,
+ lp[0], 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:
+ TIFFSwabArrayOfLong((uint32*) cp,
+ dir->tdir_count);
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_DOUBLE:
+ TIFFSwabArrayOfLong((uint32*) cp,
+ 2*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 <stdarg.h>
+
+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..7851dde0
--- /dev/null
+++ b/tools/tiffinfo.c
@@ -0,0 +1,428 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffinfo.c,v 1.24 1995/06/12 15:43:49 sam Exp $ */
+
+/*
+ * Copyright (c) 1988-1995 Sam Leffler
+ * Copyright (c) 1991-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#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;
+
+ while ((c = getopt(argc, argv, "f:o:cdDSjlmrsvw0123456789")) != -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 '?':
+ 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], "r");
+ 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",
+" -# 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..b44c8656
--- /dev/null
+++ b/tools/tiffmedian.c
@@ -0,0 +1,891 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffmedian.c,v 1.17 1995/07/01 01:16:55 sam 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
+ */
+
+#if defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#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<<B_DEPTH)
+
+#define C_DEPTH 2
+#define C_LEN (1L<<C_DEPTH) /* # cells/color to use */
+
+#define COLOR_SHIFT (COLOR_DEPTH-B_DEPTH)
+
+typedef struct colorbox {
+ struct colorbox *next, *prev;
+ int rmin, rmax;
+ int gmin, gmax;
+ int bmin, bmax;
+ int total;
+} Colorbox;
+
+typedef struct {
+ int num_ents;
+ int entries[MAX_CMAP_SIZE][2];
+} C_cell;
+
+uint16 rm[MAX_CMAP_SIZE], gm[MAX_CMAP_SIZE], bm[MAX_CMAP_SIZE];
+int bytes_per_pixel;
+int num_colors;
+int histogram[B_LEN][B_LEN][B_LEN];
+Colorbox *freeboxes;
+Colorbox *usedboxes;
+C_cell **ColorCells;
+TIFF *in, *out;
+uint32 rowsperstrip = (uint32) -1;
+uint16 compression = (uint16) -1;
+uint16 bitspersample = 1;
+uint16 samplesperpixel;
+uint32 imagewidth;
+uint32 imagelength;
+uint16 predictor = 0;
+
+static void get_histogram(TIFF*, Colorbox*);
+static void splitbox(Colorbox*);
+static void shrinkbox(Colorbox*);
+static void map_colortable(void);
+static void quant(TIFF*, TIFF*);
+static void quant_fsdither(TIFF*, TIFF*);
+static Colorbox* largest_box(void);
+
+static void usage(void);
+static int processCompressOptions(char*);
+
+#define CopyField(tag, v) \
+ if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
+
+int
+main(int argc, char* argv[])
+{
+ int i, dither = 0;
+ uint16 shortv, config, photometric;
+ Colorbox *box_list, *ptr;
+ float floatv;
+ uint32 longv;
+ int c;
+ extern int optind;
+ extern char* optarg;
+
+ num_colors = MAX_CMAP_SIZE;
+ while ((c = getopt(argc, argv, "c:C:r:f")) != -1)
+ switch (c) {
+ case 'c': /* compression scheme */
+ if (!processCompressOptions(optarg))
+ usage();
+ break;
+ case 'C': /* set colormap size */
+ num_colors = atoi(optarg);
+ if (num_colors > 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);
+ 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..4a976794
--- /dev/null
+++ b/tools/tiffsplit.c
@@ -0,0 +1,230 @@
+/* $Header: /usr/people/sam/tiff/tools/RCS/tiffsplit.c,v 1.11 1995/06/06 23:45:26 sam Exp $ */
+
+/*
+ * Copyright (c) 1992-1995 Sam Leffler
+ * Copyright (c) 1992-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 defined(unix) || defined(__unix)
+#include "port.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#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..065d62ed
--- /dev/null
+++ b/tools/ycbcr.c
@@ -0,0 +1,159 @@
+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); }
+
+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)
+
+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);
+}