1*0ef31e1fSMike Welles<HTML> 2*0ef31e1fSMike Welles<HEAD> 3*0ef31e1fSMike Welles<TITLE> 4*0ef31e1fSMike WellesModifying The TIFF Library 5*0ef31e1fSMike Welles</TITLE> 6*0ef31e1fSMike Welles</HEAD> 7*0ef31e1fSMike Welles 8*0ef31e1fSMike Welles<H1> 9*0ef31e1fSMike Welles<IMG SRC=images/dave.gif WIDTH=107 HEIGHT=148 BORDER=2 ALIGN=left HSPACE=6> 10*0ef31e1fSMike WellesModifying The TIFF Library 11*0ef31e1fSMike Welles</H1> 12*0ef31e1fSMike Welles 13*0ef31e1fSMike Welles 14*0ef31e1fSMike Welles<P> 15*0ef31e1fSMike WellesThis chapter provides information about the internal structure of 16*0ef31e1fSMike Wellesthe library, how to control the configuration when building it, and 17*0ef31e1fSMike Welleshow to add new support to the library. 18*0ef31e1fSMike WellesThe following sections are found in this chapter: 19*0ef31e1fSMike Welles 20*0ef31e1fSMike Welles<UL> 21*0ef31e1fSMike Welles<LI><A HREF=#Config>Library Configuration</A> 22*0ef31e1fSMike Welles<LI><A HREF=#Portability>General Portability Comments</A> 23*0ef31e1fSMike Welles<LI><A HREF="#Types">Types and Portability</A> 24*0ef31e1fSMike Welles<LI><A HREF=#AddingTags>Adding New Tags</A> 25*0ef31e1fSMike Welles<LI><A HREF=#AddingCODECS>Adding New Builtin Codecs</A> 26*0ef31e1fSMike Welles<LI><A HREF=#AddingCODECTags>Adding New Codec-private Tags</A> 27*0ef31e1fSMike Welles<LI><A HREF=#Other>Other Comments</A> 28*0ef31e1fSMike Welles</UL> 29*0ef31e1fSMike Welles 30*0ef31e1fSMike Welles 31*0ef31e1fSMike Welles<A NAME="Config"><P><HR WIDTH=65% ALIGN=right><H3>Library Configuration</H3></A> 32*0ef31e1fSMike Welles 33*0ef31e1fSMike WellesInformation on compiling the library is given 34*0ef31e1fSMike Welles<A HREF=build.html>elsewhere in this documentation</A>. 35*0ef31e1fSMike WellesThis section describes the low-level mechanisms used to control 36*0ef31e1fSMike Wellesthe optional parts of the library that are configured at build 37*0ef31e1fSMike Wellestime. Control is based on 38*0ef31e1fSMike Wellesa collection of C defines that are specified either on the compiler 39*0ef31e1fSMike Wellescommand line or in a configuration file such as <TT>port.h</TT> 40*0ef31e1fSMike Welles(as generated by the <TT>configure</TT> script for UNIX systems) 41*0ef31e1fSMike Wellesor <B>tiffconf.h</B>. 42*0ef31e1fSMike Welles 43*0ef31e1fSMike Welles<P> 44*0ef31e1fSMike WellesConfiguration defines are split into three areas: 45*0ef31e1fSMike Welles<UL> 46*0ef31e1fSMike Welles<LI>those that control which compression schemes are 47*0ef31e1fSMike Welles configured as part of the builtin codecs, 48*0ef31e1fSMike Welles<LI>those that control support for groups of tags that 49*0ef31e1fSMike Welles are considered optional, and 50*0ef31e1fSMike Welles<LI>those that control operating system or machine-specific support. 51*0ef31e1fSMike Welles</UL> 52*0ef31e1fSMike Welles 53*0ef31e1fSMike Welles<P> 54*0ef31e1fSMike WellesIf the define <TT>COMPRESSION_SUPPORT</TT> is <STRONG>not defined</STRONG> 55*0ef31e1fSMike Wellesthen a default set of compression schemes is automatically 56*0ef31e1fSMike Wellesconfigured: 57*0ef31e1fSMike Welles<UL> 58*0ef31e1fSMike Welles<LI>CCITT Group 3 and 4 algorithms (compression codes 2, 3, 4, and 32771), 59*0ef31e1fSMike Welles<LI>the Macintosh PackBits algorithm (compression 32773), 60*0ef31e1fSMike Welles<LI>a Lempel-Ziv & Welch (LZW) algorithm (compression 5), 61*0ef31e1fSMike Welles<LI>a 4-bit run-length encoding scheme from ThunderScan (compression 32809), 62*0ef31e1fSMike Welles<LI>a 2-bit encoding scheme used by NeXT (compression 32766), and 63*0ef31e1fSMike Welles<LI>two experimental schemes intended for images with high dynamic range 64*0ef31e1fSMike Welles(compression 34676 and 34677). 65*0ef31e1fSMike Welles</UL> 66*0ef31e1fSMike Welles 67*0ef31e1fSMike WellesTo override this behaviour define <TT>COMPRESSION_SUPPORT</TT> 68*0ef31e1fSMike Wellesand then one or more additional defines to enable configuration of 69*0ef31e1fSMike Wellesthe appropriate codecs (see the table below); e.g. 70*0ef31e1fSMike Welles 71*0ef31e1fSMike Welles<UL><PRE> 72*0ef31e1fSMike Welles#define COMPRESSION_SUPPORT 73*0ef31e1fSMike Welles#define CCITT_SUPPORT 74*0ef31e1fSMike Welles#define PACKBITS_SUPPORT 75*0ef31e1fSMike Welles</PRE></UL> 76*0ef31e1fSMike Welles 77*0ef31e1fSMike WellesSeveral other compression schemes are configured separately from 78*0ef31e1fSMike Wellesthe default set because they depend on ancillary software 79*0ef31e1fSMike Wellespackages that are not distributed with <TT>libtiff</TT>. 80*0ef31e1fSMike Welles 81*0ef31e1fSMike Welles<P> 82*0ef31e1fSMike WellesSupport for JPEG compression is controlled by <TT>JPEG_SUPPORT</TT>. 83*0ef31e1fSMike WellesThe JPEG codec that comes with <TT>libtiff</TT> is designed for 84*0ef31e1fSMike Wellesuse with release 5 or later of the Independent JPEG Group's freely 85*0ef31e1fSMike Wellesavailable software distribution. 86*0ef31e1fSMike WellesThis software can be retrieved from the directory 87*0ef31e1fSMike Welles<A HREF=ftp://ftp.uu.net/graphics/jpeg>ftp.uu.net:/graphics/jpeg/</A>. 88*0ef31e1fSMike Welles 89*0ef31e1fSMike Welles 90*0ef31e1fSMike Welles<P> 91*0ef31e1fSMike Welles<IMG SRC="images/info.gif" ALT="NOTE: " ALIGN=left HSPACE=8> 92*0ef31e1fSMike Welles<EM>Enabling JPEG support automatically enables support for 93*0ef31e1fSMike Wellesthe TIFF 6.0 colorimetry and YCbCr-related tags.</EM> 94*0ef31e1fSMike Welles 95*0ef31e1fSMike Welles<P> 96*0ef31e1fSMike WellesExperimental support for the deflate algorithm is controlled by 97*0ef31e1fSMike Welles<TT>DEFLATE_SUPPORT</TT>. 98*0ef31e1fSMike WellesThe deflate codec that comes with <TT>libtiff</TT> is designed 99*0ef31e1fSMike Wellesfor use with version 0.99 or later of the freely available 100*0ef31e1fSMike Welles<TT>libz</TT> library written by Jean-loup Gailly and Mark Adler. 101*0ef31e1fSMike WellesThe data format used by this library is described 102*0ef31e1fSMike Wellesin the files 103*0ef31e1fSMike Welles<A HREF=ftp://ftp.uu.net/pub/archiving/zip/doc/zlib-3.1.doc>zlib-3.1.doc</A>, 104*0ef31e1fSMike Wellesand 105*0ef31e1fSMike Welles<A HREF=ftp://ftp.uu.net/pub/archiving/zip/doc/deflate-1.1.doc>deflate-1.1.doc</A>, 106*0ef31e1fSMike Wellesavailable in the directory 107*0ef31e1fSMike Welles<A HREF=ftp://ftp.uu.net/pub/archiving/zip/doc>ftp.uu.net:/pub/archiving/zip/doc</A>.</EM> 108*0ef31e1fSMike WellesThe library can be retried from the directory 109*0ef31e1fSMike Welles<A HREF=ftp://ftp.uu.net/pub/archiving/zip/zlib/>ftp.uu.net:/pub/archiving/zip/zlib/</A> 110*0ef31e1fSMike Welles(or try <A HREF=ftp://quest.jpl.nasa.gov/beta/zlib/>quest.jpl.nasa.gov:/beta/zlib/</A>). 111*0ef31e1fSMike Welles 112*0ef31e1fSMike Welles<P> 113*0ef31e1fSMike Welles<IMG SRC="images/warning.gif" ALT="NOTE: " ALIGN=left HSPACE=8 VSPACE=6> 114*0ef31e1fSMike Welles<EM>The deflate algorithm is experimental. Do not expect 115*0ef31e1fSMike Wellesto exchange files using this compression scheme; 116*0ef31e1fSMike Wellesit is included only because the similar, and more common, 117*0ef31e1fSMike WellesLZW algorithm is claimed to be governed by licensing restrictions.</EM> 118*0ef31e1fSMike Welles 119*0ef31e1fSMike Welles 120*0ef31e1fSMike Welles<P> 121*0ef31e1fSMike WellesBy default <B>tiffconf.h</B> defines 122*0ef31e1fSMike Welles<TT>COLORIMETRY_SUPPORT</TT>, 123*0ef31e1fSMike Welles<TT>YCBCR_SUPPORT</TT>, 124*0ef31e1fSMike Wellesand 125*0ef31e1fSMike Welles<TT>CMYK_SUPPORT</TT>. 126*0ef31e1fSMike Welles 127*0ef31e1fSMike Welles<P> 128*0ef31e1fSMike Welles<TABLE BORDER CELLPADDING=3> 129*0ef31e1fSMike Welles 130*0ef31e1fSMike Welles<TR><TH ALIGN=left>Define</TH><TH ALIGN=left>Description</TH></TR> 131*0ef31e1fSMike Welles 132*0ef31e1fSMike Welles<TR> 133*0ef31e1fSMike Welles<TD VALIGN=top><TT>CCITT_SUPPORT</TT></TD> 134*0ef31e1fSMike Welles<TD>CCITT Group 3 and 4 algorithms (compression codes 2, 3, 4, 135*0ef31e1fSMike Welles and 32771)</TD> 136*0ef31e1fSMike Welles</TR> 137*0ef31e1fSMike Welles 138*0ef31e1fSMike Welles<TR> 139*0ef31e1fSMike Welles<TD VALIGN=top><TT>PACKBITS_SUPPORT</TT></TD> 140*0ef31e1fSMike Welles<TD>Macintosh PackBits algorithm (compression 32773)</TD> 141*0ef31e1fSMike Welles</TR> 142*0ef31e1fSMike Welles 143*0ef31e1fSMike Welles<TR> 144*0ef31e1fSMike Welles<TD VALIGN=top><TT>LZW_SUPPORT</TT></TD> 145*0ef31e1fSMike Welles<TD>Lempel-Ziv & Welch (LZW) algorithm (compression 5)</TD> 146*0ef31e1fSMike Welles</TR> 147*0ef31e1fSMike Welles 148*0ef31e1fSMike Welles<TR> 149*0ef31e1fSMike Welles<TD VALIGN=top><TT>THUNDER_SUPPORT</TT></TD> 150*0ef31e1fSMike Welles<TD>4-bit 151*0ef31e1fSMike Wellesrun-length encoding scheme from ThunderScan (compression 32809)</TD> 152*0ef31e1fSMike Welles</TR> 153*0ef31e1fSMike Welles 154*0ef31e1fSMike Welles<TR> 155*0ef31e1fSMike Welles<TD VALIGN=top><TT>NEXT_SUPPORT</TT></TD> 156*0ef31e1fSMike Welles<TD>2-bit encoding scheme used by NeXT (compression 32766)</TD> 157*0ef31e1fSMike Welles</TR> 158*0ef31e1fSMike Welles 159*0ef31e1fSMike Welles<TR> 160*0ef31e1fSMike Welles<TD VALIGN=top><TT>OJPEG_SUPPORT</TT></TD> 161*0ef31e1fSMike Welles<TD>obsolete JPEG scheme defined in the 6.0 spec (compression 6)</TD> 162*0ef31e1fSMike Welles</TR> 163*0ef31e1fSMike Welles 164*0ef31e1fSMike Welles<TR> 165*0ef31e1fSMike Welles<TD VALIGN=top><TT>JPEG_SUPPORT</TT></TD> 166*0ef31e1fSMike Welles<TD>current JPEG scheme defined in TTN2 (compression 7)</TD> 167*0ef31e1fSMike Welles</TR> 168*0ef31e1fSMike Welles 169*0ef31e1fSMike Welles<TR> 170*0ef31e1fSMike Welles<TD VALIGN=top><TT>ZIP_SUPPORT</TT></TD> 171*0ef31e1fSMike Welles<TD>experimental Deflate scheme (compression 32946)</TD> 172*0ef31e1fSMike Welles</TR> 173*0ef31e1fSMike Welles 174*0ef31e1fSMike Welles<TR> 175*0ef31e1fSMike Welles<TD VALIGN=top><TT>PIXARLOG_SUPPORT</TT></TD> 176*0ef31e1fSMike Welles<TD>Pixar's compression scheme for high-resolution color images (compression 32909)</TD> 177*0ef31e1fSMike Welles</TR> 178*0ef31e1fSMike Welles 179*0ef31e1fSMike Welles<TR> 180*0ef31e1fSMike Welles<TD VALIGN=top><TT>SGILOG_SUPPORT</TT></TD> 181*0ef31e1fSMike Welles<TD>SGI's compression scheme for high-resolution color images (compression 34676 and 34677)</TD> 182*0ef31e1fSMike Welles</TR> 183*0ef31e1fSMike Welles 184*0ef31e1fSMike Welles<TR> 185*0ef31e1fSMike Welles<TD VALIGN=top><TT>COLORIMETRY_SUPPORT</TT></TD> 186*0ef31e1fSMike Welles<TD>support for the TIFF 6.0 colorimetry tags</TD> 187*0ef31e1fSMike Welles</TR> 188*0ef31e1fSMike Welles 189*0ef31e1fSMike Welles<TR> 190*0ef31e1fSMike Welles<TD VALIGN=top><TT>YCBCR_SUPPORT</TT></TD> 191*0ef31e1fSMike Welles<TD>support for the TIFF 6.0 YCbCr-related tags</TD> 192*0ef31e1fSMike Welles</TR> 193*0ef31e1fSMike Welles 194*0ef31e1fSMike Welles<TR> 195*0ef31e1fSMike Welles<TD VALIGN=top><TT>CMYK_SUPPORT</TT></TD> 196*0ef31e1fSMike Welles<TD>support for the TIFF 6.0 CMYK-related tags</TD> 197*0ef31e1fSMike Welles</TR> 198*0ef31e1fSMike Welles 199*0ef31e1fSMike Welles<TR> 200*0ef31e1fSMike Welles<TD VALIGN=top><TT>ICC_SUPPORT</TT></TD> 201*0ef31e1fSMike Welles<TD>support for the ICC Profile tag; see 202*0ef31e1fSMike Welles<I>The ICC Profile Format Specification</I>, 203*0ef31e1fSMike WellesAnnex B.3 "Embedding ICC Profiles in TIFF Files"; 204*0ef31e1fSMike Wellesavailable at 205*0ef31e1fSMike Welles<A HREF=http://www.color.org>http://www.color.org</A> 206*0ef31e1fSMike Welles</TD> 207*0ef31e1fSMike Welles</TR> 208*0ef31e1fSMike Welles 209*0ef31e1fSMike Welles</TABLE> 210*0ef31e1fSMike Welles 211*0ef31e1fSMike Welles 212*0ef31e1fSMike Welles<A NAME="Portability"><P><HR WIDTH=65% ALIGN=right><H3>General Portability Comments</H3></A> 213*0ef31e1fSMike Welles 214*0ef31e1fSMike WellesThis software is developed on Silicon Graphics UNIX 215*0ef31e1fSMike Wellessystems (big-endian, MIPS CPU, 32-bit ints, 216*0ef31e1fSMike WellesIEEE floating point). 217*0ef31e1fSMike WellesThe <TT>configure</TT> shell script generates the appropriate 218*0ef31e1fSMike Wellesinclude files and make files for UNIX systems. 219*0ef31e1fSMike WellesMakefiles exist for non-UNIX platforms that the 220*0ef31e1fSMike Wellescode runs on -- this work has mostly been done by other people. 221*0ef31e1fSMike Welles 222*0ef31e1fSMike Welles<P> 223*0ef31e1fSMike WellesIn general, the code is guaranteed to work only on SGI machines. 224*0ef31e1fSMike WellesIn practice it is highly portable to any 32-bit or 64-bit system and much 225*0ef31e1fSMike Welleswork has been done to insure portability to 16-bit systems. 226*0ef31e1fSMike WellesIf you encounter portability problems please return fixes so 227*0ef31e1fSMike Wellesthat future distributions can be improved. 228*0ef31e1fSMike Welles 229*0ef31e1fSMike Welles<P> 230*0ef31e1fSMike WellesThe software is written to assume an ANSI C compilation environment. 231*0ef31e1fSMike WellesIf your compiler does not support ANSI function prototypes, <TT>const</TT>, 232*0ef31e1fSMike Wellesand <TT><stdarg.h></TT> then you will have to make modifications to the 233*0ef31e1fSMike Wellessoftware. In the past I have tried to support compilers without <TT>const</TT> 234*0ef31e1fSMike Wellesand systems without <TT><stdarg.h></TT>, but I am 235*0ef31e1fSMike Welles<EM>no longer interested in these 236*0ef31e1fSMike Wellesantiquated environments</EM>. With the general availability of 237*0ef31e1fSMike Wellesthe freely available GCC compiler, I 238*0ef31e1fSMike Wellessee no reason to incorporate modifications to the software for these 239*0ef31e1fSMike Wellespurposes. 240*0ef31e1fSMike Welles 241*0ef31e1fSMike Welles<P> 242*0ef31e1fSMike WellesAn effort has been made to isolate as many of the 243*0ef31e1fSMike Wellesoperating system-dependencies 244*0ef31e1fSMike Wellesas possible in two files: <B>tiffcomp.h</B> and 245*0ef31e1fSMike Welles<B>libtiff/tif_<os>.c</B>. The latter file contains 246*0ef31e1fSMike Wellesoperating system-specific routines to do I/O and I/O-related operations. 247*0ef31e1fSMike WellesThe UNIX (<B>tif_unix.c</B>), 248*0ef31e1fSMike WellesMacintosh (<B>tif_apple.c</B>), 249*0ef31e1fSMike Wellesand VMS (<B>tif_vms.c</B>) 250*0ef31e1fSMike Wellescode has had the most use; 251*0ef31e1fSMike Wellesthe MS/DOS support (<B>tif_msdos.c</B>) assumes 252*0ef31e1fSMike Wellessome level of UNIX system call emulation (i.e. 253*0ef31e1fSMike Welles<TT>open</TT>, 254*0ef31e1fSMike Welles<TT>read</TT>, 255*0ef31e1fSMike Welles<TT>write</TT>, 256*0ef31e1fSMike Welles<TT>fstat</TT>, 257*0ef31e1fSMike Welles<TT>malloc</TT>, 258*0ef31e1fSMike Welles<TT>free</TT>). 259*0ef31e1fSMike Welles 260*0ef31e1fSMike Welles<P> 261*0ef31e1fSMike WellesNative CPU byte order is determined on the fly by 262*0ef31e1fSMike Wellesthe library and does not need to be specified. 263*0ef31e1fSMike WellesThe <TT>HOST_FILLORDER</TT> and <TT>HOST_BIGENDIAN</TT> 264*0ef31e1fSMike Wellesdefinitions are not currently used, but may be employed by 265*0ef31e1fSMike Wellescodecs for optimization purposes. 266*0ef31e1fSMike Welles 267*0ef31e1fSMike Welles<P> 268*0ef31e1fSMike WellesThe following defines control general portability: 269*0ef31e1fSMike Welles 270*0ef31e1fSMike Welles<P> 271*0ef31e1fSMike Welles<TABLE BORDER CELLPADDING=3 WIDTH=100%> 272*0ef31e1fSMike Welles 273*0ef31e1fSMike Welles<TR> 274*0ef31e1fSMike Welles<TD VALIGN=top><TT>BSDTYPES</TT></TD> 275*0ef31e1fSMike Welles<TD>Define this if your system does NOT define the 276*0ef31e1fSMike Welles usual BSD typedefs: <TT>u_char</TT>, 277*0ef31e1fSMike Welles <TT>u_short</TT>, <TT>u_int</TT>, <TT>u_long</TT>.</TD> 278*0ef31e1fSMike Welles</TR> 279*0ef31e1fSMike Welles 280*0ef31e1fSMike Welles<TR> 281*0ef31e1fSMike Welles<TD VALIGN=top><TT>HAVE_IEEEFP</TT></TD> 282*0ef31e1fSMike Welles<TD>Define this as 0 or 1 according to the floating point 283*0ef31e1fSMike Welles format suported by the machine. If your machine does 284*0ef31e1fSMike Welles not support IEEE floating point then you will need to 285*0ef31e1fSMike Welles add support to tif_machdep.c to convert between the 286*0ef31e1fSMike Welles native format and IEEE format.</TD> 287*0ef31e1fSMike Welles</TR> 288*0ef31e1fSMike Welles 289*0ef31e1fSMike Welles<TR> 290*0ef31e1fSMike Welles<TD VALIGN=top><TT>HAVE_MMAP</TT></TD> 291*0ef31e1fSMike Welles<TD>Define this if there is <I>mmap-style</I> support for 292*0ef31e1fSMike Wellesmapping files into memory (used only to read data).</TD> 293*0ef31e1fSMike Welles</TR> 294*0ef31e1fSMike Welles 295*0ef31e1fSMike Welles<TR> 296*0ef31e1fSMike Welles<TD VALIGN=top><TT>HOST_FILLORDER</TT></TD> 297*0ef31e1fSMike Welles<TD>Define the native CPU bit order: one of <TT>FILLORDER_MSB2LSB</TT> 298*0ef31e1fSMike Welles or <TT>FILLORDER_LSB2MSB</TT></TD> 299*0ef31e1fSMike Welles</TR> 300*0ef31e1fSMike Welles 301*0ef31e1fSMike Welles<TR> 302*0ef31e1fSMike Welles<TD VALIGN=top><TT>HOST_BIGENDIAN</TT></TD> 303*0ef31e1fSMike Welles<TD>Define the native CPU byte order: 1 if big-endian (Motorola) 304*0ef31e1fSMike Welles or 0 if little-endian (Intel); this may be used 305*0ef31e1fSMike Welles in codecs to optimize code</TD> 306*0ef31e1fSMike Welles</TR> 307*0ef31e1fSMike Welles</TABLE> 308*0ef31e1fSMike Welles 309*0ef31e1fSMike Welles<P> 310*0ef31e1fSMike WellesOn UNIX systems <TT>HAVE_MMAP</TT> is defined through the running of 311*0ef31e1fSMike Wellesthe <TT>configure</TT> script; otherwise support for memory-mapped 312*0ef31e1fSMike Wellesfiles is disabled. 313*0ef31e1fSMike WellesNote that <B>tiffcomp.h</B> defines <TT>HAVE_IEEEFP</TT> to be 314*0ef31e1fSMike Welles1 (<TT>BSDTYPES</TT> is not defined). 315*0ef31e1fSMike Welles 316*0ef31e1fSMike Welles 317*0ef31e1fSMike Welles<A NAME="Types"><P><HR WIDTH=65% ALIGN=right><H3>Types and Portability</H3></A> 318*0ef31e1fSMike Welles 319*0ef31e1fSMike WellesThe software makes extensive use of C typedefs to promote portability. 320*0ef31e1fSMike WellesTwo sets of typedefs are used, one for communication with clients 321*0ef31e1fSMike Wellesof the library and one for internal data structures and parsing of the 322*0ef31e1fSMike WellesTIFF format. There are interactions between these two to be careful 323*0ef31e1fSMike Wellesof, but for the most part you should be able to deal with portability 324*0ef31e1fSMike Wellespurely by fiddling with the following machine-dependent typedefs: 325*0ef31e1fSMike Welles 326*0ef31e1fSMike Welles 327*0ef31e1fSMike Welles<P> 328*0ef31e1fSMike Welles<TABLE BORDER CELLPADDING=3 WIDTH=100%> 329*0ef31e1fSMike Welles 330*0ef31e1fSMike Welles<TR> 331*0ef31e1fSMike Welles<TD>uint8</TD> 332*0ef31e1fSMike Welles<TD>8-bit unsigned integer</TD> 333*0ef31e1fSMike Welles<TD>tiff.h</TD> 334*0ef31e1fSMike Welles</TR> 335*0ef31e1fSMike Welles 336*0ef31e1fSMike Welles<TR> 337*0ef31e1fSMike Welles<TD>int8</TD> 338*0ef31e1fSMike Welles<TD>8-bit signed integer</TD> 339*0ef31e1fSMike Welles<TD>tiff.h</TD> 340*0ef31e1fSMike Welles</TR> 341*0ef31e1fSMike Welles 342*0ef31e1fSMike Welles<TR> 343*0ef31e1fSMike Welles<TD>uint16</TD> 344*0ef31e1fSMike Welles<TD>16-bit unsigned integer</TD> 345*0ef31e1fSMike Welles<TD>tiff.h</TD> 346*0ef31e1fSMike Welles</TR> 347*0ef31e1fSMike Welles 348*0ef31e1fSMike Welles<TR> 349*0ef31e1fSMike Welles<TD>int16</TD> 350*0ef31e1fSMike Welles<TD>16-bit signed integer</TD> 351*0ef31e1fSMike Welles<TD>tiff.h</TD> 352*0ef31e1fSMike Welles</TR> 353*0ef31e1fSMike Welles 354*0ef31e1fSMike Welles<TR> 355*0ef31e1fSMike Welles<TD>uint32</TD> 356*0ef31e1fSMike Welles<TD>32-bit unsigned integer</TD> 357*0ef31e1fSMike Welles<TD>tiff.h</TD> 358*0ef31e1fSMike Welles</TR> 359*0ef31e1fSMike Welles 360*0ef31e1fSMike Welles<TR> 361*0ef31e1fSMike Welles<TD>int32</TD> 362*0ef31e1fSMike Welles<TD>32-bit signed integer</TD> 363*0ef31e1fSMike Welles<TD>tiff.h</TD> 364*0ef31e1fSMike Welles</TR> 365*0ef31e1fSMike Welles 366*0ef31e1fSMike Welles<TR> 367*0ef31e1fSMike Welles<TD>dblparam_t</TD> 368*0ef31e1fSMike Welles<TD>promoted type for floats</TD> 369*0ef31e1fSMike Welles<TD>tiffcomp.h</TD> 370*0ef31e1fSMike Welles</TR> 371*0ef31e1fSMike Welles 372*0ef31e1fSMike Welles</TABLE> 373*0ef31e1fSMike Welles 374*0ef31e1fSMike Welles<P> 375*0ef31e1fSMike Welles(to clarify <TT>dblparam_t</TT>, it is the type that float parameters are 376*0ef31e1fSMike Wellespromoted to when passed by value in a function call.) 377*0ef31e1fSMike Welles 378*0ef31e1fSMike Welles<P> 379*0ef31e1fSMike WellesThe following typedefs are used throughout the library and interfaces 380*0ef31e1fSMike Wellesto refer to certain objects whose size is dependent on the TIFF image 381*0ef31e1fSMike Wellesstructure: 382*0ef31e1fSMike Welles 383*0ef31e1fSMike Welles 384*0ef31e1fSMike Welles<P> 385*0ef31e1fSMike Welles<TABLE BORDER CELLPADDING=3 WIDTH=100%> 386*0ef31e1fSMike Welles 387*0ef31e1fSMike Welles<TR> 388*0ef31e1fSMike Welles<TD WIDTH=25%>typedef unsigned int ttag_t;</TD> <TD>directory tag</TD> 389*0ef31e1fSMike Welles</TR> 390*0ef31e1fSMike Welles 391*0ef31e1fSMike Welles<TR> 392*0ef31e1fSMike Welles<TD>typedef uint16 tdir_t;</TD> <TD>directory index</TD> 393*0ef31e1fSMike Welles</TR> 394*0ef31e1fSMike Welles 395*0ef31e1fSMike Welles<TR> 396*0ef31e1fSMike Welles<TD>typedef uint16 tsample_t;</TD> <TD>sample number</TD> 397*0ef31e1fSMike Welles</TR> 398*0ef31e1fSMike Welles 399*0ef31e1fSMike Welles<TR> 400*0ef31e1fSMike Welles<TD>typedef uint32 tstrip_t;</TD> <TD>strip number</TD> 401*0ef31e1fSMike Welles</TR> 402*0ef31e1fSMike Welles 403*0ef31e1fSMike Welles<TR> 404*0ef31e1fSMike Welles<TD>typedef uint32 ttile_t;</TD> <TD>tile number</TD> 405*0ef31e1fSMike Welles</TR> 406*0ef31e1fSMike Welles 407*0ef31e1fSMike Welles<TR> 408*0ef31e1fSMike Welles<TD>typedef int32 tsize_t;</TD> <TD>i/o size in bytes</TD> 409*0ef31e1fSMike Welles</TR> 410*0ef31e1fSMike Welles 411*0ef31e1fSMike Welles<TR> 412*0ef31e1fSMike Welles<TD>typedef void* tdata_t;</TD> <TD>image data ref</TD> 413*0ef31e1fSMike Welles</TR> 414*0ef31e1fSMike Welles 415*0ef31e1fSMike Welles<TR> 416*0ef31e1fSMike Welles<TD>typedef void* thandle_t;</TD> <TD>client data handle</TD> 417*0ef31e1fSMike Welles</TR> 418*0ef31e1fSMike Welles 419*0ef31e1fSMike Welles<TR> 420*0ef31e1fSMike Welles<TD>typedef int32 toff_t;</TD> <TD>file offset (should be off_t)</TD> 421*0ef31e1fSMike Welles</TR> 422*0ef31e1fSMike Welles 423*0ef31e1fSMike Welles<TR> 424*0ef31e1fSMike Welles<TD>typedef unsigned char* tidata_t;</TD> <TD>internal image data</TD> 425*0ef31e1fSMike Welles</TR> 426*0ef31e1fSMike Welles 427*0ef31e1fSMike Welles</TABLE> 428*0ef31e1fSMike Welles 429*0ef31e1fSMike Welles<P> 430*0ef31e1fSMike WellesNote that <TT>tstrip_t</TT>, <TT>ttile_t</TT>, and <TT>tsize_t</TT> 431*0ef31e1fSMike Wellesare constrained to be 432*0ef31e1fSMike Wellesno more than 32-bit quantities by 32-bit fields they are stored 433*0ef31e1fSMike Wellesin in the TIFF image. Likewise <TT>tsample_t</TT> is limited by the 16-bit 434*0ef31e1fSMike Wellesfield used to store the <TT>SamplesPerPixel</TT> tag. <TT>tdir_t</TT> 435*0ef31e1fSMike Wellesconstrains 436*0ef31e1fSMike Wellesthe maximum number of IFDs that may appear in an image and may 437*0ef31e1fSMike Wellesbe an arbitrary size (without penalty). <TT>ttag_t</TT> must be either 438*0ef31e1fSMike Welles<TT>int</TT>, <TT>unsigned int</TT>, pointer, or <TT>double</TT> 439*0ef31e1fSMike Wellesbecause the library uses a varargs 440*0ef31e1fSMike Wellesinterface and ANSI C restricts the type of the parameter before an 441*0ef31e1fSMike Wellesellipsis to be a promoted type. <TT>toff_t</TT> is defined as 442*0ef31e1fSMike Welles<TT>int32</TT> because 443*0ef31e1fSMike WellesTIFF file offsets are (unsigned) 32-bit quantities. A signed 444*0ef31e1fSMike Wellesvalue is used because some interfaces return -1 on error (sigh). 445*0ef31e1fSMike WellesFinally, note that <TT>tidata_t</TT> is used internally to the library to 446*0ef31e1fSMike Wellesmanipulate internal data. User-specified data references are 447*0ef31e1fSMike Wellespassed as opaque handles and only cast at the lowest layers where 448*0ef31e1fSMike Wellestheir type is presumed. 449*0ef31e1fSMike Welles 450*0ef31e1fSMike Welles 451*0ef31e1fSMike Welles<P><HR WIDTH=65% ALIGN=right><H3>General Comments</H3></A> 452*0ef31e1fSMike Welles 453*0ef31e1fSMike WellesThe library is designed to hide as much of the details of TIFF from 454*0ef31e1fSMike Wellesapplications as 455*0ef31e1fSMike Wellespossible. In particular, TIFF directories are read in their entirety 456*0ef31e1fSMike Wellesinto an internal format. Only the tags known by the library are 457*0ef31e1fSMike Wellesavailable to a user and certain tag data may be maintained that a user 458*0ef31e1fSMike Wellesdoes not care about (e.g. transfer function tables). 459*0ef31e1fSMike Welles 460*0ef31e1fSMike Welles<A NAME=AddingTags><P><HR WIDTH=65% ALIGN=right><H3>Adding New Tags</H3></A> 461*0ef31e1fSMike Welles 462*0ef31e1fSMike WellesTo add support for a new directory tag you have three options. If your 463*0ef31e1fSMike Wellestag is specific to a compression algorithm, see below. If you have a lot 464*0ef31e1fSMike Wellesof tags you may want to try using Niles Ritter's runtime tag-extension 465*0ef31e1fSMike Wellesscheme in the "contrib/tags" directory, which makes the changes 466*0ef31e1fSMike Wellesorthogonal to the main libtiff code. Otherwise use 467*0ef31e1fSMike Wellesthe following guidelines to add support to the ``core library''. 468*0ef31e1fSMike Welles 469*0ef31e1fSMike Welles<OL> 470*0ef31e1fSMike Welles<LI>Define the tag in <B>tiff.h</B>. 471*0ef31e1fSMike Welles<LI>Add a field to the directory structure in <B>tif_dir.h</B> 472*0ef31e1fSMike Welles and define a <TT>FIELD_*</TT> bit (also update the definition of 473*0ef31e1fSMike Welles <TT>FIELD_CODEC</TT> to reflect your addition). 474*0ef31e1fSMike Welles<LI>Add an entry in the <TT>TIFFFieldInfo</TT> array defined at the top of 475*0ef31e1fSMike Welles <B>tif_dirinfo.c</B>. 476*0ef31e1fSMike Welles Note that you must keep this array sorted by tag 477*0ef31e1fSMike Welles number and that the widest variant entry for a tag should come 478*0ef31e1fSMike Welles first (e.g. <TT>LONG</TT> before <TT>SHORT</TT>). 479*0ef31e1fSMike Welles<LI>Add entries in <TT>_TIFFVSetField()</TT> and <TT>_TIFFVGetField()</TT> 480*0ef31e1fSMike Welles for the new tag. 481*0ef31e1fSMike Welles<LI>(<I>optional</I>) If the value associated with the tag is not a scalar value 482*0ef31e1fSMike Welles (e.g. the array for <TT>TransferFunction</TT>) and requires 483*0ef31e1fSMike Welles special processing, 484*0ef31e1fSMike Welles then add the appropriate code to <TT>TIFFReadDirectory()</TT> and 485*0ef31e1fSMike Welles <TT>TIFFWriteDirectory()</TT>. You're best off finding a similar tag and 486*0ef31e1fSMike Welles cribbing code. 487*0ef31e1fSMike Welles<LI>Add support to <TT>TIFFPrintDirectory()</TT> in <B>tif_print.c</B> 488*0ef31e1fSMike Welles to print the tag's value. 489*0ef31e1fSMike Welles</OL> 490*0ef31e1fSMike Welles 491*0ef31e1fSMike Welles<P> 492*0ef31e1fSMike WellesIf you want to maintain portability, beware of making assumptions 493*0ef31e1fSMike Wellesabout data types. Use the typedefs (<TT>uint16</TT>, etc. when dealing with 494*0ef31e1fSMike Wellesdata on disk and <TT>t*_t</TT> when stuff is in memory) and be careful about 495*0ef31e1fSMike Wellespassing items through printf or similar vararg interfaces. 496*0ef31e1fSMike Welles 497*0ef31e1fSMike Welles<A NAME=AddingCODECS><P><HR WIDTH=65% ALIGN=right><H3>Adding New Builtin Codecs</H3></A> 498*0ef31e1fSMike Welles 499*0ef31e1fSMike WellesTo add builtin support for a new compression algorithm, you can either 500*0ef31e1fSMike Wellesuse the "tag-extension" trick to override the handling of the 501*0ef31e1fSMike WellesTIFF Compression tag (see <A HREF=#AddingTags>Adding New Tags</A>, above), 502*0ef31e1fSMike Wellesor do the following to add support directly to the core library: 503*0ef31e1fSMike Welles 504*0ef31e1fSMike Welles<OL> 505*0ef31e1fSMike Welles<LI>Define the tag value in <B>tiff.h</B>. 506*0ef31e1fSMike Welles<LI>Edit the file <B>tif_codec.c</B> to add an entry to the 507*0ef31e1fSMike Welles _TIFFBuiltinCODECS array (see how other algorithms are handled). 508*0ef31e1fSMike Welles<LI>Add the appropriate function prototype declaration to 509*0ef31e1fSMike Welles <B>tiffiop.h</B> (close to the bottom). 510*0ef31e1fSMike Welles<LI>Create a file with the compression scheme code, by convention files 511*0ef31e1fSMike Welles are named <B>tif_*.c</B> (except perhaps on some systems where the 512*0ef31e1fSMike Welles tif_ prefix pushes some filenames over 14 chars. 513*0ef31e1fSMike Welles<LI>Edit <B>Makefile.in</B> (and any other Makefiles) 514*0ef31e1fSMike Welles to include the new source file. 515*0ef31e1fSMike Welles</OL> 516*0ef31e1fSMike Welles 517*0ef31e1fSMike Welles<P> 518*0ef31e1fSMike WellesA codec, say <TT>foo</TT>, can have many different entry points: 519*0ef31e1fSMike Welles 520*0ef31e1fSMike Welles<PRE> 521*0ef31e1fSMike WellesTIFFInitfoo(tif, scheme)/* initialize scheme and setup entry points in tif */ 522*0ef31e1fSMike WellesfooSetupDecode(tif) /* called once per IFD after tags has been frozen */ 523*0ef31e1fSMike WellesfooPreDecode(tif, sample)/* called once per strip/tile, after data is read, 524*0ef31e1fSMike Welles but before the first row is decoded */ 525*0ef31e1fSMike WellesfooDecode*(tif, bp, cc, sample)/* decode cc bytes of data into the buffer */ 526*0ef31e1fSMike Welles fooDecodeRow(...) /* called to decode a single scanline */ 527*0ef31e1fSMike Welles fooDecodeStrip(...) /* called to decode an entire strip */ 528*0ef31e1fSMike Welles fooDecodeTile(...) /* called to decode an entire tile */ 529*0ef31e1fSMike WellesfooSetupEncode(tif) /* called once per IFD after tags has been frozen */ 530*0ef31e1fSMike WellesfooPreEncode(tif, sample)/* called once per strip/tile, before the first row in 531*0ef31e1fSMike Welles a strip/tile is encoded */ 532*0ef31e1fSMike WellesfooEncode*(tif, bp, cc, sample)/* encode cc bytes of user data (bp) */ 533*0ef31e1fSMike Welles fooEncodeRow(...) /* called to decode a single scanline */ 534*0ef31e1fSMike Welles fooEncodeStrip(...) /* called to decode an entire strip */ 535*0ef31e1fSMike Welles fooEncodeTile(...) /* called to decode an entire tile */ 536*0ef31e1fSMike WellesfooPostEncode(tif) /* called once per strip/tile, just before data is written */ 537*0ef31e1fSMike WellesfooSeek(tif, row) /* seek forwards row scanlines from the beginning 538*0ef31e1fSMike Welles of a strip (row will always be >0 and <rows/strip */ 539*0ef31e1fSMike WellesfooCleanup(tif) /* called when compression scheme is replaced by user */ 540*0ef31e1fSMike Welles</PRE> 541*0ef31e1fSMike Welles 542*0ef31e1fSMike Welles<P> 543*0ef31e1fSMike WellesNote that the encoding and decoding variants are only needed when 544*0ef31e1fSMike Wellesa compression algorithm is dependent on the structure of the data. 545*0ef31e1fSMike WellesFor example, Group 3 2D encoding and decoding maintains a reference 546*0ef31e1fSMike Wellesscanline. The sample parameter identifies which sample is to be 547*0ef31e1fSMike Wellesencoded or decoded if the image is organized with <TT>PlanarConfig</TT>=2 548*0ef31e1fSMike Welles(separate planes). This is important for algorithms such as JPEG. 549*0ef31e1fSMike WellesIf <TT>PlanarConfig</TT>=1 (interleaved), then sample will always be 0. 550*0ef31e1fSMike Welles 551*0ef31e1fSMike Welles 552*0ef31e1fSMike Welles<A NAME=AddingCODECTags><P><HR WIDTH=65% ALIGN=right><H3>Adding New Codec-private Tags</H3></A> 553*0ef31e1fSMike Welles 554*0ef31e1fSMike WellesTo add tags that are meaningful <EM>only when a particular compression 555*0ef31e1fSMike Wellesalgorithm is used</EM> follow these steps: 556*0ef31e1fSMike Welles 557*0ef31e1fSMike Welles<OL> 558*0ef31e1fSMike Welles<LI>Define the tag in <B>tiff.h</B>. 559*0ef31e1fSMike Welles<LI>Allocate storage for the tag values in the private state block of 560*0ef31e1fSMike Welles the codec. 561*0ef31e1fSMike Welles<LI>Insure the state block is created when the codec is initialized. 562*0ef31e1fSMike Welles<LI>At <TT>TIFFInitfoo</TT> time override the method pointers in the 563*0ef31e1fSMike Welles TIFF structure 564*0ef31e1fSMike Welles for getting, setting and printing tag values. For example, 565*0ef31e1fSMike Welles<PRE> 566*0ef31e1fSMike Welles sp->vgetparent = tif->tif_vgetfield; 567*0ef31e1fSMike Welles tif->tif_vgetfield = fooVGetField; /* hook for codec tags */ 568*0ef31e1fSMike Welles sp->vsetparent = tif->tif_vsetfield; 569*0ef31e1fSMike Welles tif->tif_vsetfield = fooVSetField; /* hook for codec tags */ 570*0ef31e1fSMike Welles tif->tif_printdir = fooPrintDir; /* hook for codec tags */ 571*0ef31e1fSMike Welles</PRE> 572*0ef31e1fSMike Welles (Actually you may decide not to override the 573*0ef31e1fSMike Welles <TT>tif_printdir</TT> method, but rather just specify it). 574*0ef31e1fSMike Welles<LI>Create a private <TT>TIFFFieldInfo</TT> array for your tags and 575*0ef31e1fSMike Welles merge them into the core tags at initialization time using 576*0ef31e1fSMike Welles <TT>_TIFFMergeFieldInfo</TT>; e.g. 577*0ef31e1fSMike Welles<PRE> 578*0ef31e1fSMike Welles _TIFFMergeFieldInfo(tif, fooFieldInfo, N(fooFieldInfo)); 579*0ef31e1fSMike Welles</PRE> 580*0ef31e1fSMike Welles (where <TT>N</TT> is a macro used liberaly throughout the distributed code). 581*0ef31e1fSMike Welles<LI>Fill in the get and set routines. Be sure to call the parent method 582*0ef31e1fSMike Welles for tags that you are not handled directly. Also be sure to set the 583*0ef31e1fSMike Welles <TT>FIELD_*</TT> bits for tags that are to be written to the file. Note that 584*0ef31e1fSMike Welles you can create ``pseudo-tags'' by defining tags that are processed 585*0ef31e1fSMike Welles exclusively in the get/set routines and never written to file (see 586*0ef31e1fSMike Welles the handling of <TT>TIFFTAG_FAXMODE</TT> in <B>tif_fax3.c</B> 587*0ef31e1fSMike Welles for an example of this). 588*0ef31e1fSMike Welles<LI>Fill in the print routine, if appropriate. 589*0ef31e1fSMike Welles</OL> 590*0ef31e1fSMike Welles 591*0ef31e1fSMike WellesNote that space has been allocated in the <TT>FIELD_*</TT> bit space for 592*0ef31e1fSMike Wellescodec-private tags. Define your bits as <TT>FIELD_CODEC+<offset></TT> to 593*0ef31e1fSMike Welleskeep them away from the core tags. If you need more tags than there 594*0ef31e1fSMike Wellesis room for, just increase <TT>FIELD_SETLONGS</TT> at the top of 595*0ef31e1fSMike Welles<B>tiffiop.h</B>. 596*0ef31e1fSMike Welles 597*0ef31e1fSMike Welles 598*0ef31e1fSMike Welles<A NAME=Other><P><HR WIDTH=65% ALIGN=right><H3>Other Comments</H3></A> 599*0ef31e1fSMike Welles 600*0ef31e1fSMike WellesThe library handles most I/O buffering. There are two data buffers 601*0ef31e1fSMike Welleswhen decoding data: a raw data buffer that holds all the data in a 602*0ef31e1fSMike Wellesstrip, and a user-supplied scanline buffer that compression schemes 603*0ef31e1fSMike Wellesplace decoded data into. When encoding data the data in the 604*0ef31e1fSMike Wellesuser-supplied scanline buffer is encoded into the raw data buffer (from 605*0ef31e1fSMike Welleswhere it is written). Decoding routines should never have to explicitly 606*0ef31e1fSMike Wellesread data -- a full strip/tile's worth of raw data is read and scanlines 607*0ef31e1fSMike Wellesnever cross strip boundaries. Encoding routines must be cognizant of 608*0ef31e1fSMike Wellesthe raw data buffer size and call <TT>TIFFFlushData1()</TT> when necessary. 609*0ef31e1fSMike WellesNote that any pending data is automatically flushed when a new strip/tile is 610*0ef31e1fSMike Wellesstarted, so there's no need do that in the tif_postencode routine (if 611*0ef31e1fSMike Wellesone exists). Bit order is automatically handled by the library when 612*0ef31e1fSMike Wellesa raw strip or tile is filled. If the decoded samples are interpreted 613*0ef31e1fSMike Wellesby the decoding routine before they are passed back to the user, then 614*0ef31e1fSMike Wellesthe decoding logic must handle byte-swapping by overriding the 615*0ef31e1fSMike Welles<TT>tif_postdecode</TT> 616*0ef31e1fSMike Wellesroutine (set it to <TT>TIFFNoPostDecode</TT>) and doing the required work 617*0ef31e1fSMike Wellesinternally. For an example of doing this look at the horizontal 618*0ef31e1fSMike Wellesdifferencing code in the routines in <B>tif_predict.c</TT>. 619*0ef31e1fSMike Welles 620*0ef31e1fSMike Welles<P> 621*0ef31e1fSMike WellesThe variables <TT>tif_rawcc</TT>, <TT>tif_rawdata</TT>, and 622*0ef31e1fSMike Welles<TT>tif_rawcp</TT> in a <TT>TIFF</TT> structure 623*0ef31e1fSMike Wellesare associated with the raw data buffer. <TT>tif_rawcc</TT> must be non-zero 624*0ef31e1fSMike Wellesfor the library to automatically flush data. The variable 625*0ef31e1fSMike Welles<TT>tif_scanlinesize</TT> is the size a user's scanline buffer should be. The 626*0ef31e1fSMike Wellesvariable <TT>tif_tilesize</TT> is the size of a tile for tiled images. This 627*0ef31e1fSMike Wellesshould not normally be used by compression routines, except where it 628*0ef31e1fSMike Wellesrelates to the compression algorithm. That is, the <TT>cc</TT> parameter to the 629*0ef31e1fSMike Welles<TT>tif_decode*</TT> and <TT>tif_encode*</TT> 630*0ef31e1fSMike Wellesroutines should be used in terminating 631*0ef31e1fSMike Wellesdecompression/compression. This ensures these routines can be used, 632*0ef31e1fSMike Wellesfor example, to decode/encode entire strips of data. 633*0ef31e1fSMike Welles 634*0ef31e1fSMike Welles<P> 635*0ef31e1fSMike WellesIn general, if you have a new compression algorithm to add, work from 636*0ef31e1fSMike Wellesthe code for an existing routine. In particular, 637*0ef31e1fSMike Welles<B>tif_dumpmode.c</B> 638*0ef31e1fSMike Welleshas the trivial code for the "nil" compression scheme, 639*0ef31e1fSMike Welles<B>tif_packbits.c</B> is a 640*0ef31e1fSMike Wellessimple byte-oriented scheme that has to watch out for buffer 641*0ef31e1fSMike Wellesboundaries, and <B>tif_lzw.c</B> has the LZW scheme that has the most 642*0ef31e1fSMike Wellescomplexity -- it tracks the buffer boundary at a bit level. 643*0ef31e1fSMike WellesOf course, using a private compression scheme (or private tags) limits 644*0ef31e1fSMike Wellesthe portability of your TIFF files. 645*0ef31e1fSMike Welles 646*0ef31e1fSMike Welles<P> 647*0ef31e1fSMike Welles<HR> 648*0ef31e1fSMike Welles 649*0ef31e1fSMike Welles<ADDRESS> 650*0ef31e1fSMike Welles<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:[email protected]">[email protected]</A>. 651*0ef31e1fSMike WellesLast updated: $Date: 1999-07-27 21:50:27 $ 652*0ef31e1fSMike Welles</ADDRESS> 653*0ef31e1fSMike Welles 654*0ef31e1fSMike Welles</BODY> 655*0ef31e1fSMike Welles</HTML> 656