1/* $Id: tif_open.c 276 2010-06-30 12:18:30Z nijtmans $ */ 2 3/* 4 * Copyright (c) 1988-1997 Sam Leffler 5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 6 * 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. 14 * 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. 18 * 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 24 * OF THIS SOFTWARE. 25 */ 26 27/* 28 * TIFF Library. 29 */ 30#include "tiffiop.h" 31 32static 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 */ 46}; 47static const int bigTypeshift[13] = { 48 0, /* TIFF_NOTYPE */ 49 24, /* TIFF_BYTE */ 50 0, /* TIFF_ASCII */ 51 16, /* TIFF_SHORT */ 52 0, /* TIFF_LONG */ 53 0, /* TIFF_RATIONAL */ 54 24, /* TIFF_SBYTE */ 55 24, /* TIFF_UNDEFINED */ 56 16, /* TIFF_SSHORT */ 57 0, /* TIFF_SLONG */ 58 0, /* TIFF_SRATIONAL */ 59 0, /* TIFF_FLOAT */ 60 0, /* TIFF_DOUBLE */ 61}; 62static const int litTypeshift[13] = { 63 0, /* TIFF_NOTYPE */ 64 0, /* TIFF_BYTE */ 65 0, /* TIFF_ASCII */ 66 0, /* TIFF_SHORT */ 67 0, /* TIFF_LONG */ 68 0, /* TIFF_RATIONAL */ 69 0, /* TIFF_SBYTE */ 70 0, /* TIFF_UNDEFINED */ 71 0, /* TIFF_SSHORT */ 72 0, /* TIFF_SLONG */ 73 0, /* TIFF_SRATIONAL */ 74 0, /* TIFF_FLOAT */ 75 0, /* TIFF_DOUBLE */ 76}; 77 78/* 79 * Dummy functions to fill the omitted client procedures. 80 */ 81static int 82_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) 83{ 84 (void) fd; (void) pbase; (void) psize; 85 return (0); 86} 87 88static void 89_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) 90{ 91 (void) fd; (void) base; (void) size; 92} 93 94/* 95 * Initialize the shift & mask tables, and the 96 * byte swapping state according to the file 97 * contents and the machine architecture. 98 */ 99static void 100TIFFInitOrder(TIFF* tif, int magic) 101{ 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; 107#endif 108 } else { 109 tif->tif_typeshift = litTypeshift; 110#ifdef WORDS_BIGENDIAN 111 tif->tif_flags |= TIFF_SWAB; 112#endif 113 } 114} 115 116int 117_TIFFgetMode(const char* mode, const char* module) 118{ 119 int m = -1; 120 121 switch (mode[0]) { 122 case 'r': 123 m = O_RDONLY; 124 if (mode[1] == '+') 125 m = O_RDWR; 126 break; 127 case 'w': 128 case 'a': 129 m = O_RDWR|O_CREAT; 130 if (mode[0] == 'w') 131 m |= O_TRUNC; 132 break; 133 default: 134 TIFFErrorExt(0, module, "\"%s\": Bad mode", mode); 135 break; 136 } 137 return (m); 138} 139 140TIFF* 141TIFFClientOpen( 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 151) 152{ 153 static const char module[] = "TIFFClientOpen"; 154 TIFF *tif; 155 int m; 156 const char* cp; 157 158 m = _TIFFgetMode(mode, module); 159 if (m == -1) 160 goto bad2; 161 tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1); 162 if (tif == NULL) { 163 TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name); 164 goto bad2; 165 } 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 */ 171 tif->tif_curoff = 0; 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."); 178 goto bad2; 179 } 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; 185 if (mapproc) 186 tif->tif_mapproc = mapproc; 187 else 188 tif->tif_mapproc = _tiffDummyMapProc; 189 if (unmapproc) 190 tif->tif_unmapproc = unmapproc; 191 else 192 tif->tif_unmapproc = _tiffDummyUnmapProc; 193 _TIFFSetDefaultCompressionState(tif); /* setup default state */ 194 /* 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. 198 */ 199 tif->tif_flags = FILLORDER_MSB2LSB; 200 if (m == O_RDONLY ) 201 tif->tif_flags |= TIFF_MAPPED; 202 203#ifdef STRIPCHOP_DEFAULT 204 if (m == O_RDONLY || m == O_RDWR) 205 tif->tif_flags |= STRIPCHOP_DEFAULT; 206#endif 207 208 /* 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): 215 * 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 226 * 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. 237 * 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 245 * not do right now. 246 * 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. 251 * 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. 257 */ 258 for (cp = mode; *cp; cp++) 259 switch (*cp) { 260 case 'b': 261#ifndef WORDS_BIGENDIAN 262 if (m&O_CREAT) 263 tif->tif_flags |= TIFF_SWAB; 264#endif 265 break; 266 case 'l': 267#ifdef WORDS_BIGENDIAN 268 if ((m&O_CREAT)) 269 tif->tif_flags |= TIFF_SWAB; 270#endif 271 break; 272 case 'B': 273 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | 274 FILLORDER_MSB2LSB; 275 break; 276 case 'L': 277 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | 278 FILLORDER_LSB2MSB; 279 break; 280 case 'H': 281 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | 282 HOST_FILLORDER; 283 break; 284 case 'M': 285 if (m == O_RDONLY) 286 tif->tif_flags |= TIFF_MAPPED; 287 break; 288 case 'm': 289 if (m == O_RDONLY) 290 tif->tif_flags &= ~TIFF_MAPPED; 291 break; 292 case 'C': 293 if (m == O_RDONLY) 294 tif->tif_flags |= TIFF_STRIPCHOP; 295 break; 296 case 'c': 297 if (m == O_RDONLY) 298 tif->tif_flags &= ~TIFF_STRIPCHOP; 299 break; 300 case 'h': 301 tif->tif_flags |= TIFF_HEADERONLY; 302 break; 303 } 304 /* 305 * Read in TIFF header. 306 */ 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, 311 "Cannot read TIFF header"); 312 goto bad; 313 } 314 /* 315 * Setup header and write. 316 */ 317#ifdef WORDS_BIGENDIAN 318 tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB 319 ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; 320#else 321 tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB 322 ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; 323#endif 324 tif->tif_header.tiff_version = TIFF_VERSION; 325 if (tif->tif_flags & TIFF_SWAB) 326 TIFFSwabShort(&tif->tif_header.tiff_version); 327 tif->tif_header.tiff_diroff = 0; /* filled in later */ 328 329 330 /* 331 * The doc for "fopen" for some STD_C_LIBs says that if you 332 * open a file for modify ("+"), then you must fseek (or 333 * fflush?) between any freads and fwrites. This is not 334 * necessary on most systems, but has been shown to be needed 335 * on Solaris. 336 */ 337 TIFFSeekFile( tif, 0, SEEK_SET ); 338 339 if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { 340 TIFFErrorExt(tif->tif_clientdata, name, 341 "Error writing TIFF header"); 342 goto bad; 343 } 344 /* 345 * Setup the byte order handling. 346 */ 347 TIFFInitOrder(tif, tif->tif_header.tiff_magic); 348 /* 349 * Setup default directory. 350 */ 351 if (!TIFFDefaultDirectory(tif)) 352 goto bad; 353 tif->tif_diroff = 0; 354 tif->tif_dirlist = NULL; 355 tif->tif_dirlistsize = 0; 356 tif->tif_dirnumber = 0; 357 return (tif); 358 } 359 /* 360 * Setup the byte order handling. 361 */ 362 if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN && 363 tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN 364#if MDI_SUPPORT 365 && 366#if HOST_BIGENDIAN 367 tif->tif_header.tiff_magic != MDI_BIGENDIAN 368#else 369 tif->tif_header.tiff_magic != MDI_LITTLEENDIAN 370#endif 371 ) { 372 TIFFErrorExt(tif->tif_clientdata, name, 373 "Not a TIFF or MDI file, bad magic number %d (0x%x)", 374#else 375 ) { 376 TIFFErrorExt(tif->tif_clientdata, name, 377 "Not a TIFF file, bad magic number %d (0x%x)", 378#endif 379 tif->tif_header.tiff_magic, 380 tif->tif_header.tiff_magic); 381 goto bad; 382 } 383 TIFFInitOrder(tif, tif->tif_header.tiff_magic); 384 /* 385 * Swap header if required. 386 */ 387 if (tif->tif_flags & TIFF_SWAB) { 388 TIFFSwabShort(&tif->tif_header.tiff_version); 389 TIFFSwabLong(&tif->tif_header.tiff_diroff); 390 } 391 /* 392 * Now check version (if needed, it's been byte-swapped). 393 * Note that this isn't actually a version number, it's a 394 * magic number that doesn't change (stupid). 395 */ 396 if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) { 397 TIFFErrorExt(tif->tif_clientdata, name, 398 "This is a BigTIFF file. This format not supported\n" 399 "by this version of libtiff." ); 400 goto bad; 401 } 402 if (tif->tif_header.tiff_version != TIFF_VERSION) { 403 TIFFErrorExt(tif->tif_clientdata, name, 404 "Not a TIFF file, bad version number %d (0x%x)", 405 tif->tif_header.tiff_version, 406 tif->tif_header.tiff_version); 407 goto bad; 408 } 409 tif->tif_flags |= TIFF_MYBUFFER; 410 tif->tif_rawcp = tif->tif_rawdata = 0; 411 tif->tif_rawdatasize = 0; 412 413 /* 414 * Sometimes we do not want to read the first directory (for example, 415 * it may be broken) and want to proceed to other directories. I this 416 * case we use the TIFF_HEADERONLY flag to open file and return 417 * immediately after reading TIFF header. 418 */ 419 if (tif->tif_flags & TIFF_HEADERONLY) 420 return (tif); 421 422 /* 423 * Setup initial directory. 424 */ 425 switch (mode[0]) { 426 case 'r': 427 tif->tif_nextdiroff = tif->tif_header.tiff_diroff; 428 /* 429 * Try to use a memory-mapped file if the client 430 * has not explicitly suppressed usage with the 431 * 'm' flag in the open mode (see above). 432 */ 433 if ((tif->tif_flags & TIFF_MAPPED) && 434 !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size)) 435 tif->tif_flags &= ~TIFF_MAPPED; 436 if (TIFFReadDirectory(tif)) { 437 tif->tif_rawcc = -1; 438 tif->tif_flags |= TIFF_BUFFERSETUP; 439 return (tif); 440 } 441 break; 442 case 'a': 443 /* 444 * New directories are automatically append 445 * to the end of the directory chain when they 446 * are written out (see TIFFWriteDirectory). 447 */ 448 if (!TIFFDefaultDirectory(tif)) 449 goto bad; 450 return (tif); 451 } 452bad: 453 tif->tif_mode = O_RDONLY; /* XXX avoid flush */ 454 TIFFCleanup(tif); 455bad2: 456 return ((TIFF*)0); 457} 458 459/* 460 * Query functions to access private data. 461 */ 462 463/* 464 * Return open file's name. 465 */ 466const char * 467TIFFFileName(TIFF* tif) 468{ 469 return (tif->tif_name); 470} 471 472/* 473 * Set the file name. 474 */ 475const char * 476TIFFSetFileName(TIFF* tif, const char *name) 477{ 478 const char* old_name = tif->tif_name; 479 tif->tif_name = (char *)name; 480 return (old_name); 481} 482 483/* 484 * Return open file's I/O descriptor. 485 */ 486int 487TIFFFileno(TIFF* tif) 488{ 489 return (tif->tif_fd); 490} 491 492/* 493 * Set open file's I/O descriptor, and return previous value. 494 */ 495int 496TIFFSetFileno(TIFF* tif, int fd) 497{ 498 int old_fd = tif->tif_fd; 499 tif->tif_fd = fd; 500 return old_fd; 501} 502 503/* 504 * Return open file's clientdata. 505 */ 506thandle_t 507TIFFClientdata(TIFF* tif) 508{ 509 return (tif->tif_clientdata); 510} 511 512/* 513 * Set open file's clientdata, and return previous value. 514 */ 515thandle_t 516TIFFSetClientdata(TIFF* tif, thandle_t newvalue) 517{ 518 thandle_t m = tif->tif_clientdata; 519 tif->tif_clientdata = newvalue; 520 return m; 521} 522 523/* 524 * Return read/write mode. 525 */ 526int 527TIFFGetMode(TIFF* tif) 528{ 529 return (tif->tif_mode); 530} 531 532/* 533 * Return read/write mode. 534 */ 535int 536TIFFSetMode(TIFF* tif, int mode) 537{ 538 int old_mode = tif->tif_mode; 539 tif->tif_mode = mode; 540 return (old_mode); 541} 542 543/* 544 * Return nonzero if file is organized in 545 * tiles; zero if organized as strips. 546 */ 547int 548TIFFIsTiled(TIFF* tif) 549{ 550 return (isTiled(tif)); 551} 552 553/* 554 * Return current row being read/written. 555 */ 556uint32 557TIFFCurrentRow(TIFF* tif) 558{ 559 return (tif->tif_row); 560} 561 562/* 563 * Return index of the current directory. 564 */ 565tdir_t 566TIFFCurrentDirectory(TIFF* tif) 567{ 568 return (tif->tif_curdir); 569} 570 571/* 572 * Return current strip. 573 */ 574tstrip_t 575TIFFCurrentStrip(TIFF* tif) 576{ 577 return (tif->tif_curstrip); 578} 579 580/* 581 * Return current tile. 582 */ 583ttile_t 584TIFFCurrentTile(TIFF* tif) 585{ 586 return (tif->tif_curtile); 587} 588 589/* 590 * Return nonzero if the file has byte-swapped data. 591 */ 592int 593TIFFIsByteSwapped(TIFF* tif) 594{ 595 return ((tif->tif_flags & TIFF_SWAB) != 0); 596} 597 598/* 599 * Return nonzero if the data is returned up-sampled. 600 */ 601int 602TIFFIsUpSampled(TIFF* tif) 603{ 604 return (isUpSampled(tif)); 605} 606 607/* 608 * Return nonzero if the data is returned in MSB-to-LSB bit order. 609 */ 610int 611TIFFIsMSB2LSB(TIFF* tif) 612{ 613 return (isFillOrder(tif, FILLORDER_MSB2LSB)); 614} 615 616/* 617 * Return nonzero if given file was written in big-endian order. 618 */ 619int 620TIFFIsBigEndian(TIFF* tif) 621{ 622 return (tif->tif_header.tiff_magic == TIFF_BIGENDIAN); 623} 624 625/* 626 * Return pointer to file read method. 627 */ 628TIFFReadWriteProc 629TIFFGetReadProc(TIFF* tif) 630{ 631 return (tif->tif_readproc); 632} 633 634/* 635 * Return pointer to file write method. 636 */ 637TIFFReadWriteProc 638TIFFGetWriteProc(TIFF* tif) 639{ 640 return (tif->tif_writeproc); 641} 642 643/* 644 * Return pointer to file seek method. 645 */ 646TIFFSeekProc 647TIFFGetSeekProc(TIFF* tif) 648{ 649 return (tif->tif_seekproc); 650} 651 652/* 653 * Return pointer to file close method. 654 */ 655TIFFCloseProc 656TIFFGetCloseProc(TIFF* tif) 657{ 658 return (tif->tif_closeproc); 659} 660 661/* 662 * Return pointer to file size requesting method. 663 */ 664TIFFSizeProc 665TIFFGetSizeProc(TIFF* tif) 666{ 667 return (tif->tif_sizeproc); 668} 669 670/* 671 * Return pointer to memory mapping method. 672 */ 673TIFFMapFileProc 674TIFFGetMapFileProc(TIFF* tif) 675{ 676 return (tif->tif_mapproc); 677} 678 679/* 680 * Return pointer to memory unmapping method. 681 */ 682TIFFUnmapFileProc 683TIFFGetUnmapFileProc(TIFF* tif) 684{ 685 return (tif->tif_unmapproc); 686} 687 688/* vim: set ts=8 sts=8 sw=8 noet: */ 689/* 690 * Local Variables: 691 * mode: c 692 * c-basic-offset: 8 693 * fill-column: 78 694 * End: 695 */ 696