Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentif_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
1.7.6.1
|