1 /* $Id: tif_aux.c,v 1.19 2006/02/07 10:41:30 dron Exp $ */
2 
3 /*
4  * Copyright (c) 1991-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  *
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  */
26 
27 /*
28  * TIFF Library.
29  *
30  * Auxiliary Support Routines.
31  */
32 #include "tiffiop.h"
33 #include "tif_predict.h"
34 #include <math.h>
35 
36 tdata_t
_TIFFCheckMalloc(TIFF * tif,size_t nmemb,size_t elem_size,const char * what)37 _TIFFCheckMalloc(TIFF* tif, size_t nmemb, size_t elem_size, const char* what)
38 {
39 	tdata_t cp = NULL;
40 	tsize_t	bytes = nmemb * elem_size;
41 
42 	/*
43 	 * XXX: Check for integer overflow.
44 	 */
45 	if (nmemb && elem_size && bytes / elem_size == nmemb)
46 		cp = _TIFFmalloc(bytes);
47 
48 	if (cp == NULL)
49 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space %s", what);
50 
51 	return (cp);
52 }
53 
54 static int
TIFFDefaultTransferFunction(TIFFDirectory * td)55 TIFFDefaultTransferFunction(TIFFDirectory* td)
56 {
57 	uint16 **tf = td->td_transferfunction;
58 	tsize_t i, n, nbytes;
59 
60 	tf[0] = tf[1] = tf[2] = 0;
61 	if (td->td_bitspersample >= sizeof(tsize_t) * 8 - 2)
62 		return 0;
63 
64 	n = 1<<td->td_bitspersample;
65 	nbytes = n * sizeof (uint16);
66 	if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
67 		return 0;
68 	tf[0][0] = 0;
69 	for (i = 1; i < n; i++) {
70 		double t = (double)i/((double) n-1.);
71 		tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
72 	}
73 
74 	if (td->td_samplesperpixel - td->td_extrasamples > 1) {
75 		if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
76 			goto bad;
77 		_TIFFmemcpy(tf[1], tf[0], nbytes);
78 		if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
79 			goto bad;
80 		_TIFFmemcpy(tf[2], tf[0], nbytes);
81 	}
82 	return 1;
83 
84 bad:
85 	if (tf[0])
86 		_TIFFfree(tf[0]);
87 	if (tf[1])
88 		_TIFFfree(tf[1]);
89 	if (tf[2])
90 		_TIFFfree(tf[2]);
91 	tf[0] = tf[1] = tf[2] = 0;
92 	return 0;
93 }
94 
95 /*
96  * Like TIFFGetField, but return any default
97  * value if the tag is not present in the directory.
98  *
99  * NB:	We use the value in the directory, rather than
100  *	explcit values so that defaults exist only one
101  *	place in the library -- in TIFFDefaultDirectory.
102  */
103 int
TIFFVGetFieldDefaulted(TIFF * tif,ttag_t tag,va_list ap)104 TIFFVGetFieldDefaulted(TIFF* tif, ttag_t tag, va_list ap)
105 {
106 	TIFFDirectory *td = &tif->tif_dir;
107 
108 	if (TIFFVGetField(tif, tag, ap))
109 		return (1);
110 	switch (tag) {
111 	case TIFFTAG_SUBFILETYPE:
112 		*va_arg(ap, uint32 *) = td->td_subfiletype;
113 		return (1);
114 	case TIFFTAG_BITSPERSAMPLE:
115 		*va_arg(ap, uint16 *) = td->td_bitspersample;
116 		return (1);
117 	case TIFFTAG_THRESHHOLDING:
118 		*va_arg(ap, uint16 *) = td->td_threshholding;
119 		return (1);
120 	case TIFFTAG_FILLORDER:
121 		*va_arg(ap, uint16 *) = td->td_fillorder;
122 		return (1);
123 	case TIFFTAG_ORIENTATION:
124 		*va_arg(ap, uint16 *) = td->td_orientation;
125 		return (1);
126 	case TIFFTAG_SAMPLESPERPIXEL:
127 		*va_arg(ap, uint16 *) = td->td_samplesperpixel;
128 		return (1);
129 	case TIFFTAG_ROWSPERSTRIP:
130 		*va_arg(ap, uint32 *) = td->td_rowsperstrip;
131 		return (1);
132 	case TIFFTAG_MINSAMPLEVALUE:
133 		*va_arg(ap, uint16 *) = td->td_minsamplevalue;
134 		return (1);
135 	case TIFFTAG_MAXSAMPLEVALUE:
136 		*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
137 		return (1);
138 	case TIFFTAG_PLANARCONFIG:
139 		*va_arg(ap, uint16 *) = td->td_planarconfig;
140 		return (1);
141 	case TIFFTAG_RESOLUTIONUNIT:
142 		*va_arg(ap, uint16 *) = td->td_resolutionunit;
143 		return (1);
144 	case TIFFTAG_PREDICTOR:
145                 {
146 			TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
147 			*va_arg(ap, uint16*) = (uint16) sp->predictor;
148 			return 1;
149                 }
150 	case TIFFTAG_DOTRANGE:
151 		*va_arg(ap, uint16 *) = 0;
152 		*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
153 		return (1);
154 	case TIFFTAG_INKSET:
155 		*va_arg(ap, uint16 *) = INKSET_CMYK;
156 		return 1;
157 	case TIFFTAG_NUMBEROFINKS:
158 		*va_arg(ap, uint16 *) = 4;
159 		return (1);
160 	case TIFFTAG_EXTRASAMPLES:
161 		*va_arg(ap, uint16 *) = td->td_extrasamples;
162 		*va_arg(ap, uint16 **) = td->td_sampleinfo;
163 		return (1);
164 	case TIFFTAG_MATTEING:
165 		*va_arg(ap, uint16 *) =
166 		    (td->td_extrasamples == 1 &&
167 		     td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
168 		return (1);
169 	case TIFFTAG_TILEDEPTH:
170 		*va_arg(ap, uint32 *) = td->td_tiledepth;
171 		return (1);
172 	case TIFFTAG_DATATYPE:
173 		*va_arg(ap, uint16 *) = td->td_sampleformat-1;
174 		return (1);
175 	case TIFFTAG_SAMPLEFORMAT:
176 		*va_arg(ap, uint16 *) = td->td_sampleformat;
177                 return(1);
178 	case TIFFTAG_IMAGEDEPTH:
179 		*va_arg(ap, uint32 *) = td->td_imagedepth;
180 		return (1);
181 	case TIFFTAG_YCBCRCOEFFICIENTS:
182 		{
183 			/* defaults are from CCIR Recommendation 601-1 */
184 			static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
185 			*va_arg(ap, float **) = ycbcrcoeffs;
186 			return 1;
187 		}
188 	case TIFFTAG_YCBCRSUBSAMPLING:
189 		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
190 		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
191 		return (1);
192 	case TIFFTAG_YCBCRPOSITIONING:
193 		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
194 		return (1);
195 	case TIFFTAG_WHITEPOINT:
196 		{
197 			static float whitepoint[2];
198 
199 			/* TIFF 6.0 specification tells that it is no default
200 			   value for the WhitePoint, but AdobePhotoshop TIFF
201 			   Technical Note tells that it should be CIE D50. */
202 			whitepoint[0] =	D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
203 			whitepoint[1] =	D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
204 			*va_arg(ap, float **) = whitepoint;
205 			return 1;
206 		}
207 	case TIFFTAG_TRANSFERFUNCTION:
208 		if (!td->td_transferfunction[0] &&
209 		    !TIFFDefaultTransferFunction(td)) {
210 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
211 			return (0);
212 		}
213 		*va_arg(ap, uint16 **) = td->td_transferfunction[0];
214 		if (td->td_samplesperpixel - td->td_extrasamples > 1) {
215 			*va_arg(ap, uint16 **) = td->td_transferfunction[1];
216 			*va_arg(ap, uint16 **) = td->td_transferfunction[2];
217 		}
218 		return (1);
219 	case TIFFTAG_REFERENCEBLACKWHITE:
220 		{
221 			int i;
222 			static float ycbcr_refblackwhite[] =
223 			{ 0.0F, 255.0F, 128.0F, 255.0F, 128.0F, 255.0F };
224 			static float rgb_refblackwhite[6];
225 
226 			for (i = 0; i < 3; i++) {
227 				rgb_refblackwhite[2 * i + 0] = 0.0F;
228 				rgb_refblackwhite[2 * i + 1] =
229 					(float)((1L<<td->td_bitspersample)-1L);
230 			}
231 
232 			if (td->td_photometric == PHOTOMETRIC_YCBCR) {
233 				/*
234 				 * YCbCr (Class Y) images must have the
235 				 * ReferenceBlackWhite tag set. Fix the
236 				 * broken images, which lacks that tag.
237 				 */
238 				*va_arg(ap, float **) = ycbcr_refblackwhite;
239 			} else {
240 				/*
241 				 * Assume RGB (Class R)
242 				 */
243 				*va_arg(ap, float **) = rgb_refblackwhite;
244 			}
245 			return 1;
246 		}
247 	}
248 	return 0;
249 }
250 
251 /*
252  * Like TIFFGetField, but return any default
253  * value if the tag is not present in the directory.
254  */
255 int
TIFFGetFieldDefaulted(TIFF * tif,ttag_t tag,...)256 TIFFGetFieldDefaulted(TIFF* tif, ttag_t tag, ...)
257 {
258 	int ok;
259 	va_list ap;
260 
261 	va_start(ap, tag);
262 	ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
263 	va_end(ap);
264 	return (ok);
265 }
266 
267 /* vim: set ts=8 sts=8 sw=8 noet: */
268