4  * Copyright (c) 1988-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   7  * Permission to use, copy, modify, distribute, and sell this software and  
   8  * its documentation for any purpose is hereby granted without fee, provided 
   9  * that (i) the above copyright notices and this permission notice appear in 
  10  * all copies of the software and related documentation, and (ii) the names of 
  11  * Sam Leffler and Silicon Graphics may not be used in any advertising or 
  12  * publicity relating to the software without the specific, prior written 
  13  * permission of Sam Leffler and Silicon Graphics. 
  15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  
  16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  
  17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   
  19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 
  20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 
  21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  
  23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  
  32 static const long typemask
[13] = { 
  33         (long)0L,               /* TIFF_NOTYPE */ 
  34         (long)0x000000ffL
,      /* TIFF_BYTE */ 
  35         (long)0xffffffffL
,      /* TIFF_ASCII */ 
  36         (long)0x0000ffffL
,      /* TIFF_SHORT */ 
  37         (long)0xffffffffL
,      /* TIFF_LONG */ 
  38         (long)0xffffffffL
,      /* TIFF_RATIONAL */ 
  39         (long)0x000000ffL
,      /* TIFF_SBYTE */ 
  40         (long)0x000000ffL
,      /* TIFF_UNDEFINED */ 
  41         (long)0x0000ffffL
,      /* TIFF_SSHORT */ 
  42         (long)0xffffffffL
,      /* TIFF_SLONG */ 
  43         (long)0xffffffffL
,      /* TIFF_SRATIONAL */ 
  44         (long)0xffffffffL
,      /* TIFF_FLOAT */ 
  45         (long)0xffffffffL
,      /* TIFF_DOUBLE */ 
  47 static const int bigTypeshift
[13] = { 
  53         0,              /* TIFF_RATIONAL */ 
  55         24,             /* TIFF_UNDEFINED */ 
  58         0,              /* TIFF_SRATIONAL */ 
  62 static const int litTypeshift
[13] = { 
  68         0,              /* TIFF_RATIONAL */ 
  70         0,              /* TIFF_UNDEFINED */ 
  73         0,              /* TIFF_SRATIONAL */ 
  79  * Dummy functions to fill the omitted client procedures. 
  82 _tiffDummyMapProc(thandle_t fd
, tdata_t
* pbase
, toff_t
* psize
) 
  84         (void) fd
; (void) pbase
; (void) psize
; 
  89 _tiffDummyUnmapProc(thandle_t fd
, tdata_t base
, toff_t size
) 
  91         (void) fd
; (void) base
; (void) size
; 
  95  * Initialize the shift & mask tables, and the 
  96  * byte swapping state according to the file 
  97  * contents and the machine architecture. 
 100 TIFFInitOrder(TIFF
* tif
, int magic
) 
 102         tif
->tif_typemask 
= typemask
; 
 103         if (magic 
== TIFF_BIGENDIAN
) { 
 104                 tif
->tif_typeshift 
= bigTypeshift
; 
 105 #ifndef WORDS_BIGENDIAN 
 106                 tif
->tif_flags 
|= TIFF_SWAB
; 
 109                 tif
->tif_typeshift 
= litTypeshift
; 
 110 #ifdef WORDS_BIGENDIAN 
 111                 tif
->tif_flags 
|= TIFF_SWAB
; 
 117 _TIFFgetMode(const char* mode
, const char* module) 
 134                 TIFFErrorExt(0, module, "\"%s\": Bad mode", mode
); 
 142         const char* name
, const char* mode
, 
 143         thandle_t clientdata
, 
 144         TIFFReadWriteProc readproc
, 
 145         TIFFReadWriteProc writeproc
, 
 146         TIFFSeekProc seekproc
, 
 147         TIFFCloseProc closeproc
, 
 148         TIFFSizeProc sizeproc
, 
 149         TIFFMapFileProc mapproc
, 
 150         TIFFUnmapFileProc unmapproc
 
 153         static const char module[] = "TIFFClientOpen"; 
 158         m 
= _TIFFgetMode(mode
, module); 
 161         tif 
= (TIFF 
*)_TIFFmalloc(sizeof (TIFF
) + strlen(name
) + 1); 
 163                 TIFFErrorExt(clientdata
, module, "%s: Out of memory (TIFF structure)", name
); 
 166         _TIFFmemset(tif
, 0, sizeof (*tif
)); 
 167         tif
->tif_name 
= (char *)tif 
+ sizeof (TIFF
); 
 168         strcpy(tif
->tif_name
, name
); 
 169         tif
->tif_mode 
= m 
&~ (O_CREAT
|O_TRUNC
); 
 170         tif
->tif_curdir 
= (tdir_t
) -1;          /* non-existent directory */ 
 172         tif
->tif_curstrip 
= (tstrip_t
) -1;      /* invalid strip */ 
 173         tif
->tif_row 
= (uint32
) -1;             /* read/write pre-increment */ 
 174         tif
->tif_clientdata 
= clientdata
; 
 175         if (!readproc 
|| !writeproc 
|| !seekproc 
|| !closeproc 
|| !sizeproc
) { 
 176                 TIFFErrorExt(clientdata
, module, 
 177                           "One of the client procedures is NULL pointer."); 
 180         tif
->tif_readproc 
= readproc
; 
 181         tif
->tif_writeproc 
= writeproc
; 
 182         tif
->tif_seekproc 
= seekproc
; 
 183         tif
->tif_closeproc 
= closeproc
; 
 184         tif
->tif_sizeproc 
= sizeproc
; 
 186                 tif
->tif_mapproc 
= mapproc
; 
 188                 tif
->tif_mapproc 
= _tiffDummyMapProc
; 
 190                 tif
->tif_unmapproc 
= unmapproc
; 
 192                 tif
->tif_unmapproc 
= _tiffDummyUnmapProc
; 
 193         _TIFFSetDefaultCompressionState(tif
);   /* setup default state */ 
 195          * Default is to return data MSB2LSB and enable the 
 196          * use of memory-mapped files and strip chopping when 
 197          * a file is opened read-only. 
 199         tif
->tif_flags 
= FILLORDER_MSB2LSB
; 
 201             tif
->tif_flags 
|= TIFF_MAPPED
; 
 203 #ifdef STRIPCHOP_DEFAULT 
 204         if (m 
== O_RDONLY 
|| m 
== O_RDWR
) 
 205                 tif
->tif_flags 
|= STRIPCHOP_DEFAULT
; 
 209          * Process library-specific flags in the open mode string. 
 210          * The following flags may be used to control intrinsic library 
 211          * behaviour that may or may not be desirable (usually for 
 212          * compatibility with some application that claims to support 
 213          * TIFF but only supports some braindead idea of what the 
 214          * vendor thinks TIFF is): 
 216          * 'l'          use little-endian byte order for creating a file 
 217          * 'b'          use big-endian byte order for creating a file 
 218          * 'L'          read/write information using LSB2MSB bit order 
 219          * 'B'          read/write information using MSB2LSB bit order 
 220          * 'H'          read/write information using host bit order 
 221          * 'M'          enable use of memory-mapped files when supported 
 222          * 'm'          disable use of memory-mapped files 
 223          * 'C'          enable strip chopping support when reading 
 224          * 'c'          disable strip chopping support 
 225          * 'h'          read TIFF header only, do not load the first IFD 
 227          * The use of the 'l' and 'b' flags is strongly discouraged. 
 228          * These flags are provided solely because numerous vendors, 
 229          * typically on the PC, do not correctly support TIFF; they 
 230          * only support the Intel little-endian byte order.  This 
 231          * support is not configured by default because it supports 
 232          * the violation of the TIFF spec that says that readers *MUST* 
 233          * support both byte orders.  It is strongly recommended that 
 234          * you not use this feature except to deal with busted apps 
 235          * that write invalid TIFF.  And even in those cases you should 
 236          * bang on the vendors to fix their software. 
 238          * The 'L', 'B', and 'H' flags are intended for applications 
 239          * that can optimize operations on data by using a particular 
 240          * bit order.  By default the library returns data in MSB2LSB 
 241          * bit order for compatibiltiy with older versions of this 
 242          * library.  Returning data in the bit order of the native cpu 
 243          * makes the most sense but also requires applications to check 
 244          * the value of the FillOrder tag; something they probably do 
 247          * The 'M' and 'm' flags are provided because some virtual memory 
 248          * systems exhibit poor behaviour when large images are mapped. 
 249          * These options permit clients to control the use of memory-mapped 
 250          * files on a per-file basis. 
 252          * The 'C' and 'c' flags are provided because the library support 
 253          * for chopping up large strips into multiple smaller strips is not 
 254          * application-transparent and as such can cause problems.  The 'c' 
 255          * option permits applications that only want to look at the tags, 
 256          * for example, to get the unadulterated TIFF tag information. 
 258         for (cp 
= mode
; *cp
; cp
++) 
 261 #ifndef WORDS_BIGENDIAN 
 263                                 tif
->tif_flags 
|= TIFF_SWAB
; 
 267 #ifdef WORDS_BIGENDIAN 
 269                                 tif
->tif_flags 
|= TIFF_SWAB
; 
 273                         tif
->tif_flags 
= (tif
->tif_flags 
&~ TIFF_FILLORDER
) | 
 277                         tif
->tif_flags 
= (tif
->tif_flags 
&~ TIFF_FILLORDER
) | 
 281                         tif
->tif_flags 
= (tif
->tif_flags 
&~ TIFF_FILLORDER
) | 
 286                                 tif
->tif_flags 
|= TIFF_MAPPED
; 
 290                                 tif
->tif_flags 
&= ~TIFF_MAPPED
; 
 294                                 tif
->tif_flags 
|= TIFF_STRIPCHOP
; 
 298                                 tif
->tif_flags 
&= ~TIFF_STRIPCHOP
; 
 301                         tif
->tif_flags 
|= TIFF_HEADERONLY
; 
 305          * Read in TIFF header. 
 307         if (tif
->tif_mode 
& O_TRUNC 
|| 
 308             !ReadOK(tif
, &tif
->tif_header
, sizeof (TIFFHeader
))) { 
 309                 if (tif
->tif_mode 
== O_RDONLY
) { 
 310                         TIFFErrorExt(tif
->tif_clientdata
, name
, "Cannot read TIFF header"); 
 314                  * Setup header and write. 
 316 #ifdef WORDS_BIGENDIAN 
 317                 tif
->tif_header
.tiff_magic 
= tif
->tif_flags 
& TIFF_SWAB
 
 318                     ? TIFF_LITTLEENDIAN 
: TIFF_BIGENDIAN
; 
 320                 tif
->tif_header
.tiff_magic 
= tif
->tif_flags 
& TIFF_SWAB
 
 321                     ? TIFF_BIGENDIAN 
: TIFF_LITTLEENDIAN
; 
 323                 tif
->tif_header
.tiff_version 
= TIFF_VERSION
; 
 324                 if (tif
->tif_flags 
& TIFF_SWAB
) 
 325                         TIFFSwabShort(&tif
->tif_header
.tiff_version
); 
 326                 tif
->tif_header
.tiff_diroff 
= 0;        /* filled in later */ 
 330                  * The doc for "fopen" for some STD_C_LIBs says that if you  
 331                  * open a file for modify ("+"), then you must fseek (or  
 332                  * fflush?) between any freads and fwrites.  This is not 
 333                  * necessary on most systems, but has been shown to be needed 
 336                 TIFFSeekFile( tif
, 0, SEEK_SET 
); 
 338                 if (!WriteOK(tif
, &tif
->tif_header
, sizeof (TIFFHeader
))) { 
 339                         TIFFErrorExt(tif
->tif_clientdata
, name
, "Error writing TIFF header"); 
 343                  * Setup the byte order handling. 
 345                 TIFFInitOrder(tif
, tif
->tif_header
.tiff_magic
); 
 347                  * Setup default directory. 
 349                 if (!TIFFDefaultDirectory(tif
)) 
 352                 tif
->tif_dirlist 
= NULL
; 
 353                 tif
->tif_dirnumber 
= 0; 
 357          * Setup the byte order handling. 
 359         if (tif
->tif_header
.tiff_magic 
!= TIFF_BIGENDIAN 
&& 
 360             tif
->tif_header
.tiff_magic 
!= TIFF_LITTLEENDIAN
 
 364             tif
->tif_header
.tiff_magic 
!= MDI_BIGENDIAN
 
 366             tif
->tif_header
.tiff_magic 
!= MDI_LITTLEENDIAN
 
 369                 TIFFErrorExt(tif
->tif_clientdata
, name
,  "Not a TIFF or MDI file, bad magic number %d (0x%x)", 
 372                 TIFFErrorExt(tif
->tif_clientdata
, name
,  "Not a TIFF file, bad magic number %d (0x%x)", 
 374                     tif
->tif_header
.tiff_magic
, 
 375                     tif
->tif_header
.tiff_magic
); 
 378         TIFFInitOrder(tif
, tif
->tif_header
.tiff_magic
); 
 380          * Swap header if required. 
 382         if (tif
->tif_flags 
& TIFF_SWAB
) { 
 383                 TIFFSwabShort(&tif
->tif_header
.tiff_version
); 
 384                 TIFFSwabLong(&tif
->tif_header
.tiff_diroff
); 
 387          * Now check version (if needed, it's been byte-swapped). 
 388          * Note that this isn't actually a version number, it's a 
 389          * magic number that doesn't change (stupid). 
 391         if (tif
->tif_header
.tiff_version 
== TIFF_BIGTIFF_VERSION
) { 
 392                 TIFFErrorExt(tif
->tif_clientdata
, name
, 
 393                           "This is a BigTIFF file.  This format not supported\n" 
 394                           "by this version of libtiff." ); 
 397         if (tif
->tif_header
.tiff_version 
!= TIFF_VERSION
) { 
 398                 TIFFErrorExt(tif
->tif_clientdata
, name
, 
 399                     "Not a TIFF file, bad version number %d (0x%x)", 
 400                     tif
->tif_header
.tiff_version
, 
 401                     tif
->tif_header
.tiff_version
);  
 404         tif
->tif_flags 
|= TIFF_MYBUFFER
; 
 405         tif
->tif_rawcp 
= tif
->tif_rawdata 
= 0; 
 406         tif
->tif_rawdatasize 
= 0; 
 409          * Sometimes we do not want to read the first directory (for example, 
 410          * it may be broken) and want to proceed to other directories. I this 
 411          * case we use the TIFF_HEADERONLY flag to open file and return 
 412          * immediately after reading TIFF header. 
 414         if (tif
->tif_flags 
& TIFF_HEADERONLY
) 
 418          * Setup initial directory. 
 422                 tif
->tif_nextdiroff 
= tif
->tif_header
.tiff_diroff
; 
 424                  * Try to use a memory-mapped file if the client 
 425                  * has not explicitly suppressed usage with the 
 426                  * 'm' flag in the open mode (see above). 
 428                 if ((tif
->tif_flags 
& TIFF_MAPPED
) && 
 429         !TIFFMapFileContents(tif
, (tdata_t
*) &tif
->tif_base
, &tif
->tif_size
)) 
 430                         tif
->tif_flags 
&= ~TIFF_MAPPED
; 
 431                 if (TIFFReadDirectory(tif
)) { 
 433                         tif
->tif_flags 
|= TIFF_BUFFERSETUP
; 
 439                  * New directories are automatically append 
 440                  * to the end of the directory chain when they 
 441                  * are written out (see TIFFWriteDirectory). 
 443                 if (!TIFFDefaultDirectory(tif
)) 
 448         tif
->tif_mode 
= O_RDONLY
;       /* XXX avoid flush */ 
 455  * Query functions to access private data. 
 459  * Return open file's name. 
 462 TIFFFileName(TIFF
* tif
) 
 464         return (tif
->tif_name
); 
 471 TIFFSetFileName(TIFF
* tif
, const char *name
) 
 473         const char* old_name 
= tif
->tif_name
; 
 474         tif
->tif_name 
= (char *)name
; 
 479  * Return open file's I/O descriptor. 
 482 TIFFFileno(TIFF
* tif
) 
 484         return (tif
->tif_fd
); 
 488  * Set open file's I/O descriptor, and return previous value. 
 491 TIFFSetFileno(TIFF
* tif
, int fd
) 
 493         int old_fd 
= tif
->tif_fd
; 
 499  * Return open file's clientdata. 
 502 TIFFClientdata(TIFF
* tif
) 
 504         return (tif
->tif_clientdata
); 
 508  * Set open file's clientdata, and return previous value. 
 511 TIFFSetClientdata(TIFF
* tif
, thandle_t newvalue
) 
 513         thandle_t m 
= tif
->tif_clientdata
; 
 514         tif
->tif_clientdata 
= newvalue
; 
 519  * Return read/write mode. 
 522 TIFFGetMode(TIFF
* tif
) 
 524         return (tif
->tif_mode
); 
 528  * Return read/write mode. 
 531 TIFFSetMode(TIFF
* tif
, int mode
) 
 533         int old_mode 
= tif
->tif_mode
; 
 534         tif
->tif_mode 
= mode
; 
 539  * Return nonzero if file is organized in 
 540  * tiles; zero if organized as strips. 
 543 TIFFIsTiled(TIFF
* tif
) 
 545         return (isTiled(tif
)); 
 549  * Return current row being read/written. 
 552 TIFFCurrentRow(TIFF
* tif
) 
 554         return (tif
->tif_row
); 
 558  * Return index of the current directory. 
 561 TIFFCurrentDirectory(TIFF
* tif
) 
 563         return (tif
->tif_curdir
); 
 567  * Return current strip. 
 570 TIFFCurrentStrip(TIFF
* tif
) 
 572         return (tif
->tif_curstrip
); 
 576  * Return current tile. 
 579 TIFFCurrentTile(TIFF
* tif
) 
 581         return (tif
->tif_curtile
); 
 585  * Return nonzero if the file has byte-swapped data. 
 588 TIFFIsByteSwapped(TIFF
* tif
) 
 590         return ((tif
->tif_flags 
& TIFF_SWAB
) != 0); 
 594  * Return nonzero if the data is returned up-sampled. 
 597 TIFFIsUpSampled(TIFF
* tif
) 
 599         return (isUpSampled(tif
)); 
 603  * Return nonzero if the data is returned in MSB-to-LSB bit order. 
 606 TIFFIsMSB2LSB(TIFF
* tif
) 
 608         return (isFillOrder(tif
, FILLORDER_MSB2LSB
)); 
 612  * Return nonzero if given file was written in big-endian order. 
 615 TIFFIsBigEndian(TIFF
* tif
) 
 617         return (tif
->tif_header
.tiff_magic 
== TIFF_BIGENDIAN
); 
 621  * Return pointer to file read method. 
 624 TIFFGetReadProc(TIFF
* tif
) 
 626         return (tif
->tif_readproc
); 
 630  * Return pointer to file write method. 
 633 TIFFGetWriteProc(TIFF
* tif
) 
 635         return (tif
->tif_writeproc
); 
 639  * Return pointer to file seek method. 
 642 TIFFGetSeekProc(TIFF
* tif
) 
 644         return (tif
->tif_seekproc
); 
 648  * Return pointer to file close method. 
 651 TIFFGetCloseProc(TIFF
* tif
) 
 653         return (tif
->tif_closeproc
); 
 657  * Return pointer to file size requesting method. 
 660 TIFFGetSizeProc(TIFF
* tif
) 
 662         return (tif
->tif_sizeproc
); 
 666  * Return pointer to memory mapping method. 
 669 TIFFGetMapFileProc(TIFF
* tif
) 
 671         return (tif
->tif_mapproc
); 
 675  * Return pointer to memory unmapping method. 
 678 TIFFGetUnmapFileProc(TIFF
* tif
) 
 680         return (tif
->tif_unmapproc
); 
 683 /* vim: set ts=8 sts=8 sw=8 noet: */