1 /* $Header: /cvsroot/osrs/libtiff/contrib/pds/tif_pdsdirwrite.c,v 1.2 2003/11/17 15:09:39 dron Exp $ */
2 
3 /* When writing data to TIFF files, it is often useful to store application-
4    specific data in a private TIFF directory so that the tags don't need to
5    be registered and won't conflict with other people's user-defined tags.
6    One needs to have a registered public tag which contains some amount of
7    raw data. That raw data, however, is interpreted at an independent,
8    separate, private tiff directory. This file provides some routines which
9    will be useful for converting that data from its raw binary form into
10    the proper form for your application.
11 */
12 
13 /*
14  * Copyright (c) 1988-1996 Sam Leffler
15  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
16  * Copyright (c( 1996 USAF Phillips Laboratory
17  *
18  * Permission to use, copy, modify, distribute, and sell this software and
19  * its documentation for any purpose is hereby granted without fee, provided
20  * that (i) the above copyright notices and this permission notice appear in
21  * all copies of the software and related documentation, and (ii) the names of
22  * Sam Leffler and Silicon Graphics may not be used in any advertising or
23  * publicity relating to the software without the specific, prior written
24  * permission of Sam Leffler and Silicon Graphics.
25  *
26  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
28  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
31  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
32  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
33  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
34  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
35  * OF THIS SOFTWARE.
36  */
37 
38 /*
39  * TIFF Library.
40  *
41  * These routines written by Conrad J. Poelman on a single late-night of
42  * March 20-21, 1996.
43  *
44  * The entire purpose of this file is to provide a single external function,
45  * TIFFWritePrivateDataSubDirectory(). This function is intended for use
46  * in writing a private subdirectory structure into a TIFF file. The
47  * actual reading of data from the structure is handled by the getFieldFn(),
48  * which is passed to TIFFWritePrivateDataSubDirectory() as a parameter. The
49  * idea is to enable any application wishing to read private subdirectories to
50  * do so easily using this function, without modifying the TIFF library.
51  *
52  * The astute observer will notice that only two functions are at all different
53  * from the original tif_dirwrite.c file: TIFFWritePrivateDataSubDirectory()and
54  * TIFFWriteNormalSubTag(). All the other stuff that makes this file so huge
55  * is only necessary because all of those functions are declared static in
56  * tif_dirwrite.c, so we have to totally duplicate them in order to use them.
57  *
58  * Oh, also please note the bug-fix in the routine TIFFWriteNormalSubTag(),
59  * which equally should be applied to TIFFWriteNormalTag().
60  *
61  */
62 #include "tiffiop.h"
63 
64 #if HAVE_IEEEFP
65 #define	TIFFCvtNativeToIEEEFloat(tif, n, fp)
66 #define	TIFFCvtNativeToIEEEDouble(tif, n, dp)
67 #else
68 extern	void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
69 extern	void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
70 #endif
71 
72 static	int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
73 static	int TIFFWriteNormalSubTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*,
74 				  int (*getFieldFn)(TIFF *tif,ttag_t tag,...));
75 static	void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
76 static	int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
77 static	int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
78 static	int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
79 static	int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
80 static	int TIFFWriteShortArray(TIFF*,
81 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*);
82 static	int TIFFWriteLongArray(TIFF *,
83 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*);
84 static	int TIFFWriteRationalArray(TIFF *,
85 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
86 static	int TIFFWriteFloatArray(TIFF *,
87 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
88 static	int TIFFWriteDoubleArray(TIFF *,
89 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
90 static	int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
91 static	int TIFFWriteAnyArray(TIFF*,
92 	    TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
93 #ifdef COLORIMETRY_SUPPORT
94 static	int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
95 #endif
96 static	int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
97 static	int TIFFLinkDirectory(TIFF*);
98 
99 #define	WriteRationalPair(type, tag1, v1, tag2, v2) {		\
100 	if (!TIFFWriteRational(tif, type, tag1, dir, v1))	\
101 		goto bad;					\
102 	if (!TIFFWriteRational(tif, type, tag2, dir+1, v2))	\
103 		goto bad;					\
104 	dir++;							\
105 }
106 #define	TIFFWriteRational(tif, type, tag, dir, v) \
107 	TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v))
108 #ifndef TIFFWriteRational
109 static	int TIFFWriteRational(TIFF*,
110 	    TIFFDataType, ttag_t, TIFFDirEntry*, float);
111 #endif
112 
113 /* This function will write an entire directory to the disk, and return the
114    offset value indicating where in the file it wrote the beginning of the
115    directory structure. This is NOT the same as the offset value before
116    calling this function, because some of the fields may have caused various
117    data items to be written out BEFORE writing the directory structure.
118 
119    This code was basically written by ripping of the TIFFWriteDirectory()
120    code and generalizing it, using RPS's TIFFWritePliIfd() code for
121    inspiration.  My original goal was to make this code general enough that
122    the original TIFFWriteDirectory() could be rewritten to just call this
123    function with the appropriate field and field-accessing arguments.
124 
125    However, now I realize that there's a lot of code that gets executed for
126    the main, standard TIFF directories that does not apply to special
127    private subdirectories, so such a reimplementation for the sake of
128    eliminating redundant or duplicate code is probably not possible,
129    unless we also pass in a Main flag to indiciate which type of handling
130    to do, which would be kind of a hack. I've marked those places where I
131    changed or ripped out code which would have to be re-inserted to
132    generalize this function. If it can be done in a clean and graceful way,
133    it would be a great way to generalize the TIFF library. Otherwise, I'll
134    just leave this code here where it duplicates but remains on top of and
135    hopefully mostly independent of the main TIFF library.
136 
137    The caller will probably want to free the sub directory structure after
138    returning from this call, since otherwise once written out, the user
139    is likely to forget about it and leave data lying around.
140 */
141 toff_t
TIFFWritePrivateDataSubDirectory(TIFF * tif,uint32 pdir_fieldsset[],int pdir_fields_last,TIFFFieldInfo * field_info,int (* getFieldFn)(TIFF * tif,ttag_t tag,...))142 TIFFWritePrivateDataSubDirectory(TIFF* tif,
143 				 uint32 pdir_fieldsset[], int pdir_fields_last,
144 				 TIFFFieldInfo *field_info,
145 				 int (*getFieldFn)(TIFF *tif, ttag_t tag, ...))
146 {
147 	uint16 dircount;
148 	uint32 diroff, nextdiroff;
149 	ttag_t tag;
150 	uint32 nfields;
151 	tsize_t dirsize;
152 	char* data;
153 	TIFFDirEntry* dir;
154 	u_long b, *fields, fields_size;
155 	toff_t directory_offset;
156 	TIFFFieldInfo* fip;
157 
158 	/*
159 	 * Deleted out all of the encoder flushing and such code from here -
160 	 * not necessary for subdirectories.
161 	 */
162 
163 	/* Finish writing out any image data. */
164 	TIFFFlushData(tif);
165 
166 	/*
167 	 * Size the directory so that we can calculate
168 	 * offsets for the data items that aren't kept
169 	 * in-place in each field.
170 	 */
171 	nfields = 0;
172 	for (b = 0; b <= pdir_fields_last; b++)
173 		if (FieldSet(pdir_fieldsset, b))
174 			/* Deleted code to make size of first 4 tags 2
175 			   instead of 1. */
176 			nfields += 1;
177 	dirsize = nfields * sizeof (TIFFDirEntry);
178 	data = (char*) _TIFFmalloc(dirsize);
179 	if (data == NULL) {
180 		TIFFError(tif->tif_name,
181 		    "Cannot write private subdirectory, out of space");
182 		return (0);
183 	}
184 	/*
185 	 * Place directory in data section of the file. If there isn't one
186 	 * yet, place it at the end of the file. The directory is treated as
187 	 * data, so we don't link it into the directory structure at all.
188 	 */
189 	if (tif->tif_dataoff == 0)
190 	    tif->tif_dataoff =(TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
191 	diroff = tif->tif_dataoff;
192 	tif->tif_dataoff = (toff_t)(
193 	    diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
194 	if (tif->tif_dataoff & 1)
195 		tif->tif_dataoff++;
196 	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
197 	/*tif->tif_curdir++;*/
198 	dir = (TIFFDirEntry*) data;
199 	/*
200 	 * Setup external form of directory
201 	 * entries and write data items.
202 	 */
203 	/*
204 	 * We make a local copy of the fieldsset here so that we don't mess
205 	 * up the original one when we call ResetFieldBit(). But I'm not sure
206 	 * why the original code calls ResetFieldBit(), since we're already
207 	 * going through the fields in order...
208 	 *
209 	 * fields_size is the number of uint32's we will need to hold the
210 	 * bit-mask for all of the fields. If our highest field number is
211 	 * 100, then we'll need 100 / (8*4)+1 == 4 uint32's to hold the
212 	 * fieldset.
213 	 *
214 	 * Unlike the original code, we allocate fields dynamically based
215 	 * on the requested pdir_fields_last value, allowing private
216 	 * data subdirectories to contain more than the built-in code's limit
217 	 * of 95 tags in a directory.
218 	 */
219 	fields_size = pdir_fields_last / (8*sizeof(uint32)) + 1;
220 	fields = _TIFFmalloc(fields_size*sizeof(uint32));
221 	_TIFFmemcpy(fields, pdir_fieldsset, fields_size * sizeof(uint32));
222 
223 	/* Deleted "write out extra samples tag" code here. */
224 
225 	/* Deleted code for checking a billion little special cases for the
226 	 * standard TIFF tags. Should add a general mechanism for overloading
227 	 * write function for each field, just like Brian kept telling me!!!
228 	 */
229 	for (fip = field_info; fip->field_tag; fip++) {
230 		/* Deleted code to check for FIELD_IGNORE!! */
231 		if (/* fip->field_bit == FIELD_IGNORE || */
232 		    !FieldSet(fields, fip->field_bit))
233 			continue;
234 		if (!TIFFWriteNormalSubTag(tif, dir, fip, getFieldFn))
235 			goto bad;
236 		dir++;
237 		ResetFieldBit(fields, fip->field_bit);
238 	}
239 
240 	/* Now we've written all of the referenced data, and are about to
241 	   write the main directory structure, so grab the tif_dataoff value
242 	   now so we can remember where we wrote the directory. */
243 	directory_offset = tif->tif_dataoff;
244 
245 	/*
246 	 * Write directory.
247 	 */
248 	dircount = (uint16) nfields;
249 	/* Deleted code to link to the next directory - we set it to zero! */
250 	nextdiroff = 0;
251 	if (tif->tif_flags & TIFF_SWAB) {
252 		/*
253 		 * The file's byte order is opposite to the
254 		 * native machine architecture.  We overwrite
255 		 * the directory information with impunity
256 		 * because it'll be released below after we
257 		 * write it to the file.  Note that all the
258 		 * other tag construction routines assume that
259 		 * we do this byte-swapping; i.e. they only
260 		 * byte-swap indirect data.
261 		 */
262 		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
263 			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
264 			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
265 		}
266 		dircount = (uint16) nfields;
267 		TIFFSwabShort(&dircount);
268 		TIFFSwabLong(&nextdiroff);
269 	}
270 
271 	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
272 	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
273 		TIFFError(tif->tif_name, "Error writing private subdirectory count");
274 		goto bad;
275 	}
276 	if (!WriteOK(tif, data, dirsize)) {
277 		TIFFError(tif->tif_name, "Error writing private subdirectory contents");
278 		goto bad;
279 	}
280 	if (!WriteOK(tif, &nextdiroff, sizeof (nextdiroff))) {
281 		TIFFError(tif->tif_name, "Error writing private subdirectory link");
282 		goto bad;
283 	}
284 	tif->tif_dataoff += sizeof(dircount) + dirsize + sizeof(nextdiroff);
285 
286 	_TIFFfree(data);
287 	_TIFFfree(fields);
288 	tif->tif_flags &= ~TIFF_DIRTYDIRECT;
289 
290 #if (0)
291 	/* This stuff commented out because I don't think we want it for
292 	   subdirectories, but I could be wrong. */
293 	(*tif->tif_cleanup)(tif);
294 
295 	/*
296 	 * Reset directory-related state for subsequent
297 	 * directories.
298 	 */
299 	TIFFDefaultDirectory(tif);
300 	tif->tif_curoff = 0;
301 	tif->tif_row = (uint32) -1;
302 	tif->tif_curstrip = (tstrip_t) -1;
303 #endif
304 
305 	return (directory_offset);
306 bad:
307 	_TIFFfree(data);
308 	_TIFFfree(fields);
309 	return (0);
310 }
311 #undef WriteRationalPair
312 
313 /*
314  * Process tags that are not special cased.
315  */
316 /* The standard function TIFFWriteNormalTag() could definitely be replaced
317    with a simple call to this function, just adding TIFFGetField() as the
318    last argument. */
319 static int
TIFFWriteNormalSubTag(TIFF * tif,TIFFDirEntry * dir,const TIFFFieldInfo * fip,int (* getFieldFn)(TIFF * tif,ttag_t tag,...))320 TIFFWriteNormalSubTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip,
321 		      int (*getFieldFn)(TIFF *tif, ttag_t tag, ...))
322 {
323 	u_short wc = (u_short) fip->field_writecount;
324 
325 	dir->tdir_tag = fip->field_tag;
326 	dir->tdir_type = (u_short) fip->field_type;
327 	dir->tdir_count = wc;
328 #define	WRITEF(x,y)	x(tif, fip->field_type, fip->field_tag, dir, wc, y)
329 	switch (fip->field_type) {
330 	case TIFF_SHORT:
331 	case TIFF_SSHORT:
332 		if (wc > 1) {
333 			uint16* wp;
334 			if (wc == (u_short) TIFF_VARIABLE) {
335 				(*getFieldFn)(tif, fip->field_tag, &wc, &wp);
336 				dir->tdir_count = wc;
337 			} else
338 				(*getFieldFn)(tif, fip->field_tag, &wp);
339 			if (!WRITEF(TIFFWriteShortArray, wp))
340 				return (0);
341 		} else {
342 			uint16 sv;
343 			(*getFieldFn)(tif, fip->field_tag, &sv);
344 			dir->tdir_offset =
345 			    TIFFInsertData(tif, dir->tdir_type, sv);
346 		}
347 		break;
348 	case TIFF_LONG:
349 	case TIFF_SLONG:
350 		if (wc > 1) {
351 			uint32* lp;
352 			if (wc == (u_short) TIFF_VARIABLE) {
353 				(*getFieldFn)(tif, fip->field_tag, &wc, &lp);
354 				dir->tdir_count = wc;
355 			} else
356 				(*getFieldFn)(tif, fip->field_tag, &lp);
357 			if (!WRITEF(TIFFWriteLongArray, lp))
358 				return (0);
359 		} else {
360 			/* XXX handle LONG->SHORT conversion */
361 			(*getFieldFn)(tif, fip->field_tag, &dir->tdir_offset);
362 		}
363 		break;
364 	case TIFF_RATIONAL:
365 	case TIFF_SRATIONAL:
366 		if (wc > 1) {
367 			float* fp;
368 			if (wc == (u_short) TIFF_VARIABLE) {
369 				(*getFieldFn)(tif, fip->field_tag, &wc, &fp);
370 				dir->tdir_count = wc;
371 			} else
372 				(*getFieldFn)(tif, fip->field_tag, &fp);
373 			if (!WRITEF(TIFFWriteRationalArray, fp))
374 				return (0);
375 		} else {
376 			float fv;
377 			(*getFieldFn)(tif, fip->field_tag, &fv);
378 			if (!WRITEF(TIFFWriteRationalArray, &fv))
379 				return (0);
380 		}
381 		break;
382 	case TIFF_FLOAT:
383 		if (wc > 1) {
384 			float* fp;
385 			if (wc == (u_short) TIFF_VARIABLE) {
386 				(*getFieldFn)(tif, fip->field_tag, &wc, &fp);
387 				dir->tdir_count = wc;
388 			} else
389 				(*getFieldFn)(tif, fip->field_tag, &fp);
390 			if (!WRITEF(TIFFWriteFloatArray, fp))
391 				return (0);
392 		} else {
393 			float fv;
394 			(*getFieldFn)(tif, fip->field_tag, &fv);
395 			if (!WRITEF(TIFFWriteFloatArray, &fv))
396 				return (0);
397 		}
398 		break;
399 	case TIFF_DOUBLE:
400 		/* Hey - I think this is a bug, or at least a "gross
401 		   inconsistency", in the TIFF library. Look at the original
402 		   TIFF library code below within the "#if (0) ... #else".
403 		   Just from the type of *dp, you can see that this code
404 		   expects TIFFGetField() to be handed a double ** for
405 		   any TIFF_DOUBLE tag, even for the constant wc==1 case.
406 		   This is totally inconsistent with other fields (like
407 		   TIFF_FLOAT, above) and is also inconsistent with the
408 		   TIFFSetField() function for TIFF_DOUBLEs, which expects
409 		   to be passed a single double by value for the wc==1 case.
410 		   (See the handling of TIFFFetchNormalTag() in tif_dirread.c
411 		   for an example.) Maybe this function was written before
412 		   TIFFWriteDoubleArray() was written, not that that's an
413 		   excuse. Anyway, the new code below is a trivial modification
414 		   of the TIFF_FLOAT code above. The fact that even single
415 		   doubles get written out in the data segment and get an
416 		   offset value stored is irrelevant here - that is all
417 		   handled by TIFFWriteDoubleArray(). */
418 #if (0)
419 		{ double* dp;
420 		  if (wc == (u_short) TIFF_VARIABLE) {
421 			(*getFieldFn)(tif, fip->field_tag, &wc, &dp);
422 			dir->tdir_count = wc;
423 		  } else
424 			(*getFieldFn)(tif, fip->field_tag, &dp);
425 		  TIFFCvtNativeToIEEEDouble(tif, wc, dp);
426 		  if (!TIFFWriteData(tif, dir, (char*) dp))
427 			return (0);
428 		}
429 #else
430 		if (wc > 1) {
431 			double* dp;
432 			if (wc == (u_short) TIFF_VARIABLE) {
433 				(*getFieldFn)(tif, fip->field_tag, &wc, &dp);
434 				dir->tdir_count = wc;
435 			} else
436 				(*getFieldFn)(tif, fip->field_tag, &dp);
437 			if (!WRITEF(TIFFWriteDoubleArray, dp))
438 				return (0);
439 		} else {
440 			double dv;
441 			(*getFieldFn)(tif, fip->field_tag, &dv);
442 			if (!WRITEF(TIFFWriteDoubleArray, &dv))
443 				return (0);
444 		}
445 #endif
446 		break;
447 	case TIFF_ASCII:
448 		{ char* cp;
449 		  (*getFieldFn)(tif, fip->field_tag, &cp);
450 		  dir->tdir_count = (uint32) (strlen(cp) + 1);
451 		  if (!TIFFWriteByteArray(tif, dir, cp))
452 			return (0);
453 		}
454 		break;
455 	case TIFF_UNDEFINED:
456 		{ char* cp;
457 		  if (wc == (u_short) TIFF_VARIABLE) {
458 			(*getFieldFn)(tif, fip->field_tag, &wc, &cp);
459 			dir->tdir_count = wc;
460 		  } else
461 			(*getFieldFn)(tif, fip->field_tag, &cp);
462 		  if (!TIFFWriteByteArray(tif, dir, cp))
463 			return (0);
464 		}
465 		break;
466 	}
467 	return (1);
468 }
469 #undef WRITEF
470 
471 /* Everything after this is exactly duplicated from the standard tif_dirwrite.c
472    file, necessitated by the fact that they are declared static there so
473    we can't call them!
474 */
475 /*
476  * Setup a directory entry with either a SHORT
477  * or LONG type according to the value.
478  */
479 static void
TIFFSetupShortLong(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 v)480 TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
481 {
482 	dir->tdir_tag = tag;
483 	dir->tdir_count = 1;
484 	if (v > 0xffffL) {
485 		dir->tdir_type = (short) TIFF_LONG;
486 		dir->tdir_offset = v;
487 	} else {
488 		dir->tdir_type = (short) TIFF_SHORT;
489 		dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
490 	}
491 }
492 #undef MakeShortDirent
493 
494 #ifndef TIFFWriteRational
495 /*
496  * Setup a RATIONAL directory entry and
497  * write the associated indirect value.
498  */
499 static int
TIFFWriteRational(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,float v)500 TIFFWriteRational(TIFF* tif,
501     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v)
502 {
503 	return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v));
504 }
505 #endif
506 
507 #define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))
508 /*
509  * Setup a directory entry that references a
510  * samples/pixel array of SHORT values and
511  * (potentially) write the associated indirect
512  * values.
513  */
514 static int
TIFFWritePerSampleShorts(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)515 TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
516 {
517 	uint16 buf[10], v;
518 	uint16* w = buf;
519 	int i, status, samples = tif->tif_dir.td_samplesperpixel;
520 
521 	if (samples > NITEMS(buf))
522 		w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
523 	TIFFGetField(tif, tag, &v);
524 	for (i = 0; i < samples; i++)
525 		w[i] = v;
526 	status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w);
527 	if (w != buf)
528 		_TIFFfree((char*) w);
529 	return (status);
530 }
531 
532 /*
533  * Setup a directory entry that references a samples/pixel array of ``type''
534  * values and (potentially) write the associated indirect values.  The source
535  * data from TIFFGetField() for the specified tag must be returned as double.
536  */
537 static int
TIFFWritePerSampleAnys(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir)538 TIFFWritePerSampleAnys(TIFF* tif,
539     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
540 {
541 	double buf[10], v;
542 	double* w = buf;
543 	int i, status;
544 	int samples = (int) tif->tif_dir.td_samplesperpixel;
545 
546 	if (samples > NITEMS(buf))
547 		w = (double*) _TIFFmalloc(samples * sizeof (double));
548 	TIFFGetField(tif, tag, &v);
549 	for (i = 0; i < samples; i++)
550 		w[i] = v;
551 	status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
552 	if (w != buf)
553 		_TIFFfree(w);
554 	return (status);
555 }
556 #undef NITEMS
557 
558 /*
559  * Setup a pair of shorts that are returned by
560  * value, rather than as a reference to an array.
561  */
562 static int
TIFFSetupShortPair(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)563 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
564 {
565 	uint16 v[2];
566 
567 	TIFFGetField(tif, tag, &v[0], &v[1]);
568 	return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
569 }
570 
571 /*
572  * Setup a directory entry for an NxM table of shorts,
573  * where M is known to be 2**bitspersample, and write
574  * the associated indirect data.
575  */
576 static int
TIFFWriteShortTable(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint16 ** table)577 TIFFWriteShortTable(TIFF* tif,
578     ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
579 {
580 	uint32 i, off;
581 
582 	dir->tdir_tag = tag;
583 	dir->tdir_type = (short) TIFF_SHORT;
584 	/* XXX -- yech, fool TIFFWriteData */
585 	dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
586 	off = tif->tif_dataoff;
587 	for (i = 0; i < n; i++)
588 		if (!TIFFWriteData(tif, dir, (char *)table[i]))
589 			return (0);
590 	dir->tdir_count *= n;
591 	dir->tdir_offset = off;
592 	return (1);
593 }
594 
595 /*
596  * Write/copy data associated with an ASCII or opaque tag value.
597  */
598 static int
TIFFWriteByteArray(TIFF * tif,TIFFDirEntry * dir,char * cp)599 TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
600 {
601 	if (dir->tdir_count > 4) {
602 		if (!TIFFWriteData(tif, dir, cp))
603 			return (0);
604 	} else
605 		_TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
606 	return (1);
607 }
608 
609 /*
610  * Setup a directory entry of an array of SHORT
611  * or SSHORT and write the associated indirect values.
612  */
613 static int
TIFFWriteShortArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint16 * v)614 TIFFWriteShortArray(TIFF* tif,
615     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v)
616 {
617 	dir->tdir_tag = tag;
618 	dir->tdir_type = (short) type;
619 	dir->tdir_count = n;
620 	if (n <= 2) {
621 		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
622 			dir->tdir_offset = (uint32) ((long) v[0] << 16);
623 			if (n == 2)
624 				dir->tdir_offset |= v[1] & 0xffff;
625 		} else {
626 			dir->tdir_offset = v[0] & 0xffff;
627 			if (n == 2)
628 				dir->tdir_offset |= (long) v[1] << 16;
629 		}
630 		return (1);
631 	} else
632 		return (TIFFWriteData(tif, dir, (char*) v));
633 }
634 
635 /*
636  * Setup a directory entry of an array of LONG
637  * or SLONG and write the associated indirect values.
638  */
639 static int
TIFFWriteLongArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint32 * v)640 TIFFWriteLongArray(TIFF* tif,
641     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v)
642 {
643 	dir->tdir_tag = tag;
644 	dir->tdir_type = (short) type;
645 	dir->tdir_count = n;
646 	if (n == 1) {
647 		dir->tdir_offset = v[0];
648 		return (1);
649 	} else
650 		return (TIFFWriteData(tif, dir, (char*) v));
651 }
652 
653 /*
654  * Setup a directory entry of an array of RATIONAL
655  * or SRATIONAL and write the associated indirect values.
656  */
657 static int
TIFFWriteRationalArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,float * v)658 TIFFWriteRationalArray(TIFF* tif,
659     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
660 {
661 	uint32 i;
662 	uint32* t;
663 	int status;
664 
665 	dir->tdir_tag = tag;
666 	dir->tdir_type = (short) type;
667 	dir->tdir_count = n;
668 	t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32));
669 	for (i = 0; i < n; i++) {
670 		float fv = v[i];
671 		int sign = 1;
672 		uint32 den;
673 
674 		if (fv < 0) {
675 			if (type == TIFF_RATIONAL) {
676 				TIFFWarning(tif->tif_name,
677 	"\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
678 				_TIFFFieldWithTag(tif,tag)->field_name, v);
679 				fv = 0;
680 			} else
681 				fv = -fv, sign = -1;
682 		}
683 		den = 1L;
684 		if (fv > 0) {
685 			while (fv < 1L<<(31-3) && den < 1L<<(31-3))
686 				fv *= 1<<3, den *= 1L<<3;
687 		}
688 		t[2*i+0] = sign * (fv + 0.5);
689 		t[2*i+1] = den;
690 	}
691 	status = TIFFWriteData(tif, dir, (char *)t);
692 	_TIFFfree((char*) t);
693 	return (status);
694 }
695 
696 static int
TIFFWriteFloatArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,float * v)697 TIFFWriteFloatArray(TIFF* tif,
698     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
699 {
700 	dir->tdir_tag = tag;
701 	dir->tdir_type = (short) type;
702 	dir->tdir_count = n;
703 	TIFFCvtNativeToIEEEFloat(tif, n, v);
704 	if (n == 1) {
705 		dir->tdir_offset = *(uint32*) &v[0];
706 		return (1);
707 	} else
708 		return (TIFFWriteData(tif, dir, (char*) v));
709 }
710 
711 static int
TIFFWriteDoubleArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,double * v)712 TIFFWriteDoubleArray(TIFF* tif,
713     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
714 {
715 	dir->tdir_tag = tag;
716 	dir->tdir_type = (short) type;
717 	dir->tdir_count = n;
718 	TIFFCvtNativeToIEEEDouble(tif, n, v);
719 	return (TIFFWriteData(tif, dir, (char*) v));
720 }
721 
722 /*
723  * Write an array of ``type'' values for a specified tag (i.e. this is a tag
724  * which is allowed to have different types, e.g. SMaxSampleType).
725  * Internally the data values are represented as double since a double can
726  * hold any of the TIFF tag types (yes, this should really be an abstract
727  * type tany_t for portability).  The data is converted into the specified
728  * type in a temporary buffer and then handed off to the appropriate array
729  * writer.
730  */
731 static int
TIFFWriteAnyArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,double * v)732 TIFFWriteAnyArray(TIFF* tif,
733     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
734 {
735 	char buf[10 * sizeof(double)];
736 	char* w = buf;
737 	int i, status = 0;
738 
739 	if (n * TIFFDataWidth(type) > sizeof buf)
740 		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
741 	switch (type) {
742 	case TIFF_BYTE:
743 		{ unsigned char* bp = (unsigned char*) w;
744 		  for (i = 0; i < n; i++)
745 			bp[i] = (unsigned char) v[i];
746 		  dir->tdir_tag = tag;
747 		  dir->tdir_type = (short) type;
748 		  dir->tdir_count = n;
749 		  if (!TIFFWriteByteArray(tif, dir, (char*) bp))
750 			goto out;
751 		}
752 		break;
753 	case TIFF_SBYTE:
754 		{ signed char* bp = (signed char*) w;
755 		  for (i = 0; i < n; i++)
756 			bp[i] = (signed char) v[i];
757 		  dir->tdir_tag = tag;
758 		  dir->tdir_type = (short) type;
759 		  dir->tdir_count = n;
760 		  if (!TIFFWriteByteArray(tif, dir, (char*) bp))
761 			goto out;
762 		}
763 		break;
764 	case TIFF_SHORT:
765 		{ uint16* bp = (uint16*) w;
766 		  for (i = 0; i < n; i++)
767 			bp[i] = (uint16) v[i];
768 		  if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
769 				goto out;
770 		}
771 		break;
772 	case TIFF_SSHORT:
773 		{ int16* bp = (int16*) w;
774 		  for (i = 0; i < n; i++)
775 			bp[i] = (int16) v[i];
776 		  if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
777 			goto out;
778 		}
779 		break;
780 	case TIFF_LONG:
781 		{ uint32* bp = (uint32*) w;
782 		  for (i = 0; i < n; i++)
783 			bp[i] = (uint32) v[i];
784 		  if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp))
785 			goto out;
786 		}
787 		break;
788 	case TIFF_SLONG:
789 		{ int32* bp = (int32*) w;
790 		  for (i = 0; i < n; i++)
791 			bp[i] = (int32) v[i];
792 		  if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp))
793 			goto out;
794 		}
795 		break;
796 	case TIFF_FLOAT:
797 		{ float* bp = (float*) w;
798 		  for (i = 0; i < n; i++)
799 			bp[i] = (float) v[i];
800 		  if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp))
801 			goto out;
802 		}
803 		break;
804 	case TIFF_DOUBLE:
805 		return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v));
806 	default:
807 		/* TIFF_NOTYPE */
808 		/* TIFF_ASCII */
809 		/* TIFF_UNDEFINED */
810 		/* TIFF_RATIONAL */
811 		/* TIFF_SRATIONAL */
812 		goto out;
813 	}
814 	status = 1;
815  out:
816 	if (w != buf)
817 		_TIFFfree(w);
818 	return (status);
819 }
820 
821 #ifdef COLORIMETRY_SUPPORT
822 static int
TIFFWriteTransferFunction(TIFF * tif,TIFFDirEntry * dir)823 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
824 {
825 	TIFFDirectory* td = &tif->tif_dir;
826 	tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
827 	uint16** tf = td->td_transferfunction;
828 	int ncols;
829 
830 	/*
831 	 * Check if the table can be written as a single column,
832 	 * or if it must be written as 3 columns.  Note that we
833 	 * write a 3-column tag if there are 2 samples/pixel and
834 	 * a single column of data won't suffice--hmm.
835 	 */
836 	switch (td->td_samplesperpixel - td->td_extrasamples) {
837 	default:	if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
838 	case 2:		if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
839 	case 1: case 0:	ncols = 1;
840 	}
841 	return (TIFFWriteShortTable(tif,
842 	    TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
843 }
844 #endif
845 
846 /*
847  * Write a contiguous directory item.
848  */
849 static int
TIFFWriteData(TIFF * tif,TIFFDirEntry * dir,char * cp)850 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
851 {
852 	tsize_t cc;
853 
854 	if (tif->tif_flags & TIFF_SWAB) {
855 		switch (dir->tdir_type) {
856 		case TIFF_SHORT:
857 		case TIFF_SSHORT:
858 			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
859 			break;
860 		case TIFF_LONG:
861 		case TIFF_SLONG:
862 		case TIFF_FLOAT:
863 			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
864 			break;
865 		case TIFF_RATIONAL:
866 		case TIFF_SRATIONAL:
867 			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
868 			break;
869 		case TIFF_DOUBLE:
870 			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
871 			break;
872 		}
873 	}
874 	dir->tdir_offset = tif->tif_dataoff;
875 	cc = dir->tdir_count * TIFFDataWidth(dir->tdir_type);
876 	if (SeekOK(tif, dir->tdir_offset) &&
877 	    WriteOK(tif, cp, cc)) {
878 		tif->tif_dataoff += (cc + 1) & ~1;
879 		return (1);
880 	}
881 	TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
882 	    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
883 	return (0);
884 }
885 
886 /*
887  * Link the current directory into the
888  * directory chain for the file.
889  */
890 static int
TIFFLinkDirectory(TIFF * tif)891 TIFFLinkDirectory(TIFF* tif)
892 {
893 	static const char module[] = "TIFFLinkDirectory";
894 	uint32 nextdir;
895 	uint32 diroff;
896 
897 	tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
898 	diroff = (uint32) tif->tif_diroff;
899 	if (tif->tif_flags & TIFF_SWAB)
900 		TIFFSwabLong(&diroff);
901 #if SUBIFD_SUPPORT
902 	if (tif->tif_flags & TIFF_INSUBIFD) {
903 		(void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
904 		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
905 			TIFFError(module,
906 			    "%s: Error writing SubIFD directory link",
907 			    tif->tif_name);
908 			return (0);
909 		}
910 		/*
911 		 * Advance to the next SubIFD or, if this is
912 		 * the last one configured, revert back to the
913 		 * normal directory linkage.
914 		 */
915 		if (--tif->tif_nsubifd)
916 			tif->tif_subifdoff += sizeof (diroff);
917 		else
918 			tif->tif_flags &= ~TIFF_INSUBIFD;
919 		return (1);
920 	}
921 #endif
922 	if (tif->tif_header.tiff_diroff == 0) {
923 		/*
924 		 * First directory, overwrite offset in header.
925 		 */
926 		tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff;
927 #define	HDROFF(f)	((toff_t) &(((TIFFHeader*) 0)->f))
928 		(void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET);
929 		if (!WriteOK(tif, &diroff, sizeof (diroff))) {
930 			TIFFError(tif->tif_name, "Error writing TIFF header");
931 			return (0);
932 		}
933 		return (1);
934 	}
935 	/*
936 	 * Not the first directory, search to the last and append.
937 	 */
938 	nextdir = tif->tif_header.tiff_diroff;
939 	do {
940 		uint16 dircount;
941 
942 		if (!SeekOK(tif, nextdir) ||
943 		    !ReadOK(tif, &dircount, sizeof (dircount))) {
944 			TIFFError(module, "Error fetching directory count");
945 			return (0);
946 		}
947 		if (tif->tif_flags & TIFF_SWAB)
948 			TIFFSwabShort(&dircount);
949 		(void) TIFFSeekFile(tif,
950 		    dircount * sizeof (TIFFDirEntry), SEEK_CUR);
951 		if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
952 			TIFFError(module, "Error fetching directory link");
953 			return (0);
954 		}
955 		if (tif->tif_flags & TIFF_SWAB)
956 			TIFFSwabLong(&nextdir);
957 	} while (nextdir != 0);
958 	(void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR);
959 	if (!WriteOK(tif, &diroff, sizeof (diroff))) {
960 		TIFFError(module, "Error writing directory link");
961 		return (0);
962 	}
963 	return (1);
964 }
965