1 /* 2 * Copyright (c) 1988-1997 Sam Leffler 3 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and 6 * its documentation for any purpose is hereby granted without fee, provided 7 * that (i) the above copyright notices and this permission notice appear in 8 * all copies of the software and related documentation, and (ii) the names of 9 * Sam Leffler and Silicon Graphics may not be used in any advertising or 10 * publicity relating to the software without the specific, prior written 11 * permission of Sam Leffler and Silicon Graphics. 12 * 13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25 /* 26 * TIFF Library. 27 */ 28 #include <precomp.h> 29 30 /* 31 * Dummy functions to fill the omitted client procedures. 32 */ 33 static int 34 _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) 35 { 36 (void) fd; (void) pbase; (void) psize; 37 return (0); 38 } 39 40 static void 41 _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) 42 { 43 (void) fd; (void) base; (void) size; 44 } 45 46 int 47 _TIFFgetMode(const char* mode, const char* module) 48 { 49 int m = -1; 50 51 switch (mode[0]) { 52 case 'r': 53 m = O_RDONLY; 54 if (mode[1] == '+') 55 m = O_RDWR; 56 break; 57 case 'w': 58 case 'a': 59 m = O_RDWR|O_CREAT; 60 if (mode[0] == 'w') 61 m |= O_TRUNC; 62 break; 63 default: 64 TIFFErrorExt(0, module, "\"%s\": Bad mode", mode); 65 break; 66 } 67 return (m); 68 } 69 70 TIFF* 71 TIFFClientOpen( 72 const char* name, const char* mode, 73 thandle_t clientdata, 74 TIFFReadWriteProc readproc, 75 TIFFReadWriteProc writeproc, 76 TIFFSeekProc seekproc, 77 TIFFCloseProc closeproc, 78 TIFFSizeProc sizeproc, 79 TIFFMapFileProc mapproc, 80 TIFFUnmapFileProc unmapproc 81 ) 82 { 83 static const char module[] = "TIFFClientOpen"; 84 TIFF *tif; 85 int m; 86 const char* cp; 87 88 /* The following are configuration checks. They should be redundant, but should not 89 * compile to any actual code in an optimised release build anyway. If any of them 90 * fail, (makefile-based or other) configuration is not correct */ 91 assert(sizeof(uint8)==1); 92 assert(sizeof(int8)==1); 93 assert(sizeof(uint16)==2); 94 assert(sizeof(int16)==2); 95 assert(sizeof(uint32)==4); 96 assert(sizeof(int32)==4); 97 assert(sizeof(uint64)==8); 98 assert(sizeof(int64)==8); 99 assert(sizeof(tmsize_t)==sizeof(void*)); 100 { 101 union{ 102 uint8 a8[2]; 103 uint16 a16; 104 } n; 105 n.a8[0]=1; 106 n.a8[1]=0; 107 #ifdef WORDS_BIGENDIAN 108 assert(n.a16==256); 109 #else 110 assert(n.a16==1); 111 #endif 112 } 113 114 m = _TIFFgetMode(mode, module); 115 if (m == -1) 116 goto bad2; 117 tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1)); 118 if (tif == NULL) { 119 TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name); 120 goto bad2; 121 } 122 _TIFFmemset(tif, 0, sizeof (*tif)); 123 tif->tif_name = (char *)tif + sizeof (TIFF); 124 strcpy(tif->tif_name, name); 125 tif->tif_mode = m &~ (O_CREAT|O_TRUNC); 126 tif->tif_curdir = (uint16) -1; /* non-existent directory */ 127 tif->tif_curoff = 0; 128 tif->tif_curstrip = (uint32) -1; /* invalid strip */ 129 tif->tif_row = (uint32) -1; /* read/write pre-increment */ 130 tif->tif_clientdata = clientdata; 131 if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { 132 TIFFErrorExt(clientdata, module, 133 "One of the client procedures is NULL pointer."); 134 _TIFFfree(tif); 135 goto bad2; 136 } 137 tif->tif_readproc = readproc; 138 tif->tif_writeproc = writeproc; 139 tif->tif_seekproc = seekproc; 140 tif->tif_closeproc = closeproc; 141 tif->tif_sizeproc = sizeproc; 142 if (mapproc) 143 tif->tif_mapproc = mapproc; 144 else 145 tif->tif_mapproc = _tiffDummyMapProc; 146 if (unmapproc) 147 tif->tif_unmapproc = unmapproc; 148 else 149 tif->tif_unmapproc = _tiffDummyUnmapProc; 150 _TIFFSetDefaultCompressionState(tif); /* setup default state */ 151 /* 152 * Default is to return data MSB2LSB and enable the 153 * use of memory-mapped files and strip chopping when 154 * a file is opened read-only. 155 */ 156 tif->tif_flags = FILLORDER_MSB2LSB; 157 if (m == O_RDONLY ) 158 tif->tif_flags |= TIFF_MAPPED; 159 160 #ifdef STRIPCHOP_DEFAULT 161 if (m == O_RDONLY || m == O_RDWR) 162 tif->tif_flags |= STRIPCHOP_DEFAULT; 163 #endif 164 165 /* 166 * Process library-specific flags in the open mode string. 167 * The following flags may be used to control intrinsic library 168 * behaviour that may or may not be desirable (usually for 169 * compatibility with some application that claims to support 170 * TIFF but only supports some brain dead idea of what the 171 * vendor thinks TIFF is): 172 * 173 * 'l' use little-endian byte order for creating a file 174 * 'b' use big-endian byte order for creating a file 175 * 'L' read/write information using LSB2MSB bit order 176 * 'B' read/write information using MSB2LSB bit order 177 * 'H' read/write information using host bit order 178 * 'M' enable use of memory-mapped files when supported 179 * 'm' disable use of memory-mapped files 180 * 'C' enable strip chopping support when reading 181 * 'c' disable strip chopping support 182 * 'h' read TIFF header only, do not load the first IFD 183 * '4' ClassicTIFF for creating a file (default) 184 * '8' BigTIFF for creating a file 185 * 'D' enable use of deferred strip/tile offset/bytecount array loading. 186 * 'O' on-demand loading of values instead of whole array loading (implies D) 187 * 188 * The use of the 'l' and 'b' flags is strongly discouraged. 189 * These flags are provided solely because numerous vendors, 190 * typically on the PC, do not correctly support TIFF; they 191 * only support the Intel little-endian byte order. This 192 * support is not configured by default because it supports 193 * the violation of the TIFF spec that says that readers *MUST* 194 * support both byte orders. It is strongly recommended that 195 * you not use this feature except to deal with busted apps 196 * that write invalid TIFF. And even in those cases you should 197 * bang on the vendors to fix their software. 198 * 199 * The 'L', 'B', and 'H' flags are intended for applications 200 * that can optimize operations on data by using a particular 201 * bit order. By default the library returns data in MSB2LSB 202 * bit order for compatibility with older versions of this 203 * library. Returning data in the bit order of the native CPU 204 * makes the most sense but also requires applications to check 205 * the value of the FillOrder tag; something they probably do 206 * not do right now. 207 * 208 * The 'M' and 'm' flags are provided because some virtual memory 209 * systems exhibit poor behaviour when large images are mapped. 210 * These options permit clients to control the use of memory-mapped 211 * files on a per-file basis. 212 * 213 * The 'C' and 'c' flags are provided because the library support 214 * for chopping up large strips into multiple smaller strips is not 215 * application-transparent and as such can cause problems. The 'c' 216 * option permits applications that only want to look at the tags, 217 * for example, to get the unadulterated TIFF tag information. 218 */ 219 for (cp = mode; *cp; cp++) 220 switch (*cp) { 221 case 'b': 222 #ifndef WORDS_BIGENDIAN 223 if (m&O_CREAT) 224 tif->tif_flags |= TIFF_SWAB; 225 #endif 226 break; 227 case 'l': 228 #ifdef WORDS_BIGENDIAN 229 if ((m&O_CREAT)) 230 tif->tif_flags |= TIFF_SWAB; 231 #endif 232 break; 233 case 'B': 234 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | 235 FILLORDER_MSB2LSB; 236 break; 237 case 'L': 238 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | 239 FILLORDER_LSB2MSB; 240 break; 241 case 'H': 242 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | 243 HOST_FILLORDER; 244 break; 245 case 'M': 246 if (m == O_RDONLY) 247 tif->tif_flags |= TIFF_MAPPED; 248 break; 249 case 'm': 250 if (m == O_RDONLY) 251 tif->tif_flags &= ~TIFF_MAPPED; 252 break; 253 case 'C': 254 if (m == O_RDONLY) 255 tif->tif_flags |= TIFF_STRIPCHOP; 256 break; 257 case 'c': 258 if (m == O_RDONLY) 259 tif->tif_flags &= ~TIFF_STRIPCHOP; 260 break; 261 case 'h': 262 tif->tif_flags |= TIFF_HEADERONLY; 263 break; 264 case '8': 265 if (m&O_CREAT) 266 tif->tif_flags |= TIFF_BIGTIFF; 267 break; 268 case 'D': 269 tif->tif_flags |= TIFF_DEFERSTRILELOAD; 270 break; 271 case 'O': 272 if( m == O_RDONLY ) 273 tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); 274 break; 275 } 276 277 #ifdef DEFER_STRILE_LOAD 278 /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ 279 /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ 280 /* GDAL was the only user of this, and will now use the new 'D' flag */ 281 tif->tif_flags |= TIFF_DEFERSTRILELOAD; 282 #endif 283 284 /* 285 * Read in TIFF header. 286 */ 287 if ((m & O_TRUNC) || 288 !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) { 289 if (tif->tif_mode == O_RDONLY) { 290 TIFFErrorExt(tif->tif_clientdata, name, 291 "Cannot read TIFF header"); 292 goto bad; 293 } 294 /* 295 * Setup header and write. 296 */ 297 #ifdef WORDS_BIGENDIAN 298 tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) 299 ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; 300 #else 301 tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) 302 ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; 303 #endif 304 if (!(tif->tif_flags&TIFF_BIGTIFF)) 305 { 306 tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; 307 tif->tif_header.classic.tiff_diroff = 0; 308 if (tif->tif_flags & TIFF_SWAB) 309 TIFFSwabShort(&tif->tif_header.common.tiff_version); 310 tif->tif_header_size = sizeof(TIFFHeaderClassic); 311 } 312 else 313 { 314 tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; 315 tif->tif_header.big.tiff_offsetsize = 8; 316 tif->tif_header.big.tiff_unused = 0; 317 tif->tif_header.big.tiff_diroff = 0; 318 if (tif->tif_flags & TIFF_SWAB) 319 { 320 TIFFSwabShort(&tif->tif_header.common.tiff_version); 321 TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); 322 } 323 tif->tif_header_size = sizeof (TIFFHeaderBig); 324 } 325 /* 326 * The doc for "fopen" for some STD_C_LIBs says that if you 327 * open a file for modify ("+"), then you must fseek (or 328 * fflush?) between any freads and fwrites. This is not 329 * necessary on most systems, but has been shown to be needed 330 * on Solaris. 331 */ 332 TIFFSeekFile( tif, 0, SEEK_SET ); 333 if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) { 334 TIFFErrorExt(tif->tif_clientdata, name, 335 "Error writing TIFF header"); 336 goto bad; 337 } 338 /* 339 * Setup the byte order handling. 340 */ 341 if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { 342 #ifndef WORDS_BIGENDIAN 343 tif->tif_flags |= TIFF_SWAB; 344 #endif 345 } else { 346 #ifdef WORDS_BIGENDIAN 347 tif->tif_flags |= TIFF_SWAB; 348 #endif 349 } 350 /* 351 * Setup default directory. 352 */ 353 if (!TIFFDefaultDirectory(tif)) 354 goto bad; 355 tif->tif_diroff = 0; 356 tif->tif_dirlist = NULL; 357 tif->tif_dirlistsize = 0; 358 tif->tif_dirnumber = 0; 359 return (tif); 360 } 361 /* 362 * Setup the byte order handling. 363 */ 364 if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && 365 tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN 366 #if MDI_SUPPORT 367 && 368 #if HOST_BIGENDIAN 369 tif->tif_header.common.tiff_magic != MDI_BIGENDIAN 370 #else 371 tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN 372 #endif 373 ) { 374 TIFFErrorExt(tif->tif_clientdata, name, 375 "Not a TIFF or MDI file, bad magic number %d (0x%x)", 376 #else 377 ) { 378 TIFFErrorExt(tif->tif_clientdata, name, 379 "Not a TIFF file, bad magic number %d (0x%x)", 380 #endif 381 tif->tif_header.common.tiff_magic, 382 tif->tif_header.common.tiff_magic); 383 goto bad; 384 } 385 if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { 386 #ifndef WORDS_BIGENDIAN 387 tif->tif_flags |= TIFF_SWAB; 388 #endif 389 } else { 390 #ifdef WORDS_BIGENDIAN 391 tif->tif_flags |= TIFF_SWAB; 392 #endif 393 } 394 if (tif->tif_flags & TIFF_SWAB) 395 TIFFSwabShort(&tif->tif_header.common.tiff_version); 396 if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&& 397 (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) { 398 TIFFErrorExt(tif->tif_clientdata, name, 399 "Not a TIFF file, bad version number %d (0x%x)", 400 tif->tif_header.common.tiff_version, 401 tif->tif_header.common.tiff_version); 402 goto bad; 403 } 404 if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) 405 { 406 if (tif->tif_flags & TIFF_SWAB) 407 TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); 408 tif->tif_header_size = sizeof(TIFFHeaderClassic); 409 } 410 else 411 { 412 if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic)))) 413 { 414 TIFFErrorExt(tif->tif_clientdata, name, 415 "Cannot read TIFF header"); 416 goto bad; 417 } 418 if (tif->tif_flags & TIFF_SWAB) 419 { 420 TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); 421 TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); 422 } 423 if (tif->tif_header.big.tiff_offsetsize != 8) 424 { 425 TIFFErrorExt(tif->tif_clientdata, name, 426 "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)", 427 tif->tif_header.big.tiff_offsetsize, 428 tif->tif_header.big.tiff_offsetsize); 429 goto bad; 430 } 431 if (tif->tif_header.big.tiff_unused != 0) 432 { 433 TIFFErrorExt(tif->tif_clientdata, name, 434 "Not a TIFF file, bad BigTIFF unused %d (0x%x)", 435 tif->tif_header.big.tiff_unused, 436 tif->tif_header.big.tiff_unused); 437 goto bad; 438 } 439 tif->tif_header_size = sizeof(TIFFHeaderBig); 440 tif->tif_flags |= TIFF_BIGTIFF; 441 } 442 tif->tif_flags |= TIFF_MYBUFFER; 443 tif->tif_rawcp = tif->tif_rawdata = 0; 444 tif->tif_rawdatasize = 0; 445 tif->tif_rawdataoff = 0; 446 tif->tif_rawdataloaded = 0; 447 448 switch (mode[0]) { 449 case 'r': 450 if (!(tif->tif_flags&TIFF_BIGTIFF)) 451 tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; 452 else 453 tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; 454 /* 455 * Try to use a memory-mapped file if the client 456 * has not explicitly suppressed usage with the 457 * 'm' flag in the open mode (see above). 458 */ 459 if (tif->tif_flags & TIFF_MAPPED) 460 { 461 toff_t n; 462 if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n)) 463 { 464 tif->tif_size=(tmsize_t)n; 465 assert((toff_t)tif->tif_size==n); 466 } 467 else 468 tif->tif_flags &= ~TIFF_MAPPED; 469 } 470 /* 471 * Sometimes we do not want to read the first directory (for example, 472 * it may be broken) and want to proceed to other directories. I this 473 * case we use the TIFF_HEADERONLY flag to open file and return 474 * immediately after reading TIFF header. 475 */ 476 if (tif->tif_flags & TIFF_HEADERONLY) 477 return (tif); 478 479 /* 480 * Setup initial directory. 481 */ 482 if (TIFFReadDirectory(tif)) { 483 tif->tif_rawcc = (tmsize_t)-1; 484 tif->tif_flags |= TIFF_BUFFERSETUP; 485 return (tif); 486 } 487 break; 488 case 'a': 489 /* 490 * New directories are automatically append 491 * to the end of the directory chain when they 492 * are written out (see TIFFWriteDirectory). 493 */ 494 if (!TIFFDefaultDirectory(tif)) 495 goto bad; 496 return (tif); 497 } 498 bad: 499 tif->tif_mode = O_RDONLY; /* XXX avoid flush */ 500 TIFFCleanup(tif); 501 bad2: 502 return ((TIFF*)0); 503 } 504 505 /* 506 * Query functions to access private data. 507 */ 508 509 /* 510 * Return open file's name. 511 */ 512 const char * 513 TIFFFileName(TIFF* tif) 514 { 515 return (tif->tif_name); 516 } 517 518 /* 519 * Set the file name. 520 */ 521 const char * 522 TIFFSetFileName(TIFF* tif, const char *name) 523 { 524 const char* old_name = tif->tif_name; 525 tif->tif_name = (char *)name; 526 return (old_name); 527 } 528 529 /* 530 * Return open file's I/O descriptor. 531 */ 532 int 533 TIFFFileno(TIFF* tif) 534 { 535 return (tif->tif_fd); 536 } 537 538 /* 539 * Set open file's I/O descriptor, and return previous value. 540 */ 541 int 542 TIFFSetFileno(TIFF* tif, int fd) 543 { 544 int old_fd = tif->tif_fd; 545 tif->tif_fd = fd; 546 return old_fd; 547 } 548 549 /* 550 * Return open file's clientdata. 551 */ 552 thandle_t 553 TIFFClientdata(TIFF* tif) 554 { 555 return (tif->tif_clientdata); 556 } 557 558 /* 559 * Set open file's clientdata, and return previous value. 560 */ 561 thandle_t 562 TIFFSetClientdata(TIFF* tif, thandle_t newvalue) 563 { 564 thandle_t m = tif->tif_clientdata; 565 tif->tif_clientdata = newvalue; 566 return m; 567 } 568 569 /* 570 * Return read/write mode. 571 */ 572 int 573 TIFFGetMode(TIFF* tif) 574 { 575 return (tif->tif_mode); 576 } 577 578 /* 579 * Return read/write mode. 580 */ 581 int 582 TIFFSetMode(TIFF* tif, int mode) 583 { 584 int old_mode = tif->tif_mode; 585 tif->tif_mode = mode; 586 return (old_mode); 587 } 588 589 /* 590 * Return nonzero if file is organized in 591 * tiles; zero if organized as strips. 592 */ 593 int 594 TIFFIsTiled(TIFF* tif) 595 { 596 return (isTiled(tif)); 597 } 598 599 /* 600 * Return current row being read/written. 601 */ 602 uint32 603 TIFFCurrentRow(TIFF* tif) 604 { 605 return (tif->tif_row); 606 } 607 608 /* 609 * Return index of the current directory. 610 */ 611 uint16 612 TIFFCurrentDirectory(TIFF* tif) 613 { 614 return (tif->tif_curdir); 615 } 616 617 /* 618 * Return current strip. 619 */ 620 uint32 621 TIFFCurrentStrip(TIFF* tif) 622 { 623 return (tif->tif_curstrip); 624 } 625 626 /* 627 * Return current tile. 628 */ 629 uint32 630 TIFFCurrentTile(TIFF* tif) 631 { 632 return (tif->tif_curtile); 633 } 634 635 /* 636 * Return nonzero if the file has byte-swapped data. 637 */ 638 int 639 TIFFIsByteSwapped(TIFF* tif) 640 { 641 return ((tif->tif_flags & TIFF_SWAB) != 0); 642 } 643 644 /* 645 * Return nonzero if the data is returned up-sampled. 646 */ 647 int 648 TIFFIsUpSampled(TIFF* tif) 649 { 650 return (isUpSampled(tif)); 651 } 652 653 /* 654 * Return nonzero if the data is returned in MSB-to-LSB bit order. 655 */ 656 int 657 TIFFIsMSB2LSB(TIFF* tif) 658 { 659 return (isFillOrder(tif, FILLORDER_MSB2LSB)); 660 } 661 662 /* 663 * Return nonzero if given file was written in big-endian order. 664 */ 665 int 666 TIFFIsBigEndian(TIFF* tif) 667 { 668 return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); 669 } 670 671 /* 672 * Return pointer to file read method. 673 */ 674 TIFFReadWriteProc 675 TIFFGetReadProc(TIFF* tif) 676 { 677 return (tif->tif_readproc); 678 } 679 680 /* 681 * Return pointer to file write method. 682 */ 683 TIFFReadWriteProc 684 TIFFGetWriteProc(TIFF* tif) 685 { 686 return (tif->tif_writeproc); 687 } 688 689 /* 690 * Return pointer to file seek method. 691 */ 692 TIFFSeekProc 693 TIFFGetSeekProc(TIFF* tif) 694 { 695 return (tif->tif_seekproc); 696 } 697 698 /* 699 * Return pointer to file close method. 700 */ 701 TIFFCloseProc 702 TIFFGetCloseProc(TIFF* tif) 703 { 704 return (tif->tif_closeproc); 705 } 706 707 /* 708 * Return pointer to file size requesting method. 709 */ 710 TIFFSizeProc 711 TIFFGetSizeProc(TIFF* tif) 712 { 713 return (tif->tif_sizeproc); 714 } 715 716 /* 717 * Return pointer to memory mapping method. 718 */ 719 TIFFMapFileProc 720 TIFFGetMapFileProc(TIFF* tif) 721 { 722 return (tif->tif_mapproc); 723 } 724 725 /* 726 * Return pointer to memory unmapping method. 727 */ 728 TIFFUnmapFileProc 729 TIFFGetUnmapFileProc(TIFF* tif) 730 { 731 return (tif->tif_unmapproc); 732 } 733 734 /* vim: set ts=8 sts=8 sw=8 noet: */ 735 /* 736 * Local Variables: 737 * mode: c 738 * c-basic-offset: 8 739 * fill-column: 78 740 * End: 741 */ 742