tif_dir.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:39k
源码类别:

打印编程

开发平台:

Visual C++

  1. /* $Id: tif_dir.c,v 1.72 2006/03/15 12:49:35 dron Exp $ */
  2. /*
  3.  * Copyright (c) 1988-1997 Sam Leffler
  4.  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. /*
  26.  * TIFF Library.
  27.  *
  28.  * Directory Tag Get & Set Routines.
  29.  * (and also some miscellaneous stuff)
  30.  */
  31. #include "tiffiop.h"
  32. /*
  33.  * These are used in the backwards compatibility code...
  34.  */
  35. #define DATATYPE_VOID 0       /* !untyped data */
  36. #define DATATYPE_INT 1       /* !signed integer data */
  37. #define DATATYPE_UINT 2       /* !unsigned integer data */
  38. #define DATATYPE_IEEEFP 3       /* !IEEE floating point data */
  39. static void
  40. setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
  41. {
  42. if (*vpp)
  43. _TIFFfree(*vpp), *vpp = 0;
  44. if (vp) {
  45. tsize_t bytes = nmemb * elem_size;
  46. if (elem_size && bytes / elem_size == nmemb)
  47. *vpp = (void*) _TIFFmalloc(bytes);
  48. if (*vpp)
  49. _TIFFmemcpy(*vpp, vp, bytes);
  50. }
  51. }
  52. void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
  53.     { setByteArray(vpp, vp, n, 1); }
  54. void _TIFFsetString(char** cpp, char* cp)
  55.     { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
  56. void _TIFFsetNString(char** cpp, char* cp, uint32 n)
  57.     { setByteArray((void**) cpp, (void*) cp, n, 1); }
  58. void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
  59.     { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
  60. void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
  61.     { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
  62. void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
  63.     { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
  64. void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
  65.     { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
  66. /*
  67.  * Install extra samples information.
  68.  */
  69. static int
  70. setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
  71. {
  72. uint16* va;
  73. uint32 i;
  74. *v = va_arg(ap, uint32);
  75. if ((uint16) *v > td->td_samplesperpixel)
  76. return (0);
  77. va = va_arg(ap, uint16*);
  78. if (*v > 0 && va == NULL) /* typically missing param */
  79. return (0);
  80. for (i = 0; i < *v; i++)
  81. if (va[i] > EXTRASAMPLE_UNASSALPHA)
  82. return (0);
  83. td->td_extrasamples = (uint16) *v;
  84. _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
  85. return (1);
  86. }
  87. static uint32
  88. checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
  89. {
  90. TIFFDirectory* td = &tif->tif_dir;
  91. uint16 i = td->td_samplesperpixel;
  92. if (slen > 0) {
  93. const char* ep = s+slen;
  94. const char* cp = s;
  95. for (; i > 0; i--) {
  96. for (; *cp != ''; cp++)
  97. if (cp >= ep)
  98. goto bad;
  99. cp++; /* skip  */
  100. }
  101. return (cp-s);
  102. }
  103. bad:
  104. TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
  105.     "%s: Invalid InkNames value; expecting %d names, found %d",
  106.     tif->tif_name,
  107.     td->td_samplesperpixel,
  108.     td->td_samplesperpixel-i);
  109. return (0);
  110. }
  111. static int
  112. _TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
  113. {
  114. static const char module[] = "_TIFFVSetField";
  115. TIFFDirectory* td = &tif->tif_dir;
  116. int status = 1;
  117. uint32 v32, i, v;
  118. char* s;
  119. switch (tag) {
  120. case TIFFTAG_SUBFILETYPE:
  121. td->td_subfiletype = va_arg(ap, uint32);
  122. break;
  123. case TIFFTAG_IMAGEWIDTH:
  124. td->td_imagewidth = va_arg(ap, uint32);
  125. break;
  126. case TIFFTAG_IMAGELENGTH:
  127. td->td_imagelength = va_arg(ap, uint32);
  128. break;
  129. case TIFFTAG_BITSPERSAMPLE:
  130. td->td_bitspersample = (uint16) va_arg(ap, int);
  131. /*
  132.  * If the data require post-decoding processing to byte-swap
  133.  * samples, set it up here.  Note that since tags are required
  134.  * to be ordered, compression code can override this behaviour
  135.  * in the setup method if it wants to roll the post decoding
  136.  * work in with its normal work.
  137.  */
  138. if (tif->tif_flags & TIFF_SWAB) {
  139. if (td->td_bitspersample == 16)
  140. tif->tif_postdecode = _TIFFSwab16BitData;
  141. else if (td->td_bitspersample == 24)
  142. tif->tif_postdecode = _TIFFSwab24BitData;
  143. else if (td->td_bitspersample == 32)
  144. tif->tif_postdecode = _TIFFSwab32BitData;
  145. else if (td->td_bitspersample == 64)
  146. tif->tif_postdecode = _TIFFSwab64BitData;
  147. else if (td->td_bitspersample == 128) /* two 64's */
  148. tif->tif_postdecode = _TIFFSwab64BitData;
  149. }
  150. break;
  151. case TIFFTAG_COMPRESSION:
  152. v = va_arg(ap, uint32) & 0xffff;
  153. /*
  154.  * If we're changing the compression scheme, the notify the
  155.  * previous module so that it can cleanup any state it's
  156.  * setup.
  157.  */
  158. if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
  159. if (td->td_compression == v)
  160. break;
  161. (*tif->tif_cleanup)(tif);
  162. tif->tif_flags &= ~TIFF_CODERSETUP;
  163. }
  164. /*
  165.  * Setup new compression routine state.
  166.  */
  167. if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
  168.                     td->td_compression = (uint16) v;
  169.                 else
  170.                     status = 0;
  171. break;
  172. case TIFFTAG_PHOTOMETRIC:
  173. td->td_photometric = (uint16) va_arg(ap, int);
  174. break;
  175. case TIFFTAG_THRESHHOLDING:
  176. td->td_threshholding = (uint16) va_arg(ap, int);
  177. break;
  178. case TIFFTAG_FILLORDER:
  179. v = va_arg(ap, uint32);
  180. if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
  181. goto badvalue;
  182. td->td_fillorder = (uint16) v;
  183. break;
  184. break;
  185. case TIFFTAG_ORIENTATION:
  186. v = va_arg(ap, uint32);
  187. if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) {
  188. TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
  189.     "Bad value %lu for "%s" tag ignored",
  190.     v, _TIFFFieldWithTag(tif, tag)->field_name);
  191. } else
  192. td->td_orientation = (uint16) v;
  193. break;
  194. case TIFFTAG_SAMPLESPERPIXEL:
  195. /* XXX should cross check -- e.g. if pallette, then 1 */
  196. v = va_arg(ap, uint32);
  197. if (v == 0)
  198. goto badvalue;
  199. td->td_samplesperpixel = (uint16) v;
  200. break;
  201. case TIFFTAG_ROWSPERSTRIP:
  202. v32 = va_arg(ap, uint32);
  203. if (v32 == 0)
  204. goto badvalue32;
  205. td->td_rowsperstrip = v32;
  206. if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
  207. td->td_tilelength = v32;
  208. td->td_tilewidth = td->td_imagewidth;
  209. }
  210. break;
  211. case TIFFTAG_MINSAMPLEVALUE:
  212. td->td_minsamplevalue = (uint16) va_arg(ap, int);
  213. break;
  214. case TIFFTAG_MAXSAMPLEVALUE:
  215. td->td_maxsamplevalue = (uint16) va_arg(ap, int);
  216. break;
  217. case TIFFTAG_SMINSAMPLEVALUE:
  218. td->td_sminsamplevalue = va_arg(ap, double);
  219. break;
  220. case TIFFTAG_SMAXSAMPLEVALUE:
  221. td->td_smaxsamplevalue = va_arg(ap, double);
  222. break;
  223. case TIFFTAG_XRESOLUTION:
  224. td->td_xresolution = (float) va_arg(ap, double);
  225. break;
  226. case TIFFTAG_YRESOLUTION:
  227. td->td_yresolution = (float) va_arg(ap, double);
  228. break;
  229. case TIFFTAG_PLANARCONFIG:
  230. v = va_arg(ap, uint32);
  231. if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
  232. goto badvalue;
  233. td->td_planarconfig = (uint16) v;
  234. break;
  235. case TIFFTAG_XPOSITION:
  236. td->td_xposition = (float) va_arg(ap, double);
  237. break;
  238. case TIFFTAG_YPOSITION:
  239. td->td_yposition = (float) va_arg(ap, double);
  240. break;
  241. case TIFFTAG_RESOLUTIONUNIT:
  242. v = va_arg(ap, uint32);
  243. if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
  244. goto badvalue;
  245. td->td_resolutionunit = (uint16) v;
  246. break;
  247. case TIFFTAG_PAGENUMBER:
  248. td->td_pagenumber[0] = (uint16) va_arg(ap, int);
  249. td->td_pagenumber[1] = (uint16) va_arg(ap, int);
  250. break;
  251. case TIFFTAG_HALFTONEHINTS:
  252. td->td_halftonehints[0] = (uint16) va_arg(ap, int);
  253. td->td_halftonehints[1] = (uint16) va_arg(ap, int);
  254. break;
  255. case TIFFTAG_COLORMAP:
  256. v32 = (uint32)(1L<<td->td_bitspersample);
  257. _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
  258. _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
  259. _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
  260. break;
  261. case TIFFTAG_EXTRASAMPLES:
  262. if (!setExtraSamples(td, ap, &v))
  263. goto badvalue;
  264. break;
  265. case TIFFTAG_MATTEING:
  266. td->td_extrasamples = (uint16) (va_arg(ap, int) != 0);
  267. if (td->td_extrasamples) {
  268. uint16 sv = EXTRASAMPLE_ASSOCALPHA;
  269. _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
  270. }
  271. break;
  272. case TIFFTAG_TILEWIDTH:
  273. v32 = va_arg(ap, uint32);
  274. if (v32 % 16) {
  275. if (tif->tif_mode != O_RDONLY)
  276. goto badvalue32;
  277. TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
  278. "Nonstandard tile width %d, convert file", v32);
  279. }
  280. td->td_tilewidth = v32;
  281. tif->tif_flags |= TIFF_ISTILED;
  282. break;
  283. case TIFFTAG_TILELENGTH:
  284. v32 = va_arg(ap, uint32);
  285. if (v32 % 16) {
  286. if (tif->tif_mode != O_RDONLY)
  287. goto badvalue32;
  288. TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
  289.     "Nonstandard tile length %d, convert file", v32);
  290. }
  291. td->td_tilelength = v32;
  292. tif->tif_flags |= TIFF_ISTILED;
  293. break;
  294. case TIFFTAG_TILEDEPTH:
  295. v32 = va_arg(ap, uint32);
  296. if (v32 == 0)
  297. goto badvalue32;
  298. td->td_tiledepth = v32;
  299. break;
  300. case TIFFTAG_DATATYPE:
  301. v = va_arg(ap, uint32);
  302. switch (v) {
  303. case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break;
  304. case DATATYPE_INT: v = SAMPLEFORMAT_INT; break;
  305. case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break;
  306. case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
  307. default: goto badvalue;
  308. }
  309. td->td_sampleformat = (uint16) v;
  310. break;
  311. case TIFFTAG_SAMPLEFORMAT:
  312. v = va_arg(ap, uint32);
  313. if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
  314. goto badvalue;
  315. td->td_sampleformat = (uint16) v;
  316.                 /*  Try to fix up the SWAB function for complex data. */
  317.                 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
  318.                     && td->td_bitspersample == 32
  319.                     && tif->tif_postdecode == _TIFFSwab32BitData )
  320.                     tif->tif_postdecode = _TIFFSwab16BitData;
  321.                 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 
  322.                           || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
  323.                          && td->td_bitspersample == 64
  324.                          && tif->tif_postdecode == _TIFFSwab64BitData )
  325.                     tif->tif_postdecode = _TIFFSwab32BitData;
  326. break;
  327. case TIFFTAG_IMAGEDEPTH:
  328. td->td_imagedepth = va_arg(ap, uint32);
  329. break;
  330. case TIFFTAG_SUBIFD:
  331. if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
  332. td->td_nsubifd = (uint16) va_arg(ap, int);
  333. _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*),
  334.     (long) td->td_nsubifd);
  335. } else {
  336. TIFFErrorExt(tif->tif_clientdata, module, "%s: Sorry, cannot nest SubIFDs",
  337.   tif->tif_name);
  338. status = 0;
  339. }
  340. break;
  341. case TIFFTAG_YCBCRPOSITIONING:
  342. td->td_ycbcrpositioning = (uint16) va_arg(ap, int);
  343. break;
  344. case TIFFTAG_YCBCRSUBSAMPLING:
  345. td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int);
  346. td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int);
  347. break;
  348. case TIFFTAG_TRANSFERFUNCTION:
  349. v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
  350. for (i = 0; i < v; i++)
  351. _TIFFsetShortArray(&td->td_transferfunction[i],
  352.     va_arg(ap, uint16*), 1L<<td->td_bitspersample);
  353. break;
  354. case TIFFTAG_INKNAMES:
  355. v = va_arg(ap, uint32);
  356. s = va_arg(ap, char*);
  357. v = checkInkNamesString(tif, v, s);
  358.                 status = v > 0;
  359. if( v > 0 ) {
  360. _TIFFsetNString(&td->td_inknames, s, v);
  361. td->td_inknameslen = v;
  362. }
  363. break;
  364.         default: {
  365.             const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
  366.             TIFFTagValue *tv;
  367.             int tv_size, iCustom;
  368.             /*
  369.      * This can happen if multiple images are open with different
  370.      * codecs which have private tags.  The global tag information
  371.      * table may then have tags that are valid for one file but not
  372.      * the other. If the client tries to set a tag that is not valid
  373.      * for the image's codec then we'll arrive here.  This
  374.      * happens, for example, when tiffcp is used to convert between
  375.      * compression schemes and codec-specific tags are blindly copied.
  376.              */
  377.             if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
  378. TIFFErrorExt(tif->tif_clientdata, module,
  379.     "%s: Invalid %stag "%s" (not supported by codec)",
  380.     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
  381.     _TIFFFieldWithTag(tif, tag)->field_name);
  382. status = 0;
  383. break;
  384.             }
  385.             /*
  386.              * Find the existing entry for this custom value.
  387.              */
  388.             tv = NULL;
  389.             for(iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
  390.                 if(td->td_customValues[iCustom].info == fip) {
  391.                     tv = td->td_customValues + iCustom;
  392.                     if(tv->value != NULL)
  393.                     {
  394.                         _TIFFfree(tv->value);
  395.                         tv->value = NULL;
  396.                     }
  397.                     break;
  398.                 }
  399.             }
  400.             /*
  401.              * Grow the custom list if the entry was not found.
  402.              */
  403.             if(tv == NULL) {
  404. TIFFTagValue *new_customValues;
  405. td->td_customValueCount++;
  406. new_customValues = (TIFFTagValue *)
  407. _TIFFrealloc(td->td_customValues,
  408.      sizeof(TIFFTagValue) * td->td_customValueCount);
  409. if (!new_customValues) {
  410. TIFFErrorExt(tif->tif_clientdata, module,
  411. "%s: Failed to allocate space for list of custom values",
  412.   tif->tif_name);
  413. status = 0;
  414. goto end;
  415. }
  416. td->td_customValues = new_customValues;
  417.                 tv = td->td_customValues + (td->td_customValueCount-1);
  418.                 tv->info = fip;
  419.                 tv->value = NULL;
  420.                 tv->count = 0;
  421.             }
  422.             /*
  423.              * Set custom value ... save a copy of the custom tag value.
  424.              */
  425.     tv_size = _TIFFDataSize(fip->field_type);
  426.     if (tv_size == 0) {
  427.     status = 0;
  428.     TIFFErrorExt(tif->tif_clientdata, module,
  429.  "%s: Bad field type %d for "%s"",
  430.  tif->tif_name, fip->field_type,
  431.  fip->field_name);
  432.     goto end;
  433.     }
  434.            
  435.             if(fip->field_passcount) {
  436.     if (fip->field_writecount == TIFF_VARIABLE2)
  437. tv->count = (uint32) va_arg(ap, uint32);
  438.     else
  439. tv->count = (int) va_arg(ap, int);
  440.     } else if (fip->field_writecount == TIFF_VARIABLE
  441.        || fip->field_writecount == TIFF_VARIABLE2)
  442. tv->count = 1;
  443.     else if (fip->field_writecount == TIFF_SPP)
  444. tv->count = td->td_samplesperpixel;
  445.     else
  446.                 tv->count = fip->field_writecount;
  447.             
  448.     
  449.     if (fip->field_type == TIFF_ASCII)
  450.     _TIFFsetString((char **)&tv->value, va_arg(ap, char *));
  451.     else {
  452.                 tv->value = _TIFFmalloc(tv_size * tv->count);
  453. if (!tv->value) {
  454.     status = 0;
  455.     goto end;
  456. }
  457. if ((fip->field_passcount
  458.     || fip->field_writecount == TIFF_VARIABLE
  459.     || fip->field_writecount == TIFF_VARIABLE2
  460.     || fip->field_writecount == TIFF_SPP
  461.     || tv->count > 1)
  462.     && fip->field_tag != TIFFTAG_PAGENUMBER
  463.     && fip->field_tag != TIFFTAG_HALFTONEHINTS
  464.     && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
  465.     && fip->field_tag != TIFFTAG_DOTRANGE) {
  466.                     _TIFFmemcpy(tv->value, va_arg(ap, void *),
  467. tv->count * tv_size);
  468. } else {
  469.     /*
  470.      * XXX: The following loop required to handle
  471.      * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS,
  472.      * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags.
  473.      * These tags are actually arrays and should be passed as
  474.      * array pointers to TIFFSetField() function, but actually
  475.      * passed as a list of separate values. This behaviour
  476.      * must be changed in the future!
  477.      */
  478.     int i;
  479.     char *val = (char *)tv->value;
  480.     for (i = 0; i < tv->count; i++, val += tv_size) {
  481.     switch (fip->field_type) {
  482. case TIFF_BYTE:
  483. case TIFF_UNDEFINED:
  484.     {
  485. uint8 v = (uint8)va_arg(ap, int);
  486. _TIFFmemcpy(val, &v, tv_size);
  487.     }
  488.     break;
  489. case TIFF_SBYTE:
  490.     {
  491. int8 v = (int8)va_arg(ap, int);
  492. _TIFFmemcpy(val, &v, tv_size);
  493.     }
  494.     break;
  495. case TIFF_SHORT:
  496.     {
  497. uint16 v = (uint16)va_arg(ap, int);
  498. _TIFFmemcpy(val, &v, tv_size);
  499.     }
  500.     break;
  501. case TIFF_SSHORT:
  502.     {
  503. int16 v = (int16)va_arg(ap, int);
  504. _TIFFmemcpy(val, &v, tv_size);
  505.     }
  506.     break;
  507. case TIFF_LONG:
  508. case TIFF_IFD:
  509.     {
  510. uint32 v = va_arg(ap, uint32);
  511. _TIFFmemcpy(val, &v, tv_size);
  512.     }
  513.     break;
  514. case TIFF_SLONG:
  515.     {
  516. int32 v = va_arg(ap, int32);
  517. _TIFFmemcpy(val, &v, tv_size);
  518.     }
  519.     break;
  520. case TIFF_RATIONAL:
  521. case TIFF_SRATIONAL:
  522. case TIFF_FLOAT:
  523.     {
  524. float v = (float)va_arg(ap, double);
  525. _TIFFmemcpy(val, &v, tv_size);
  526.     }
  527.     break;
  528. case TIFF_DOUBLE:
  529.     {
  530. double v = va_arg(ap, double);
  531. _TIFFmemcpy(val, &v, tv_size);
  532.     }
  533.     break;
  534. default:
  535.     _TIFFmemset(val, 0, tv_size);
  536.     status = 0;
  537.     break;
  538.     }
  539.     }
  540. }
  541.     }
  542.           }
  543. }
  544. if (status) {
  545. TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
  546. tif->tif_flags |= TIFF_DIRTYDIRECT;
  547. }
  548. end:
  549. va_end(ap);
  550. return (status);
  551. badvalue:
  552. TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %d for "%s"",
  553.   tif->tif_name, v, _TIFFFieldWithTag(tif, tag)->field_name);
  554. va_end(ap);
  555. return (0);
  556. badvalue32:
  557. TIFFErrorExt(tif->tif_clientdata, module, "%s: Bad value %ld for "%s"",
  558.    tif->tif_name, v32, _TIFFFieldWithTag(tif, tag)->field_name);
  559. va_end(ap);
  560. return (0);
  561. }
  562. /*
  563.  * Return 1/0 according to whether or not
  564.  * it is permissible to set the tag's value.
  565.  * Note that we allow ImageLength to be changed
  566.  * so that we can append and extend to images.
  567.  * Any other tag may not be altered once writing
  568.  * has commenced, unless its value has no effect
  569.  * on the format of the data that is written.
  570.  */
  571. static int
  572. OkToChangeTag(TIFF* tif, ttag_t tag)
  573. {
  574. const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
  575. if (!fip) { /* unknown tag */
  576. TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
  577.     tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
  578. return (0);
  579. }
  580. if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
  581.     !fip->field_oktochange) {
  582. /*
  583.  * Consult info table to see if tag can be changed
  584.  * after we've started writing.  We only allow changes
  585.  * to those tags that don't/shouldn't affect the
  586.  * compression and/or format of the data.
  587.  */
  588. TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
  589.     "%s: Cannot modify tag "%s" while writing",
  590.     tif->tif_name, fip->field_name);
  591. return (0);
  592. }
  593. return (1);
  594. }
  595. /*
  596.  * Record the value of a field in the
  597.  * internal directory structure.  The
  598.  * field will be written to the file
  599.  * when/if the directory structure is
  600.  * updated.
  601.  */
  602. int
  603. TIFFSetField(TIFF* tif, ttag_t tag, ...)
  604. {
  605. va_list ap;
  606. int status;
  607. va_start(ap, tag);
  608. status = TIFFVSetField(tif, tag, ap);
  609. va_end(ap);
  610. return (status);
  611. }
  612. /*
  613.  * Like TIFFSetField, but taking a varargs
  614.  * parameter list.  This routine is useful
  615.  * for building higher-level interfaces on
  616.  * top of the library.
  617.  */
  618. int
  619. TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap)
  620. {
  621. return OkToChangeTag(tif, tag) ?
  622.     (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
  623. }
  624. static int
  625. _TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
  626. {
  627.     TIFFDirectory* td = &tif->tif_dir;
  628.     int            ret_val = 1;
  629.     switch (tag) {
  630. case TIFFTAG_SUBFILETYPE:
  631.             *va_arg(ap, uint32*) = td->td_subfiletype;
  632.             break;
  633. case TIFFTAG_IMAGEWIDTH:
  634.             *va_arg(ap, uint32*) = td->td_imagewidth;
  635.             break;
  636. case TIFFTAG_IMAGELENGTH:
  637.             *va_arg(ap, uint32*) = td->td_imagelength;
  638.             break;
  639. case TIFFTAG_BITSPERSAMPLE:
  640.             *va_arg(ap, uint16*) = td->td_bitspersample;
  641.             break;
  642. case TIFFTAG_COMPRESSION:
  643.             *va_arg(ap, uint16*) = td->td_compression;
  644.             break;
  645. case TIFFTAG_PHOTOMETRIC:
  646.             *va_arg(ap, uint16*) = td->td_photometric;
  647.             break;
  648. case TIFFTAG_THRESHHOLDING:
  649.             *va_arg(ap, uint16*) = td->td_threshholding;
  650.             break;
  651. case TIFFTAG_FILLORDER:
  652.             *va_arg(ap, uint16*) = td->td_fillorder;
  653.             break;
  654. case TIFFTAG_ORIENTATION:
  655.             *va_arg(ap, uint16*) = td->td_orientation;
  656.             break;
  657. case TIFFTAG_SAMPLESPERPIXEL:
  658.             *va_arg(ap, uint16*) = td->td_samplesperpixel;
  659.             break;
  660. case TIFFTAG_ROWSPERSTRIP:
  661.             *va_arg(ap, uint32*) = td->td_rowsperstrip;
  662.             break;
  663. case TIFFTAG_MINSAMPLEVALUE:
  664.             *va_arg(ap, uint16*) = td->td_minsamplevalue;
  665.             break;
  666. case TIFFTAG_MAXSAMPLEVALUE:
  667.             *va_arg(ap, uint16*) = td->td_maxsamplevalue;
  668.             break;
  669. case TIFFTAG_SMINSAMPLEVALUE:
  670.             *va_arg(ap, double*) = td->td_sminsamplevalue;
  671.             break;
  672. case TIFFTAG_SMAXSAMPLEVALUE:
  673.             *va_arg(ap, double*) = td->td_smaxsamplevalue;
  674.             break;
  675. case TIFFTAG_XRESOLUTION:
  676.             *va_arg(ap, float*) = td->td_xresolution;
  677.             break;
  678. case TIFFTAG_YRESOLUTION:
  679.             *va_arg(ap, float*) = td->td_yresolution;
  680.             break;
  681. case TIFFTAG_PLANARCONFIG:
  682.             *va_arg(ap, uint16*) = td->td_planarconfig;
  683.             break;
  684. case TIFFTAG_XPOSITION:
  685.             *va_arg(ap, float*) = td->td_xposition;
  686.             break;
  687. case TIFFTAG_YPOSITION:
  688.             *va_arg(ap, float*) = td->td_yposition;
  689.             break;
  690. case TIFFTAG_RESOLUTIONUNIT:
  691.             *va_arg(ap, uint16*) = td->td_resolutionunit;
  692.             break;
  693. case TIFFTAG_PAGENUMBER:
  694.             *va_arg(ap, uint16*) = td->td_pagenumber[0];
  695.             *va_arg(ap, uint16*) = td->td_pagenumber[1];
  696.             break;
  697. case TIFFTAG_HALFTONEHINTS:
  698.             *va_arg(ap, uint16*) = td->td_halftonehints[0];
  699.             *va_arg(ap, uint16*) = td->td_halftonehints[1];
  700.             break;
  701. case TIFFTAG_COLORMAP:
  702.             *va_arg(ap, uint16**) = td->td_colormap[0];
  703.             *va_arg(ap, uint16**) = td->td_colormap[1];
  704.             *va_arg(ap, uint16**) = td->td_colormap[2];
  705.             break;
  706. case TIFFTAG_STRIPOFFSETS:
  707. case TIFFTAG_TILEOFFSETS:
  708.             *va_arg(ap, uint32**) = td->td_stripoffset;
  709.             break;
  710. case TIFFTAG_STRIPBYTECOUNTS:
  711. case TIFFTAG_TILEBYTECOUNTS:
  712.             *va_arg(ap, uint32**) = td->td_stripbytecount;
  713.             break;
  714. case TIFFTAG_MATTEING:
  715.             *va_arg(ap, uint16*) =
  716.                 (td->td_extrasamples == 1 &&
  717.                  td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
  718.             break;
  719. case TIFFTAG_EXTRASAMPLES:
  720.             *va_arg(ap, uint16*) = td->td_extrasamples;
  721.             *va_arg(ap, uint16**) = td->td_sampleinfo;
  722.             break;
  723. case TIFFTAG_TILEWIDTH:
  724.             *va_arg(ap, uint32*) = td->td_tilewidth;
  725.             break;
  726. case TIFFTAG_TILELENGTH:
  727.             *va_arg(ap, uint32*) = td->td_tilelength;
  728.             break;
  729. case TIFFTAG_TILEDEPTH:
  730.             *va_arg(ap, uint32*) = td->td_tiledepth;
  731.             break;
  732. case TIFFTAG_DATATYPE:
  733.             switch (td->td_sampleformat) {
  734. case SAMPLEFORMAT_UINT:
  735.                     *va_arg(ap, uint16*) = DATATYPE_UINT;
  736.                     break;
  737. case SAMPLEFORMAT_INT:
  738.                     *va_arg(ap, uint16*) = DATATYPE_INT;
  739.                     break;
  740. case SAMPLEFORMAT_IEEEFP:
  741.                     *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
  742.                     break;
  743. case SAMPLEFORMAT_VOID:
  744.                     *va_arg(ap, uint16*) = DATATYPE_VOID;
  745.                     break;
  746.             }
  747.             break;
  748. case TIFFTAG_SAMPLEFORMAT:
  749.             *va_arg(ap, uint16*) = td->td_sampleformat;
  750.             break;
  751. case TIFFTAG_IMAGEDEPTH:
  752.             *va_arg(ap, uint32*) = td->td_imagedepth;
  753.             break;
  754. case TIFFTAG_SUBIFD:
  755.             *va_arg(ap, uint16*) = td->td_nsubifd;
  756.             *va_arg(ap, uint32**) = td->td_subifd;
  757.             break;
  758. case TIFFTAG_YCBCRPOSITIONING:
  759.             *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
  760.             break;
  761. case TIFFTAG_YCBCRSUBSAMPLING:
  762.             *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
  763.             *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
  764.             break;
  765. case TIFFTAG_TRANSFERFUNCTION:
  766.             *va_arg(ap, uint16**) = td->td_transferfunction[0];
  767.             if (td->td_samplesperpixel - td->td_extrasamples > 1) {
  768.                 *va_arg(ap, uint16**) = td->td_transferfunction[1];
  769.                 *va_arg(ap, uint16**) = td->td_transferfunction[2];
  770.             }
  771.             break;
  772. case TIFFTAG_INKNAMES:
  773.             *va_arg(ap, char**) = td->td_inknames;
  774.             break;
  775.         default:
  776.         {
  777.             const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
  778.             int           i;
  779.             
  780.             /*
  781.              * This can happen if multiple images are open with
  782.              * different codecs which have private tags.  The
  783.              * global tag information table may then have tags
  784.              * that are valid for one file but not the other. 
  785.              * If the client tries to get a tag that is not valid
  786.              * for the image's codec then we'll arrive here.
  787.              */
  788.             if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
  789.             {
  790. TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
  791.                           "%s: Invalid %stag "%s" (not supported by codec)",
  792.                           tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
  793.                           _TIFFFieldWithTag(tif, tag)->field_name);
  794.                 ret_val = 0;
  795.                 break;
  796.             }
  797.             /*
  798.      * Do we have a custom value?
  799.      */
  800.             ret_val = 0;
  801.             for (i = 0; i < td->td_customValueCount; i++) {
  802. TIFFTagValue *tv = td->td_customValues + i;
  803. if (tv->info->field_tag != tag)
  804. continue;
  805.                 
  806. if (fip->field_passcount) {
  807. if (fip->field_readcount == TIFF_VARIABLE2) 
  808. *va_arg(ap, uint32*) = (uint32)tv->count;
  809. else /* Assume TIFF_VARIABLE */
  810. *va_arg(ap, uint16*) = (uint16)tv->count;
  811. *va_arg(ap, void **) = tv->value;
  812. ret_val = 1;
  813.                 } else {
  814. if ((fip->field_type == TIFF_ASCII
  815.     || fip->field_readcount == TIFF_VARIABLE
  816.     || fip->field_readcount == TIFF_VARIABLE2
  817.     || fip->field_readcount == TIFF_SPP
  818.     || tv->count > 1)
  819.     && fip->field_tag != TIFFTAG_PAGENUMBER
  820.     && fip->field_tag != TIFFTAG_HALFTONEHINTS
  821.     && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
  822.     && fip->field_tag != TIFFTAG_DOTRANGE) {
  823. *va_arg(ap, void **) = tv->value;
  824. ret_val = 1;
  825. } else {
  826.     int j;
  827.     char *val = (char *)tv->value;
  828.     for (j = 0; j < tv->count;
  829.  j++, val += _TIFFDataSize(tv->info->field_type)) {
  830. switch (fip->field_type) {
  831. case TIFF_BYTE:
  832. case TIFF_UNDEFINED:
  833. *va_arg(ap, uint8*) =
  834. *(uint8 *)val;
  835. ret_val = 1;
  836. break;
  837. case TIFF_SBYTE:
  838. *va_arg(ap, int8*) =
  839. *(int8 *)val;
  840. ret_val = 1;
  841. break;
  842. case TIFF_SHORT:
  843. *va_arg(ap, uint16*) =
  844. *(uint16 *)val;
  845. ret_val = 1;
  846. break;
  847. case TIFF_SSHORT:
  848. *va_arg(ap, int16*) =
  849. *(int16 *)val;
  850. ret_val = 1;
  851. break;
  852. case TIFF_LONG:
  853. case TIFF_IFD:
  854. *va_arg(ap, uint32*) =
  855. *(uint32 *)val;
  856. ret_val = 1;
  857. break;
  858. case TIFF_SLONG:
  859. *va_arg(ap, int32*) =
  860. *(int32 *)val;
  861. ret_val = 1;
  862. break;
  863. case TIFF_RATIONAL:
  864. case TIFF_SRATIONAL:
  865. case TIFF_FLOAT:
  866. *va_arg(ap, float*) =
  867. *(float *)val;
  868. ret_val = 1;
  869. break;
  870. case TIFF_DOUBLE:
  871. *va_arg(ap, double*) =
  872. *(double *)val;
  873. ret_val = 1;
  874. break;
  875. default:
  876. ret_val = 0;
  877. break;
  878. }
  879.     }
  880. }
  881.                 }
  882. break;
  883.             }
  884.         }
  885.     }
  886.     return(ret_val);
  887. }
  888. /*
  889.  * Return the value of a field in the
  890.  * internal directory structure.
  891.  */
  892. int
  893. TIFFGetField(TIFF* tif, ttag_t tag, ...)
  894. {
  895. int status;
  896. va_list ap;
  897. va_start(ap, tag);
  898. status = TIFFVGetField(tif, tag, ap);
  899. va_end(ap);
  900. return (status);
  901. }
  902. /*
  903.  * Like TIFFGetField, but taking a varargs
  904.  * parameter list.  This routine is useful
  905.  * for building higher-level interfaces on
  906.  * top of the library.
  907.  */
  908. int
  909. TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap)
  910. {
  911. const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY);
  912. return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
  913.     (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
  914. }
  915. #define CleanupField(member) {
  916.     if (td->member) {
  917. _TIFFfree(td->member);
  918. td->member = 0;
  919.     }
  920. }
  921. /*
  922.  * Release storage associated with a directory.
  923.  */
  924. void
  925. TIFFFreeDirectory(TIFF* tif)
  926. {
  927. TIFFDirectory *td = &tif->tif_dir;
  928. int            i;
  929. _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
  930. CleanupField(td_colormap[0]);
  931. CleanupField(td_colormap[1]);
  932. CleanupField(td_colormap[2]);
  933. CleanupField(td_sampleinfo);
  934. CleanupField(td_subifd);
  935. CleanupField(td_inknames);
  936. CleanupField(td_transferfunction[0]);
  937. CleanupField(td_transferfunction[1]);
  938. CleanupField(td_transferfunction[2]);
  939. CleanupField(td_stripoffset);
  940. CleanupField(td_stripbytecount);
  941. TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
  942. TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
  943. /* Cleanup custom tag values */
  944. for( i = 0; i < td->td_customValueCount; i++ ) {
  945. if (td->td_customValues[i].value)
  946. _TIFFfree(td->td_customValues[i].value);
  947. }
  948. td->td_customValueCount = 0;
  949. CleanupField(td_customValues);
  950. }
  951. #undef CleanupField
  952. /*
  953.  * Client Tag extension support (from Niles Ritter).
  954.  */
  955. static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
  956. TIFFExtendProc
  957. TIFFSetTagExtender(TIFFExtendProc extender)
  958. {
  959. TIFFExtendProc prev = _TIFFextender;
  960. _TIFFextender = extender;
  961. return (prev);
  962. }
  963. /*
  964.  * Setup for a new directory.  Should we automatically call
  965.  * TIFFWriteDirectory() if the current one is dirty?
  966.  *
  967.  * The newly created directory will not exist on the file till
  968.  * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
  969.  */
  970. int
  971. TIFFCreateDirectory(TIFF* tif)
  972. {
  973.     TIFFDefaultDirectory(tif);
  974.     tif->tif_diroff = 0;
  975.     tif->tif_nextdiroff = 0;
  976.     tif->tif_curoff = 0;
  977.     tif->tif_row = (uint32) -1;
  978.     tif->tif_curstrip = (tstrip_t) -1;
  979.     return 0;
  980. }
  981. /*
  982.  * Setup a default directory structure.
  983.  */
  984. int
  985. TIFFDefaultDirectory(TIFF* tif)
  986. {
  987. register TIFFDirectory* td = &tif->tif_dir;
  988. size_t tiffFieldInfoCount;
  989. const TIFFFieldInfo *tiffFieldInfo =
  990. _TIFFGetFieldInfo(&tiffFieldInfoCount);
  991. _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount);
  992. _TIFFmemset(td, 0, sizeof (*td));
  993. td->td_fillorder = FILLORDER_MSB2LSB;
  994. td->td_bitspersample = 1;
  995. td->td_threshholding = THRESHHOLD_BILEVEL;
  996. td->td_orientation = ORIENTATION_TOPLEFT;
  997. td->td_samplesperpixel = 1;
  998. td->td_rowsperstrip = (uint32) -1;
  999. td->td_tilewidth = 0;
  1000. td->td_tilelength = 0;
  1001. td->td_tiledepth = 1;
  1002. td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
  1003. td->td_resolutionunit = RESUNIT_INCH;
  1004. td->td_sampleformat = SAMPLEFORMAT_UINT;
  1005. td->td_imagedepth = 1;
  1006. td->td_ycbcrsubsampling[0] = 2;
  1007. td->td_ycbcrsubsampling[1] = 2;
  1008. td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
  1009. tif->tif_postdecode = _TIFFNoPostDecode;
  1010.         tif->tif_foundfield = NULL;
  1011. tif->tif_tagmethods.vsetfield = _TIFFVSetField;
  1012. tif->tif_tagmethods.vgetfield = _TIFFVGetField;
  1013. tif->tif_tagmethods.printdir = NULL;
  1014. /*
  1015.  *  Give client code a chance to install their own
  1016.  *  tag extensions & methods, prior to compression overloads.
  1017.  */
  1018. if (_TIFFextender)
  1019. (*_TIFFextender)(tif);
  1020. (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
  1021. /*
  1022.  * NB: The directory is marked dirty as a result of setting
  1023.  * up the default compression scheme.  However, this really
  1024.  * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
  1025.  * if the user does something.  We could just do the setup
  1026.  * by hand, but it seems better to use the normal mechanism
  1027.  * (i.e. TIFFSetField).
  1028.  */
  1029. tif->tif_flags &= ~TIFF_DIRTYDIRECT;
  1030.         /*
  1031.          * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
  1032.          * we clear the ISTILED flag when setting up a new directory.
  1033.          * Should we also be clearing stuff like INSUBIFD?
  1034.          */
  1035.         tif->tif_flags &= ~TIFF_ISTILED;
  1036. return (1);
  1037. }
  1038. static int
  1039. TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
  1040. {
  1041.     static const char module[] = "TIFFAdvanceDirectory";
  1042.     uint16 dircount;
  1043.     if (isMapped(tif))
  1044.     {
  1045.         toff_t poff=*nextdir;
  1046.         if (poff+sizeof(uint16) > tif->tif_size)
  1047.         {
  1048. TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
  1049.                       tif->tif_name);
  1050.             return (0);
  1051.         }
  1052.         _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
  1053.         if (tif->tif_flags & TIFF_SWAB)
  1054.             TIFFSwabShort(&dircount);
  1055.         poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
  1056.         if (off != NULL)
  1057.             *off = poff;
  1058.         if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
  1059.         {
  1060. TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
  1061.                       tif->tif_name);
  1062.             return (0);
  1063.         }
  1064.         _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
  1065.         if (tif->tif_flags & TIFF_SWAB)
  1066.             TIFFSwabLong(nextdir);
  1067.         return (1);
  1068.     }
  1069.     else
  1070.     {
  1071.         if (!SeekOK(tif, *nextdir) ||
  1072.             !ReadOK(tif, &dircount, sizeof (uint16))) {
  1073. TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
  1074.                       tif->tif_name);
  1075.             return (0);
  1076.         }
  1077.         if (tif->tif_flags & TIFF_SWAB)
  1078.             TIFFSwabShort(&dircount);
  1079.         if (off != NULL)
  1080.             *off = TIFFSeekFile(tif,
  1081.                                 dircount*sizeof (TIFFDirEntry), SEEK_CUR);
  1082.         else
  1083.             (void) TIFFSeekFile(tif,
  1084.                                 dircount*sizeof (TIFFDirEntry), SEEK_CUR);
  1085.         if (!ReadOK(tif, nextdir, sizeof (uint32))) {
  1086. TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
  1087.                       tif->tif_name);
  1088.             return (0);
  1089.         }
  1090.         if (tif->tif_flags & TIFF_SWAB)
  1091.             TIFFSwabLong(nextdir);
  1092.         return (1);
  1093.     }
  1094. }
  1095. /*
  1096.  * Count the number of directories in a file.
  1097.  */
  1098. tdir_t
  1099. TIFFNumberOfDirectories(TIFF* tif)
  1100. {
  1101.     toff_t nextdir = tif->tif_header.tiff_diroff;
  1102.     tdir_t n = 0;
  1103.     
  1104.     while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
  1105.         n++;
  1106.     return (n);
  1107. }
  1108. /*
  1109.  * Set the n-th directory as the current directory.
  1110.  * NB: Directories are numbered starting at 0.
  1111.  */
  1112. int
  1113. TIFFSetDirectory(TIFF* tif, tdir_t dirn)
  1114. {
  1115. toff_t nextdir;
  1116. tdir_t n;
  1117. nextdir = tif->tif_header.tiff_diroff;
  1118. for (n = dirn; n > 0 && nextdir != 0; n--)
  1119. if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
  1120. return (0);
  1121. tif->tif_nextdiroff = nextdir;
  1122. /*
  1123.  * Set curdir to the actual directory index.  The
  1124.  * -1 is because TIFFReadDirectory will increment
  1125.  * tif_curdir after successfully reading the directory.
  1126.  */
  1127. tif->tif_curdir = (dirn - n) - 1;
  1128. /*
  1129.  * Reset tif_dirnumber counter and start new list of seen directories.
  1130.  * We need this to prevent IFD loops.
  1131.  */
  1132. tif->tif_dirnumber = 0;
  1133. return (TIFFReadDirectory(tif));
  1134. }
  1135. /*
  1136.  * Set the current directory to be the directory
  1137.  * located at the specified file offset.  This interface
  1138.  * is used mainly to access directories linked with
  1139.  * the SubIFD tag (e.g. thumbnail images).
  1140.  */
  1141. int
  1142. TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
  1143. {
  1144. tif->tif_nextdiroff = diroff;
  1145. /*
  1146.  * Reset tif_dirnumber counter and start new list of seen directories.
  1147.  * We need this to prevent IFD loops.
  1148.  */
  1149. tif->tif_dirnumber = 0;
  1150. return (TIFFReadDirectory(tif));
  1151. }
  1152. /*
  1153.  * Return file offset of the current directory.
  1154.  */
  1155. uint32
  1156. TIFFCurrentDirOffset(TIFF* tif)
  1157. {
  1158. return (tif->tif_diroff);
  1159. }
  1160. /*
  1161.  * Return an indication of whether or not we are
  1162.  * at the last directory in the file.
  1163.  */
  1164. int
  1165. TIFFLastDirectory(TIFF* tif)
  1166. {
  1167. return (tif->tif_nextdiroff == 0);
  1168. }
  1169. /*
  1170.  * Unlink the specified directory from the directory chain.
  1171.  */
  1172. int
  1173. TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
  1174. {
  1175. static const char module[] = "TIFFUnlinkDirectory";
  1176. toff_t nextdir;
  1177. toff_t off;
  1178. tdir_t n;
  1179. if (tif->tif_mode == O_RDONLY) {
  1180. TIFFErrorExt(tif->tif_clientdata, module,
  1181.                              "Can not unlink directory in read-only file");
  1182. return (0);
  1183. }
  1184. /*
  1185.  * Go to the directory before the one we want
  1186.  * to unlink and nab the offset of the link
  1187.  * field we'll need to patch.
  1188.  */
  1189. nextdir = tif->tif_header.tiff_diroff;
  1190. off = sizeof (uint16) + sizeof (uint16);
  1191. for (n = dirn-1; n > 0; n--) {
  1192. if (nextdir == 0) {
  1193. TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
  1194. return (0);
  1195. }
  1196. if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
  1197. return (0);
  1198. }
  1199. /*
  1200.  * Advance to the directory to be unlinked and fetch
  1201.  * the offset of the directory that follows.
  1202.  */
  1203. if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
  1204. return (0);
  1205. /*
  1206.  * Go back and patch the link field of the preceding
  1207.  * directory to point to the offset of the directory
  1208.  * that follows.
  1209.  */
  1210. (void) TIFFSeekFile(tif, off, SEEK_SET);
  1211. if (tif->tif_flags & TIFF_SWAB)
  1212. TIFFSwabLong(&nextdir);
  1213. if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
  1214. TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
  1215. return (0);
  1216. }
  1217. /*
  1218.  * Leave directory state setup safely.  We don't have
  1219.  * facilities for doing inserting and removing directories,
  1220.  * so it's safest to just invalidate everything.  This
  1221.  * means that the caller can only append to the directory
  1222.  * chain.
  1223.  */
  1224. (*tif->tif_cleanup)(tif);
  1225. if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
  1226. _TIFFfree(tif->tif_rawdata);
  1227. tif->tif_rawdata = NULL;
  1228. tif->tif_rawcc = 0;
  1229. }
  1230. tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
  1231. TIFFFreeDirectory(tif);
  1232. TIFFDefaultDirectory(tif);
  1233. tif->tif_diroff = 0; /* force link on next write */
  1234. tif->tif_nextdiroff = 0; /* next write must be at end */
  1235. tif->tif_curoff = 0;
  1236. tif->tif_row = (uint32) -1;
  1237. tif->tif_curstrip = (tstrip_t) -1;
  1238. return (1);
  1239. }
  1240. /* [BFC]
  1241.  *
  1242.  * Author: Bruce Cameron <cameron@petris.com>
  1243.  *
  1244.  * Set a table of tags that are to be replaced during directory process by the
  1245.  * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
  1246.  * 'ReadDirectory' can use the stored information.
  1247.  *
  1248.  * FIXME: this is never used properly. Should be removed in the future.
  1249.  */
  1250. int
  1251. TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
  1252. {
  1253.     static int TIFFignoretags [FIELD_LAST];
  1254.     static int tagcount = 0 ;
  1255.     int i; /* Loop index */
  1256.     int j; /* Loop index */
  1257.     switch (task)
  1258.     {
  1259.       case TIS_STORE:
  1260.         if ( tagcount < (FIELD_LAST - 1) )
  1261.         {
  1262.             for ( j = 0 ; j < tagcount ; ++j )
  1263.             { /* Do not add duplicate tag */
  1264.                 if ( TIFFignoretags [j] == TIFFtagID )
  1265.                     return (TRUE) ;
  1266.             }
  1267.             TIFFignoretags [tagcount++] = TIFFtagID ;
  1268.             return (TRUE) ;
  1269.         }
  1270.         break ;
  1271.         
  1272.       case TIS_EXTRACT:
  1273.         for ( i = 0 ; i < tagcount ; ++i )
  1274.         {
  1275.             if ( TIFFignoretags [i] == TIFFtagID )
  1276.                 return (TRUE) ;
  1277.         }
  1278.         break;
  1279.         
  1280.       case TIS_EMPTY:
  1281.         tagcount = 0 ; /* Clear the list */
  1282.         return (TRUE) ;
  1283.         
  1284.       default:
  1285.         break;
  1286.     }
  1287.     
  1288.     return (FALSE);
  1289. }
  1290. /* vim: set ts=8 sts=8 sw=8 noet: */