ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_dir.c
Go to the documentation of this file.
00001 /* $Id: tif_dir.c,v 1.75.2.5 2010-06-09 21:15:27 bfriesen Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1988-1997 Sam Leffler
00005  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 /*
00028  * TIFF Library.
00029  *
00030  * Directory Tag Get & Set Routines.
00031  * (and also some miscellaneous stuff)
00032  */
00033 #include "tiffiop.h"
00034 
00035 /*
00036  * These are used in the backwards compatibility code...
00037  */
00038 #define DATATYPE_VOID       0       /* !untyped data */
00039 #define DATATYPE_INT        1       /* !signed integer data */
00040 #define DATATYPE_UINT       2       /* !unsigned integer data */
00041 #define DATATYPE_IEEEFP     3       /* !IEEE floating point data */
00042 
00043 static void
00044 setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
00045 {
00046     if (*vpp)
00047         _TIFFfree(*vpp), *vpp = 0;
00048     if (vp) {
00049         tsize_t bytes = nmemb * elem_size;
00050         if (elem_size && bytes / elem_size == nmemb)
00051             *vpp = (void*) _TIFFmalloc(bytes);
00052         if (*vpp)
00053             _TIFFmemcpy(*vpp, vp, bytes);
00054     }
00055 }
00056 void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
00057     { setByteArray(vpp, vp, n, 1); }
00058 void _TIFFsetString(char** cpp, char* cp)
00059     { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
00060 void _TIFFsetNString(char** cpp, char* cp, uint32 n)
00061     { setByteArray((void**) cpp, (void*) cp, n, 1); }
00062 void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
00063     { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
00064 void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
00065     { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
00066 void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
00067     { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
00068 void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
00069     { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
00070 
00071 /*
00072  * Install extra samples information.
00073  */
00074 static int
00075 setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
00076 {
00077 /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
00078 #define EXTRASAMPLE_COREL_UNASSALPHA 999 
00079 
00080     uint16* va;
00081     uint32 i;
00082 
00083     *v = va_arg(ap, uint32);
00084     if ((uint16) *v > td->td_samplesperpixel)
00085         return 0;
00086     va = va_arg(ap, uint16*);
00087     if (*v > 0 && va == NULL)       /* typically missing param */
00088         return 0;
00089     for (i = 0; i < *v; i++) {
00090         if (va[i] > EXTRASAMPLE_UNASSALPHA) {
00091             /*
00092              * XXX: Corel Draw is known to produce incorrect
00093              * ExtraSamples tags which must be patched here if we
00094              * want to be able to open some of the damaged TIFF
00095              * files: 
00096              */
00097             if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
00098                 va[i] = EXTRASAMPLE_UNASSALPHA;
00099             else
00100                 return 0;
00101         }
00102     }
00103     td->td_extrasamples = (uint16) *v;
00104     _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
00105     return 1;
00106 
00107 #undef EXTRASAMPLE_COREL_UNASSALPHA
00108 }
00109 
00110 static uint32
00111 checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
00112 {
00113     TIFFDirectory* td = &tif->tif_dir;
00114     uint16 i = td->td_samplesperpixel;
00115 
00116     if (slen > 0) {
00117         const char* ep = s+slen;
00118         const char* cp = s;
00119         for (; i > 0; i--) {
00120             for (; *cp != '\0'; cp++)
00121                 if (cp >= ep)
00122                     goto bad;
00123             cp++;               /* skip \0 */
00124         }
00125         return (cp-s);
00126     }
00127 bad:
00128     TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
00129         "%s: Invalid InkNames value; expecting %d names, found %d",
00130         tif->tif_name,
00131         td->td_samplesperpixel,
00132         td->td_samplesperpixel-i);
00133     return (0);
00134 }
00135 
00136 static int
00137 _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
00138 {
00139     static const char module[] = "_TIFFVSetField";
00140 
00141     TIFFDirectory* td = &tif->tif_dir;
00142     int status = 1;
00143     uint32 v32, i, v;
00144     char* s;
00145 
00146     switch (tag) {
00147     case TIFFTAG_SUBFILETYPE:
00148         td->td_subfiletype = va_arg(ap, uint32);
00149         break;
00150     case TIFFTAG_IMAGEWIDTH:
00151         td->td_imagewidth = va_arg(ap, uint32);
00152         break;
00153     case TIFFTAG_IMAGELENGTH:
00154         td->td_imagelength = va_arg(ap, uint32);
00155         break;
00156     case TIFFTAG_BITSPERSAMPLE:
00157         td->td_bitspersample = (uint16) va_arg(ap, int);
00158         /*
00159          * If the data require post-decoding processing to byte-swap
00160          * samples, set it up here.  Note that since tags are required
00161          * to be ordered, compression code can override this behaviour
00162          * in the setup method if it wants to roll the post decoding
00163          * work in with its normal work.
00164          */
00165         if (tif->tif_flags & TIFF_SWAB) {
00166             if (td->td_bitspersample == 16)
00167                 tif->tif_postdecode = _TIFFSwab16BitData;
00168             else if (td->td_bitspersample == 24)
00169                 tif->tif_postdecode = _TIFFSwab24BitData;
00170             else if (td->td_bitspersample == 32)
00171                 tif->tif_postdecode = _TIFFSwab32BitData;
00172             else if (td->td_bitspersample == 64)
00173                 tif->tif_postdecode = _TIFFSwab64BitData;
00174             else if (td->td_bitspersample == 128) /* two 64's */
00175                 tif->tif_postdecode = _TIFFSwab64BitData;
00176         }
00177         break;
00178     case TIFFTAG_COMPRESSION:
00179         v = va_arg(ap, uint32) & 0xffff;
00180         /*
00181          * If we're changing the compression scheme, the notify the
00182          * previous module so that it can cleanup any state it's
00183          * setup.
00184          */
00185         if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
00186             if (td->td_compression == v)
00187                 break;
00188             (*tif->tif_cleanup)(tif);
00189             tif->tif_flags &= ~TIFF_CODERSETUP;
00190         }
00191         /*
00192          * Setup new compression routine state.
00193          */
00194         if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
00195                     td->td_compression = (uint16) v;
00196                 else
00197                     status = 0;
00198         break;
00199     case TIFFTAG_PHOTOMETRIC:
00200         td->td_photometric = (uint16) va_arg(ap, int);
00201         break;
00202     case TIFFTAG_THRESHHOLDING:
00203         td->td_threshholding = (uint16) va_arg(ap, int);
00204         break;
00205     case TIFFTAG_FILLORDER:
00206         v = va_arg(ap, uint32);
00207         if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
00208             goto badvalue;
00209         td->td_fillorder = (uint16) v;
00210         break;
00211     case TIFFTAG_ORIENTATION:
00212         v = va_arg(ap, uint32);
00213         if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
00214             goto badvalue;
00215         else
00216             td->td_orientation = (uint16) v;
00217         break;
00218     case TIFFTAG_SAMPLESPERPIXEL:
00219         /* XXX should cross check -- e.g. if pallette, then 1 */
00220         v = va_arg(ap, uint32);
00221         if (v == 0)
00222             goto badvalue;
00223         td->td_samplesperpixel = (uint16) v;
00224         break;
00225     case TIFFTAG_ROWSPERSTRIP:
00226         v32 = va_arg(ap, uint32);
00227         if (v32 == 0)
00228             goto badvalue32;
00229         td->td_rowsperstrip = v32;
00230         if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
00231             td->td_tilelength = v32;
00232             td->td_tilewidth = td->td_imagewidth;
00233         }
00234         break;
00235     case TIFFTAG_MINSAMPLEVALUE:
00236         td->td_minsamplevalue = (uint16) va_arg(ap, int);
00237         break;
00238     case TIFFTAG_MAXSAMPLEVALUE:
00239         td->td_maxsamplevalue = (uint16) va_arg(ap, int);
00240         break;
00241     case TIFFTAG_SMINSAMPLEVALUE:
00242         td->td_sminsamplevalue = va_arg(ap, double);
00243         break;
00244     case TIFFTAG_SMAXSAMPLEVALUE:
00245         td->td_smaxsamplevalue = va_arg(ap, double);
00246         break;
00247     case TIFFTAG_XRESOLUTION:
00248         td->td_xresolution = (float) va_arg(ap, double);
00249         break;
00250     case TIFFTAG_YRESOLUTION:
00251         td->td_yresolution = (float) va_arg(ap, double);
00252         break;
00253     case TIFFTAG_PLANARCONFIG:
00254         v = va_arg(ap, uint32);
00255         if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
00256             goto badvalue;
00257         td->td_planarconfig = (uint16) v;
00258         break;
00259     case TIFFTAG_XPOSITION:
00260         td->td_xposition = (float) va_arg(ap, double);
00261         break;
00262     case TIFFTAG_YPOSITION:
00263         td->td_yposition = (float) va_arg(ap, double);
00264         break;
00265     case TIFFTAG_RESOLUTIONUNIT:
00266         v = va_arg(ap, uint32);
00267         if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
00268             goto badvalue;
00269         td->td_resolutionunit = (uint16) v;
00270         break;
00271     case TIFFTAG_PAGENUMBER:
00272         td->td_pagenumber[0] = (uint16) va_arg(ap, int);
00273         td->td_pagenumber[1] = (uint16) va_arg(ap, int);
00274         break;
00275     case TIFFTAG_HALFTONEHINTS:
00276         td->td_halftonehints[0] = (uint16) va_arg(ap, int);
00277         td->td_halftonehints[1] = (uint16) va_arg(ap, int);
00278         break;
00279     case TIFFTAG_COLORMAP:
00280         v32 = (uint32)(1L<<td->td_bitspersample);
00281         _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
00282         _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
00283         _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
00284         break;
00285     case TIFFTAG_EXTRASAMPLES:
00286         if (!setExtraSamples(td, ap, &v))
00287             goto badvalue;
00288         break;
00289     case TIFFTAG_MATTEING:
00290         td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
00291         if (td->td_extrasamples) {
00292             uint16 sv = EXTRASAMPLE_ASSOCALPHA;
00293             _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
00294         }
00295         break;
00296     case TIFFTAG_TILEWIDTH:
00297         v32 = va_arg(ap, uint32);
00298         if (v32 % 16) {
00299             if (tif->tif_mode != O_RDONLY)
00300                 goto badvalue32;
00301             TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
00302                 "Nonstandard tile width %d, convert file", v32);
00303         }
00304         td->td_tilewidth = v32;
00305         tif->tif_flags |= TIFF_ISTILED;
00306         break;
00307     case TIFFTAG_TILELENGTH:
00308         v32 = va_arg(ap, uint32);
00309         if (v32 % 16) {
00310             if (tif->tif_mode != O_RDONLY)
00311                 goto badvalue32;
00312             TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
00313                 "Nonstandard tile length %d, convert file", v32);
00314         }
00315         td->td_tilelength = v32;
00316         tif->tif_flags |= TIFF_ISTILED;
00317         break;
00318     case TIFFTAG_TILEDEPTH:
00319         v32 = va_arg(ap, uint32);
00320         if (v32 == 0)
00321             goto badvalue32;
00322         td->td_tiledepth = v32;
00323         break;
00324     case TIFFTAG_DATATYPE:
00325         v = va_arg(ap, uint32);
00326         switch (v) {
00327         case DATATYPE_VOID: v = SAMPLEFORMAT_VOID;  break;
00328         case DATATYPE_INT:  v = SAMPLEFORMAT_INT;   break;
00329         case DATATYPE_UINT: v = SAMPLEFORMAT_UINT;  break;
00330         case DATATYPE_IEEEFP:   v = SAMPLEFORMAT_IEEEFP;break;
00331         default:        goto badvalue;
00332         }
00333         td->td_sampleformat = (uint16) v;
00334         break;
00335     case TIFFTAG_SAMPLEFORMAT:
00336         v = va_arg(ap, uint32);
00337         if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
00338             goto badvalue;
00339         td->td_sampleformat = (uint16) v;
00340 
00341                 /*  Try to fix up the SWAB function for complex data. */
00342                 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
00343                     && td->td_bitspersample == 32
00344                     && tif->tif_postdecode == _TIFFSwab32BitData )
00345                     tif->tif_postdecode = _TIFFSwab16BitData;
00346                 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
00347                           || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
00348                          && td->td_bitspersample == 64
00349                          && tif->tif_postdecode == _TIFFSwab64BitData )
00350                     tif->tif_postdecode = _TIFFSwab32BitData;
00351         break;
00352     case TIFFTAG_IMAGEDEPTH:
00353         td->td_imagedepth = va_arg(ap, uint32);
00354         break;
00355     case TIFFTAG_SUBIFD:
00356         if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
00357             td->td_nsubifd = (uint16) va_arg(ap, int);
00358             _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
00359                 (long) td->td_nsubifd);
00360         } else {
00361             TIFFErrorExt(tif->tif_clientdata, module,
00362                      "%s: Sorry, cannot nest SubIFDs",
00363                      tif->tif_name);
00364             status = 0;
00365         }
00366         break;
00367     case TIFFTAG_YCBCRPOSITIONING:
00368         td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
00369         break;
00370     case TIFFTAG_YCBCRSUBSAMPLING:
00371         td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
00372         td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
00373         break;
00374     case TIFFTAG_TRANSFERFUNCTION:
00375         v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
00376         for (i = 0; i < v; i++)
00377             _TIFFsetShortArray(&td->td_transferfunction[i],
00378                 va_arg(ap, uint16*), 1L<<td->td_bitspersample);
00379         break;
00380     case TIFFTAG_REFERENCEBLACKWHITE:
00381         /* XXX should check for null range */
00382         _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
00383         break;
00384     case TIFFTAG_INKNAMES:
00385         v = va_arg(ap, uint32);
00386         s = va_arg(ap, char*);
00387         v = checkInkNamesString(tif, v, s);
00388                 status = v > 0;
00389         if( v > 0 ) {
00390             _TIFFsetNString(&td->td_inknames, s, v);
00391             td->td_inknameslen = v;
00392         }
00393         break;
00394         default: {
00395             TIFFTagValue *tv;
00396             int tv_size, iCustom;
00397         const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
00398 
00399             /*
00400          * This can happen if multiple images are open with different
00401          * codecs which have private tags.  The global tag information
00402          * table may then have tags that are valid for one file but not
00403          * the other. If the client tries to set a tag that is not valid
00404          * for the image's codec then we'll arrive here.  This
00405          * happens, for example, when tiffcp is used to convert between
00406          * compression schemes and codec-specific tags are blindly copied.
00407              */
00408             if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
00409         TIFFErrorExt(tif->tif_clientdata, module,
00410                  "%s: Invalid %stag \"%s\" (not supported by codec)",
00411                  tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
00412                  fip ? fip->field_name : "Unknown");
00413         status = 0;
00414         break;
00415             }
00416 
00417             /*
00418              * Find the existing entry for this custom value.
00419              */
00420             tv = NULL;
00421             for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
00422             if (td->td_customValues[iCustom].info->field_tag == tag) {
00423                 tv = td->td_customValues + iCustom;
00424                 if (tv->value != NULL) {
00425                     _TIFFfree(tv->value);
00426                     tv->value = NULL;
00427                 }
00428                 break;
00429             }
00430             }
00431 
00432             /*
00433              * Grow the custom list if the entry was not found.
00434              */
00435             if(tv == NULL) {
00436         TIFFTagValue    *new_customValues;
00437         
00438         td->td_customValueCount++;
00439         new_customValues = (TIFFTagValue *)
00440             _TIFFrealloc(td->td_customValues,
00441                      sizeof(TIFFTagValue) * td->td_customValueCount);
00442         if (!new_customValues) {
00443             TIFFErrorExt(tif->tif_clientdata, module,
00444         "%s: Failed to allocate space for list of custom values",
00445                   tif->tif_name);
00446             status = 0;
00447             goto end;
00448         }
00449 
00450         td->td_customValues = new_customValues;
00451 
00452                 tv = td->td_customValues + (td->td_customValueCount - 1);
00453                 tv->info = fip;
00454                 tv->value = NULL;
00455                 tv->count = 0;
00456             }
00457 
00458             /*
00459              * Set custom value ... save a copy of the custom tag value.
00460              */
00461         tv_size = _TIFFDataSize(fip->field_type);
00462         if (tv_size == 0) {
00463             status = 0;
00464             TIFFErrorExt(tif->tif_clientdata, module,
00465                  "%s: Bad field type %d for \"%s\"",
00466                  tif->tif_name, fip->field_type,
00467                  fip->field_name);
00468             goto end;
00469         }
00470            
00471             if(fip->field_passcount) {
00472             if (fip->field_writecount == TIFF_VARIABLE2)
00473             tv->count = (uint32) va_arg(ap, uint32);
00474             else
00475             tv->count = (int) va_arg(ap, int);
00476         } else if (fip->field_writecount == TIFF_VARIABLE
00477                || fip->field_writecount == TIFF_VARIABLE2)
00478         tv->count = 1;
00479         else if (fip->field_writecount == TIFF_SPP)
00480         tv->count = td->td_samplesperpixel;
00481         else
00482                 tv->count = fip->field_writecount;
00483             
00484     
00485         if (fip->field_type == TIFF_ASCII)
00486             _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
00487         else {
00488         tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count,
00489                          "Tag Value");
00490         if (!tv->value) {
00491             status = 0;
00492             goto end;
00493         }
00494 
00495         if ((fip->field_passcount
00496             || fip->field_writecount == TIFF_VARIABLE
00497             || fip->field_writecount == TIFF_VARIABLE2
00498             || fip->field_writecount == TIFF_SPP
00499             || tv->count > 1)
00500             && fip->field_tag != TIFFTAG_PAGENUMBER
00501             && fip->field_tag != TIFFTAG_HALFTONEHINTS
00502             && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
00503             && fip->field_tag != TIFFTAG_DOTRANGE) {
00504                     _TIFFmemcpy(tv->value, va_arg(ap, void *),
00505                 tv->count * tv_size);
00506         } else {
00507             /*
00508              * XXX: The following loop required to handle
00509              * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
00510              * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
00511              * These tags are actually arrays and should be passed as
00512              * array pointers to TIFFSetField() function, but actually
00513              * passed as a list of separate values. This behaviour
00514              * must be changed in the future!
00515              */
00516             int i;
00517             char *val = (char *)tv->value;
00518 
00519             for (i = 0; i < tv->count; i++, val += tv_size) {
00520                 switch (fip->field_type) {
00521                 case TIFF_BYTE:
00522                 case TIFF_UNDEFINED:
00523                     {
00524                     uint8 v = (uint8)va_arg(ap, int);
00525                     _TIFFmemcpy(val, &v, tv_size);
00526                     }
00527                     break;
00528                 case TIFF_SBYTE:
00529                     {
00530                     int8 v = (int8)va_arg(ap, int);
00531                     _TIFFmemcpy(val, &v, tv_size);
00532                     }
00533                     break;
00534                 case TIFF_SHORT:
00535                     {
00536                     uint16 v = (uint16)va_arg(ap, int);
00537                     _TIFFmemcpy(val, &v, tv_size);
00538                     }
00539                     break;
00540                 case TIFF_SSHORT:
00541                     {
00542                     int16 v = (int16)va_arg(ap, int);
00543                     _TIFFmemcpy(val, &v, tv_size);
00544                     }
00545                     break;
00546                 case TIFF_LONG:
00547                 case TIFF_IFD:
00548                     {
00549                     uint32 v = va_arg(ap, uint32);
00550                     _TIFFmemcpy(val, &v, tv_size);
00551                     }
00552                     break;
00553                 case TIFF_SLONG:
00554                     {
00555                     int32 v = va_arg(ap, int32);
00556                     _TIFFmemcpy(val, &v, tv_size);
00557                     }
00558                     break;
00559                 case TIFF_RATIONAL:
00560                 case TIFF_SRATIONAL:
00561                 case TIFF_FLOAT:
00562                     {
00563                     float v = (float)va_arg(ap, double);
00564                     _TIFFmemcpy(val, &v, tv_size);
00565                     }
00566                     break;
00567                 case TIFF_DOUBLE:
00568                     {
00569                     double v = va_arg(ap, double);
00570                     _TIFFmemcpy(val, &v, tv_size);
00571                     }
00572                     break;
00573                 default:
00574                     _TIFFmemset(val, 0, tv_size);
00575                     status = 0;
00576                     break;
00577                 }
00578             }
00579         }
00580         }
00581           }
00582     }
00583     if (status) {
00584         TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
00585         tif->tif_flags |= TIFF_DIRTYDIRECT;
00586     }
00587 
00588 end:
00589     va_end(ap);
00590     return (status);
00591 badvalue:
00592     TIFFErrorExt(tif->tif_clientdata, module,
00593              "%s: Bad value %d for \"%s\" tag",
00594              tif->tif_name, v,
00595              _TIFFFieldWithTag(tif, tag)->field_name);
00596     va_end(ap);
00597     return (0);
00598 badvalue32:
00599     TIFFErrorExt(tif->tif_clientdata, module,
00600              "%s: Bad value %u for \"%s\" tag",
00601              tif->tif_name, v32,
00602              _TIFFFieldWithTag(tif, tag)->field_name);
00603     va_end(ap);
00604     return (0);
00605 }
00606 
00607 /*
00608  * Return 1/0 according to whether or not
00609  * it is permissible to set the tag's value.
00610  * Note that we allow ImageLength to be changed
00611  * so that we can append and extend to images.
00612  * Any other tag may not be altered once writing
00613  * has commenced, unless its value has no effect
00614  * on the format of the data that is written.
00615  */
00616 static int
00617 OkToChangeTag(TIFF* tif, ttag_t tag)
00618 {
00619     const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
00620     if (!fip) {         /* unknown tag */
00621         TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
00622             tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
00623         return (0);
00624     }
00625     if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
00626         !fip->field_oktochange) {
00627         /*
00628          * Consult info table to see if tag can be changed
00629          * after we've started writing.  We only allow changes
00630          * to those tags that don't/shouldn't affect the
00631          * compression and/or format of the data.
00632          */
00633         TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
00634             "%s: Cannot modify tag \"%s\" while writing",
00635             tif->tif_name, fip->field_name);
00636         return (0);
00637     }
00638     return (1);
00639 }
00640 
00641 /*
00642  * Record the value of a field in the
00643  * internal directory structure.  The
00644  * field will be written to the file
00645  * when/if the directory structure is
00646  * updated.
00647  */
00648 int
00649 TIFFSetField(TIFF* tif, ttag_t tag, ...)
00650 {
00651     va_list ap;
00652     int status;
00653 
00654     va_start(ap, tag);
00655     status = TIFFVSetField(tif, tag, ap);
00656     va_end(ap);
00657     return (status);
00658 }
00659 
00660 /*
00661  * Like TIFFSetField, but taking a varargs
00662  * parameter list.  This routine is useful
00663  * for building higher-level interfaces on
00664  * top of the library.
00665  */
00666 int
00667 TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
00668 {
00669     return OkToChangeTag(tif, tag) ?
00670         (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
00671 }
00672 
00673 static int
00674 _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
00675 {
00676     TIFFDirectory* td = &tif->tif_dir;
00677     int            ret_val = 1;
00678 
00679     switch (tag) {
00680     case TIFFTAG_SUBFILETYPE:
00681             *va_arg(ap, uint32*) = td->td_subfiletype;
00682             break;
00683     case TIFFTAG_IMAGEWIDTH:
00684             *va_arg(ap, uint32*) = td->td_imagewidth;
00685             break;
00686     case TIFFTAG_IMAGELENGTH:
00687             *va_arg(ap, uint32*) = td->td_imagelength;
00688             break;
00689     case TIFFTAG_BITSPERSAMPLE:
00690             *va_arg(ap, uint16*) = td->td_bitspersample;
00691             break;
00692     case TIFFTAG_COMPRESSION:
00693             *va_arg(ap, uint16*) = td->td_compression;
00694             break;
00695     case TIFFTAG_PHOTOMETRIC:
00696             *va_arg(ap, uint16*) = td->td_photometric;
00697             break;
00698     case TIFFTAG_THRESHHOLDING:
00699             *va_arg(ap, uint16*) = td->td_threshholding;
00700             break;
00701     case TIFFTAG_FILLORDER:
00702             *va_arg(ap, uint16*) = td->td_fillorder;
00703             break;
00704     case TIFFTAG_ORIENTATION:
00705             *va_arg(ap, uint16*) = td->td_orientation;
00706             break;
00707     case TIFFTAG_SAMPLESPERPIXEL:
00708             *va_arg(ap, uint16*) = td->td_samplesperpixel;
00709             break;
00710     case TIFFTAG_ROWSPERSTRIP:
00711             *va_arg(ap, uint32*) = td->td_rowsperstrip;
00712             break;
00713     case TIFFTAG_MINSAMPLEVALUE:
00714             *va_arg(ap, uint16*) = td->td_minsamplevalue;
00715             break;
00716     case TIFFTAG_MAXSAMPLEVALUE:
00717             *va_arg(ap, uint16*) = td->td_maxsamplevalue;
00718             break;
00719     case TIFFTAG_SMINSAMPLEVALUE:
00720             *va_arg(ap, double*) = td->td_sminsamplevalue;
00721             break;
00722     case TIFFTAG_SMAXSAMPLEVALUE:
00723             *va_arg(ap, double*) = td->td_smaxsamplevalue;
00724             break;
00725     case TIFFTAG_XRESOLUTION:
00726             *va_arg(ap, float*) = td->td_xresolution;
00727             break;
00728     case TIFFTAG_YRESOLUTION:
00729             *va_arg(ap, float*) = td->td_yresolution;
00730             break;
00731     case TIFFTAG_PLANARCONFIG:
00732             *va_arg(ap, uint16*) = td->td_planarconfig;
00733             break;
00734     case TIFFTAG_XPOSITION:
00735             *va_arg(ap, float*) = td->td_xposition;
00736             break;
00737     case TIFFTAG_YPOSITION:
00738             *va_arg(ap, float*) = td->td_yposition;
00739             break;
00740     case TIFFTAG_RESOLUTIONUNIT:
00741             *va_arg(ap, uint16*) = td->td_resolutionunit;
00742             break;
00743     case TIFFTAG_PAGENUMBER:
00744             *va_arg(ap, uint16*) = td->td_pagenumber[0];
00745             *va_arg(ap, uint16*) = td->td_pagenumber[1];
00746             break;
00747     case TIFFTAG_HALFTONEHINTS:
00748             *va_arg(ap, uint16*) = td->td_halftonehints[0];
00749             *va_arg(ap, uint16*) = td->td_halftonehints[1];
00750             break;
00751     case TIFFTAG_COLORMAP:
00752             *va_arg(ap, uint16**) = td->td_colormap[0];
00753             *va_arg(ap, uint16**) = td->td_colormap[1];
00754             *va_arg(ap, uint16**) = td->td_colormap[2];
00755             break;
00756     case TIFFTAG_STRIPOFFSETS:
00757     case TIFFTAG_TILEOFFSETS:
00758             *va_arg(ap, uint32**) = td->td_stripoffset;
00759             break;
00760     case TIFFTAG_STRIPBYTECOUNTS:
00761     case TIFFTAG_TILEBYTECOUNTS:
00762             *va_arg(ap, uint32**) = td->td_stripbytecount;
00763             break;
00764     case TIFFTAG_MATTEING:
00765             *va_arg(ap, uint16*) =
00766                 (td->td_extrasamples == 1 &&
00767                  td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
00768             break;
00769     case TIFFTAG_EXTRASAMPLES:
00770             *va_arg(ap, uint16*) = td->td_extrasamples;
00771             *va_arg(ap, uint16**) = td->td_sampleinfo;
00772             break;
00773     case TIFFTAG_TILEWIDTH:
00774             *va_arg(ap, uint32*) = td->td_tilewidth;
00775             break;
00776     case TIFFTAG_TILELENGTH:
00777             *va_arg(ap, uint32*) = td->td_tilelength;
00778             break;
00779     case TIFFTAG_TILEDEPTH:
00780             *va_arg(ap, uint32*) = td->td_tiledepth;
00781             break;
00782     case TIFFTAG_DATATYPE:
00783             switch (td->td_sampleformat) {
00784         case SAMPLEFORMAT_UINT:
00785                     *va_arg(ap, uint16*) = DATATYPE_UINT;
00786                     break;
00787         case SAMPLEFORMAT_INT:
00788                     *va_arg(ap, uint16*) = DATATYPE_INT;
00789                     break;
00790         case SAMPLEFORMAT_IEEEFP:
00791                     *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
00792                     break;
00793         case SAMPLEFORMAT_VOID:
00794                     *va_arg(ap, uint16*) = DATATYPE_VOID;
00795                     break;
00796             }
00797             break;
00798     case TIFFTAG_SAMPLEFORMAT:
00799             *va_arg(ap, uint16*) = td->td_sampleformat;
00800             break;
00801     case TIFFTAG_IMAGEDEPTH:
00802             *va_arg(ap, uint32*) = td->td_imagedepth;
00803             break;
00804     case TIFFTAG_SUBIFD:
00805             *va_arg(ap, uint16*) = td->td_nsubifd;
00806             *va_arg(ap, uint32**) = td->td_subifd;
00807             break;
00808     case TIFFTAG_YCBCRPOSITIONING:
00809             *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
00810             break;
00811     case TIFFTAG_YCBCRSUBSAMPLING:
00812             *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
00813             *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
00814             break;
00815     case TIFFTAG_TRANSFERFUNCTION:
00816             *va_arg(ap, uint16**) = td->td_transferfunction[0];
00817             if (td->td_samplesperpixel - td->td_extrasamples > 1) {
00818                 *va_arg(ap, uint16**) = td->td_transferfunction[1];
00819                 *va_arg(ap, uint16**) = td->td_transferfunction[2];
00820             }
00821             break;
00822     case TIFFTAG_REFERENCEBLACKWHITE:
00823         *va_arg(ap, float**) = td->td_refblackwhite;
00824         break;
00825     case TIFFTAG_INKNAMES:
00826             *va_arg(ap, char**) = td->td_inknames;
00827             break;
00828         default:
00829         {
00830             const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
00831             int           i;
00832             
00833             /*
00834          * This can happen if multiple images are open with different
00835          * codecs which have private tags.  The global tag information
00836          * table may then have tags that are valid for one file but not
00837          * the other. If the client tries to get a tag that is not valid
00838          * for the image's codec then we'll arrive here.
00839              */
00840             if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
00841             {
00842             TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
00843                  "%s: Invalid %stag \"%s\" "
00844                  "(not supported by codec)",
00845                  tif->tif_name,
00846                  isPseudoTag(tag) ? "pseudo-" : "",
00847                  fip ? fip->field_name : "Unknown");
00848             ret_val = 0;
00849             break;
00850             }
00851 
00852             /*
00853          * Do we have a custom value?
00854          */
00855             ret_val = 0;
00856             for (i = 0; i < td->td_customValueCount; i++) {
00857         TIFFTagValue *tv = td->td_customValues + i;
00858 
00859         if (tv->info->field_tag != tag)
00860             continue;
00861                 
00862         if (fip->field_passcount) {
00863             if (fip->field_readcount == TIFF_VARIABLE2) 
00864                 *va_arg(ap, uint32*) = (uint32)tv->count;
00865             else    /* Assume TIFF_VARIABLE */
00866                 *va_arg(ap, uint16*) = (uint16)tv->count;
00867             *va_arg(ap, void **) = tv->value;
00868             ret_val = 1;
00869                 } else {
00870             if ((fip->field_type == TIFF_ASCII
00871                 || fip->field_readcount == TIFF_VARIABLE
00872                 || fip->field_readcount == TIFF_VARIABLE2
00873                 || fip->field_readcount == TIFF_SPP
00874                 || tv->count > 1)
00875                 && fip->field_tag != TIFFTAG_PAGENUMBER
00876                 && fip->field_tag != TIFFTAG_HALFTONEHINTS
00877                 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
00878                 && fip->field_tag != TIFFTAG_DOTRANGE) {
00879                 *va_arg(ap, void **) = tv->value;
00880                 ret_val = 1;
00881             } else {
00882                 int j;
00883                 char *val = (char *)tv->value;
00884 
00885                 for (j = 0; j < tv->count;
00886                  j++, val += _TIFFDataSize(tv->info->field_type)) {
00887                 switch (fip->field_type) {
00888                     case TIFF_BYTE:
00889                     case TIFF_UNDEFINED:
00890                         *va_arg(ap, uint8*) =
00891                             *(uint8 *)val;
00892                         ret_val = 1;
00893                         break;
00894                     case TIFF_SBYTE:
00895                         *va_arg(ap, int8*) =
00896                             *(int8 *)val;
00897                         ret_val = 1;
00898                         break;
00899                     case TIFF_SHORT:
00900                         *va_arg(ap, uint16*) =
00901                             *(uint16 *)val;
00902                         ret_val = 1;
00903                         break;
00904                     case TIFF_SSHORT:
00905                         *va_arg(ap, int16*) =
00906                             *(int16 *)val;
00907                         ret_val = 1;
00908                         break;
00909                     case TIFF_LONG:
00910                     case TIFF_IFD:
00911                         *va_arg(ap, uint32*) =
00912                             *(uint32 *)val;
00913                         ret_val = 1;
00914                         break;
00915                     case TIFF_SLONG:
00916                         *va_arg(ap, int32*) =
00917                             *(int32 *)val;
00918                         ret_val = 1;
00919                         break;
00920                     case TIFF_RATIONAL:
00921                     case TIFF_SRATIONAL:
00922                     case TIFF_FLOAT:
00923                         *va_arg(ap, float*) =
00924                             *(float *)val;
00925                         ret_val = 1;
00926                         break;
00927                     case TIFF_DOUBLE:
00928                         *va_arg(ap, double*) =
00929                             *(double *)val;
00930                         ret_val = 1;
00931                         break;
00932                     default:
00933                         ret_val = 0;
00934                         break;
00935                 }
00936                 }
00937             }
00938                 }
00939         break;
00940             }
00941         }
00942     }
00943     return(ret_val);
00944 }
00945 
00946 /*
00947  * Return the value of a field in the
00948  * internal directory structure.
00949  */
00950 int
00951 TIFFGetField(TIFF* tif, ttag_t tag, ...)
00952 {
00953     int status;
00954     va_list ap;
00955 
00956     va_start(ap, tag);
00957     status = TIFFVGetField(tif, tag, ap);
00958     va_end(ap);
00959     return (status);
00960 }
00961 
00962 /*
00963  * Like TIFFGetField, but taking a varargs
00964  * parameter list.  This routine is useful
00965  * for building higher-level interfaces on
00966  * top of the library.
00967  */
00968 int
00969 TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
00970 {
00971     const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
00972     return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
00973         (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
00974 }
00975 
00976 #define CleanupField(member) {      \
00977     if (td->member) {           \
00978     _TIFFfree(td->member);      \
00979     td->member = 0;         \
00980     }                   \
00981 }
00982 
00983 /*
00984  * Release storage associated with a directory.
00985  */
00986 void
00987 TIFFFreeDirectory(TIFF* tif)
00988 {
00989     TIFFDirectory *td = &tif->tif_dir;
00990     int            i;
00991 
00992     _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
00993     CleanupField(td_colormap[0]);
00994     CleanupField(td_colormap[1]);
00995     CleanupField(td_colormap[2]);
00996     CleanupField(td_sampleinfo);
00997     CleanupField(td_subifd);
00998     CleanupField(td_inknames);
00999     CleanupField(td_refblackwhite);
01000     CleanupField(td_transferfunction[0]);
01001     CleanupField(td_transferfunction[1]);
01002     CleanupField(td_transferfunction[2]);
01003     CleanupField(td_stripoffset);
01004     CleanupField(td_stripbytecount);
01005     TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
01006     TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
01007 
01008     /* Cleanup custom tag values */
01009     for( i = 0; i < td->td_customValueCount; i++ ) {
01010         if (td->td_customValues[i].value)
01011             _TIFFfree(td->td_customValues[i].value);
01012     }
01013 
01014     td->td_customValueCount = 0;
01015     CleanupField(td_customValues);
01016 }
01017 #undef CleanupField
01018 
01019 /*
01020  * Client Tag extension support (from Niles Ritter).
01021  */
01022 static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
01023 
01024 TIFFExtendProc
01025 TIFFSetTagExtender(TIFFExtendProc extender)
01026 {
01027     TIFFExtendProc prev = _TIFFextender;
01028     _TIFFextender = extender;
01029     return (prev);
01030 }
01031 
01032 /*
01033  * Setup for a new directory.  Should we automatically call
01034  * TIFFWriteDirectory() if the current one is dirty?
01035  *
01036  * The newly created directory will not exist on the file till
01037  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
01038  */
01039 int
01040 TIFFCreateDirectory(TIFF* tif)
01041 {
01042     TIFFDefaultDirectory(tif);
01043     tif->tif_diroff = 0;
01044     tif->tif_nextdiroff = 0;
01045     tif->tif_curoff = 0;
01046     tif->tif_row = (uint32) -1;
01047     tif->tif_curstrip = (tstrip_t) -1;
01048 
01049     return 0;
01050 }
01051 
01052 /*
01053  * Setup a default directory structure.
01054  */
01055 int
01056 TIFFDefaultDirectory(TIFF* tif)
01057 {
01058     register TIFFDirectory* td = &tif->tif_dir;
01059 
01060     size_t tiffFieldInfoCount;
01061     const TIFFFieldInfo *tiffFieldInfo =
01062         _TIFFGetFieldInfo(&tiffFieldInfoCount);
01063     _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
01064 
01065     _TIFFmemset(td, 0, sizeof (*td));
01066     td->td_fillorder = FILLORDER_MSB2LSB;
01067     td->td_bitspersample = 1;
01068     td->td_threshholding = THRESHHOLD_BILEVEL;
01069     td->td_orientation = ORIENTATION_TOPLEFT;
01070     td->td_samplesperpixel = 1;
01071     td->td_rowsperstrip = (uint32) -1;
01072     td->td_tilewidth = 0;
01073     td->td_tilelength = 0;
01074     td->td_tiledepth = 1;
01075     td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
01076     td->td_resolutionunit = RESUNIT_INCH;
01077     td->td_sampleformat = SAMPLEFORMAT_UINT;
01078     td->td_imagedepth = 1;
01079     td->td_ycbcrsubsampling[0] = 2;
01080     td->td_ycbcrsubsampling[1] = 2;
01081     td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
01082     tif->tif_postdecode = _TIFFNoPostDecode;
01083     tif->tif_foundfield = NULL;
01084     tif->tif_tagmethods.vsetfield = _TIFFVSetField;
01085     tif->tif_tagmethods.vgetfield = _TIFFVGetField;
01086     tif->tif_tagmethods.printdir = NULL;
01087     /*
01088      *  Give client code a chance to install their own
01089      *  tag extensions & methods, prior to compression overloads.
01090      */
01091     if (_TIFFextender)
01092         (*_TIFFextender)(tif);
01093     (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
01094     /*
01095      * NB: The directory is marked dirty as a result of setting
01096      * up the default compression scheme.  However, this really
01097      * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
01098      * if the user does something.  We could just do the setup
01099      * by hand, but it seems better to use the normal mechanism
01100      * (i.e. TIFFSetField).
01101      */
01102     tif->tif_flags &= ~TIFF_DIRTYDIRECT;
01103 
01104     /*
01105      * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
01106      * we clear the ISTILED flag when setting up a new directory.
01107      * Should we also be clearing stuff like INSUBIFD?
01108      */
01109     tif->tif_flags &= ~TIFF_ISTILED;
01110         /*
01111          * Clear other directory-specific fields.
01112          */
01113         tif->tif_tilesize = -1;
01114         tif->tif_scanlinesize = -1;
01115 
01116     return (1);
01117 }
01118 
01119 static int
01120 TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
01121 {
01122     static const char module[] = "TIFFAdvanceDirectory";
01123     uint16 dircount;
01124     if (isMapped(tif))
01125     {
01126         toff_t poff=*nextdir;
01127         if (poff+sizeof(uint16) > tif->tif_size)
01128         {
01129             TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
01130                 tif->tif_name);
01131             return (0);
01132         }
01133         _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
01134         if (tif->tif_flags & TIFF_SWAB)
01135             TIFFSwabShort(&dircount);
01136         poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
01137         if (off != NULL)
01138             *off = poff;
01139         if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
01140         {
01141             TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
01142                 tif->tif_name);
01143             return (0);
01144         }
01145         _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
01146         if (tif->tif_flags & TIFF_SWAB)
01147             TIFFSwabLong(nextdir);
01148         return (1);
01149     }
01150     else
01151     {
01152         if (!SeekOK(tif, *nextdir) ||
01153             !ReadOK(tif, &dircount, sizeof (uint16))) {
01154             TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
01155                 tif->tif_name);
01156             return (0);
01157         }
01158         if (tif->tif_flags & TIFF_SWAB)
01159             TIFFSwabShort(&dircount);
01160         if (off != NULL)
01161             *off = TIFFSeekFile(tif,
01162                 dircount*sizeof (TIFFDirEntry), SEEK_CUR);
01163         else
01164             (void) TIFFSeekFile(tif,
01165                 dircount*sizeof (TIFFDirEntry), SEEK_CUR);
01166         if (!ReadOK(tif, nextdir, sizeof (uint32))) {
01167             TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
01168                 tif->tif_name);
01169             return (0);
01170         }
01171         if (tif->tif_flags & TIFF_SWAB)
01172             TIFFSwabLong(nextdir);
01173         return (1);
01174     }
01175 }
01176 
01177 /*
01178  * Count the number of directories in a file.
01179  */
01180 tdir_t
01181 TIFFNumberOfDirectories(TIFF* tif)
01182 {
01183     toff_t nextdir = tif->tif_header.tiff_diroff;
01184     tdir_t n = 0;
01185     
01186     while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
01187         n++;
01188     return (n);
01189 }
01190 
01191 /*
01192  * Set the n-th directory as the current directory.
01193  * NB: Directories are numbered starting at 0.
01194  */
01195 int
01196 TIFFSetDirectory(TIFF* tif, tdir_t dirn)
01197 {
01198     toff_t nextdir;
01199     tdir_t n;
01200 
01201     nextdir = tif->tif_header.tiff_diroff;
01202     for (n = dirn; n > 0 && nextdir != 0; n--)
01203         if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
01204             return (0);
01205     tif->tif_nextdiroff = nextdir;
01206     /*
01207      * Set curdir to the actual directory index.  The
01208      * -1 is because TIFFReadDirectory will increment
01209      * tif_curdir after successfully reading the directory.
01210      */
01211     tif->tif_curdir = (dirn - n) - 1;
01212     /*
01213      * Reset tif_dirnumber counter and start new list of seen directories.
01214      * We need this to prevent IFD loops.
01215      */
01216     tif->tif_dirnumber = 0;
01217     return (TIFFReadDirectory(tif));
01218 }
01219 
01220 /*
01221  * Set the current directory to be the directory
01222  * located at the specified file offset.  This interface
01223  * is used mainly to access directories linked with
01224  * the SubIFD tag (e.g. thumbnail images).
01225  */
01226 int
01227 TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
01228 {
01229     tif->tif_nextdiroff = diroff;
01230     /*
01231      * Reset tif_dirnumber counter and start new list of seen directories.
01232      * We need this to prevent IFD loops.
01233      */
01234     tif->tif_dirnumber = 0;
01235     return (TIFFReadDirectory(tif));
01236 }
01237 
01238 /*
01239  * Return file offset of the current directory.
01240  */
01241 uint32
01242 TIFFCurrentDirOffset(TIFF* tif)
01243 {
01244     return (tif->tif_diroff);
01245 }
01246 
01247 /*
01248  * Return an indication of whether or not we are
01249  * at the last directory in the file.
01250  */
01251 int
01252 TIFFLastDirectory(TIFF* tif)
01253 {
01254     return (tif->tif_nextdiroff == 0);
01255 }
01256 
01257 /*
01258  * Unlink the specified directory from the directory chain.
01259  */
01260 int
01261 TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
01262 {
01263     static const char module[] = "TIFFUnlinkDirectory";
01264     toff_t nextdir;
01265     toff_t off;
01266     tdir_t n;
01267 
01268     if (tif->tif_mode == O_RDONLY) {
01269         TIFFErrorExt(tif->tif_clientdata, module,
01270                              "Can not unlink directory in read-only file");
01271         return (0);
01272     }
01273     /*
01274      * Go to the directory before the one we want
01275      * to unlink and nab the offset of the link
01276      * field we'll need to patch.
01277      */
01278     nextdir = tif->tif_header.tiff_diroff;
01279     off = sizeof (uint16) + sizeof (uint16);
01280     for (n = dirn-1; n > 0; n--) {
01281         if (nextdir == 0) {
01282             TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
01283             return (0);
01284         }
01285         if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
01286             return (0);
01287     }
01288     /*
01289      * Advance to the directory to be unlinked and fetch
01290      * the offset of the directory that follows.
01291      */
01292     if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
01293         return (0);
01294     /*
01295      * Go back and patch the link field of the preceding
01296      * directory to point to the offset of the directory
01297      * that follows.
01298      */
01299     (void) TIFFSeekFile(tif, off, SEEK_SET);
01300     if (tif->tif_flags & TIFF_SWAB)
01301         TIFFSwabLong(&nextdir);
01302     if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
01303         TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
01304         return (0);
01305     }
01306     /*
01307      * Leave directory state setup safely.  We don't have
01308      * facilities for doing inserting and removing directories,
01309      * so it's safest to just invalidate everything.  This
01310      * means that the caller can only append to the directory
01311      * chain.
01312      */
01313     (*tif->tif_cleanup)(tif);
01314     if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
01315         _TIFFfree(tif->tif_rawdata);
01316         tif->tif_rawdata = NULL;
01317         tif->tif_rawcc = 0;
01318     }
01319     tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
01320     TIFFFreeDirectory(tif);
01321     TIFFDefaultDirectory(tif);
01322     tif->tif_diroff = 0;            /* force link on next write */
01323     tif->tif_nextdiroff = 0;        /* next write must be at end */
01324     tif->tif_curoff = 0;
01325     tif->tif_row = (uint32) -1;
01326     tif->tif_curstrip = (tstrip_t) -1;
01327     return (1);
01328 }
01329 
01330 /*          [BFC]
01331  *
01332  * Author: Bruce Cameron <cameron@petris.com>
01333  *
01334  * Set a table of tags that are to be replaced during directory process by the
01335  * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
01336  * 'ReadDirectory' can use the stored information.
01337  *
01338  * FIXME: this is never used properly. Should be removed in the future.
01339  */
01340 int
01341 TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
01342 {
01343     static int TIFFignoretags [FIELD_LAST];
01344     static int tagcount = 0 ;
01345     int     i;                  /* Loop index */
01346     int     j;                  /* Loop index */
01347 
01348     switch (task)
01349     {
01350       case TIS_STORE:
01351         if ( tagcount < (FIELD_LAST - 1) )
01352         {
01353             for ( j = 0 ; j < tagcount ; ++j )
01354             {                   /* Do not add duplicate tag */
01355                 if ( TIFFignoretags [j] == TIFFtagID )
01356                     return (TRUE) ;
01357             }
01358             TIFFignoretags [tagcount++] = TIFFtagID ;
01359             return (TRUE) ;
01360         }
01361         break ;
01362         
01363       case TIS_EXTRACT:
01364         for ( i = 0 ; i < tagcount ; ++i )
01365         {
01366             if ( TIFFignoretags [i] == TIFFtagID )
01367                 return (TRUE) ;
01368         }
01369         break;
01370         
01371       case TIS_EMPTY:
01372         tagcount = 0 ;          /* Clear the list */
01373         return (TRUE) ;
01374         
01375       default:
01376         break;
01377     }
01378     
01379     return (FALSE);
01380 }
01381 
01382 /* vim: set ts=8 sts=8 sw=8 noet: */
01383 /*
01384  * Local Variables:
01385  * mode: c
01386  * c-basic-offset: 8
01387  * fill-column: 78
01388  * End:
01389  */

Generated on Sun May 27 2012 04:19:33 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.