xref: /reactos/dll/3rdparty/libtiff/tif_aux.c (revision ac43fd2b)
1 /*
2  * Copyright (c) 1991-1997 Sam Leffler
3  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that (i) the above copyright notices and this permission notice appear in
8  * all copies of the software and related documentation, and (ii) the names of
9  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10  * publicity relating to the software without the specific, prior written
11  * permission of Sam Leffler and Silicon Graphics.
12  *
13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22  * OF THIS SOFTWARE.
23  */
24 
25 /*
26  * TIFF Library.
27  *
28  * Auxiliary Support Routines.
29  */
30 
31 #include <precomp.h>
32 #include "tif_predict.h"
33 #include <math.h>
34 
35 uint32
36 _TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
37 {
38 	uint32 bytes = first * second;
39 
40 	if (second && bytes / second != first) {
41 		TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
42 		bytes = 0;
43 	}
44 
45 	return bytes;
46 }
47 
48 uint64
49 _TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
50 {
51 	uint64 bytes = first * second;
52 
53 	if (second && bytes / second != first) {
54 		TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
55 		bytes = 0;
56 	}
57 
58 	return bytes;
59 }
60 
61 void*
62 _TIFFCheckRealloc(TIFF* tif, void* buffer,
63 		  tmsize_t nmemb, tmsize_t elem_size, const char* what)
64 {
65 	void* cp = NULL;
66 	tmsize_t bytes = nmemb * elem_size;
67 
68 	/*
69 	 * XXX: Check for integer overflow.
70 	 */
71 	if (nmemb && elem_size && bytes / elem_size == nmemb)
72 		cp = _TIFFrealloc(buffer, bytes);
73 
74 	if (cp == NULL) {
75 		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
76 			     "Failed to allocate memory for %s "
77 			     "(%ld elements of %ld bytes each)",
78 			     what,(long) nmemb, (long) elem_size);
79 	}
80 
81 	return cp;
82 }
83 
84 void*
85 _TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what)
86 {
87 	return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
88 }
89 
90 static int
91 TIFFDefaultTransferFunction(TIFFDirectory* td)
92 {
93 	uint16 **tf = td->td_transferfunction;
94 	tmsize_t i, n, nbytes;
95 
96 	tf[0] = tf[1] = tf[2] = 0;
97 	if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
98 		return 0;
99 
100 	n = ((tmsize_t)1)<<td->td_bitspersample;
101 	nbytes = n * sizeof (uint16);
102         tf[0] = (uint16 *)_TIFFmalloc(nbytes);
103 	if (tf[0] == NULL)
104 		return 0;
105 	tf[0][0] = 0;
106 	for (i = 1; i < n; i++) {
107 		double t = (double)i/((double) n-1.);
108 		tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
109 	}
110 
111 	if (td->td_samplesperpixel - td->td_extrasamples > 1) {
112                 tf[1] = (uint16 *)_TIFFmalloc(nbytes);
113 		if(tf[1] == NULL)
114 			goto bad;
115 		_TIFFmemcpy(tf[1], tf[0], nbytes);
116                 tf[2] = (uint16 *)_TIFFmalloc(nbytes);
117 		if (tf[2] == NULL)
118 			goto bad;
119 		_TIFFmemcpy(tf[2], tf[0], nbytes);
120 	}
121 	return 1;
122 
123 bad:
124 	if (tf[0])
125 		_TIFFfree(tf[0]);
126 	if (tf[1])
127 		_TIFFfree(tf[1]);
128 	if (tf[2])
129 		_TIFFfree(tf[2]);
130 	tf[0] = tf[1] = tf[2] = 0;
131 	return 0;
132 }
133 
134 static int
135 TIFFDefaultRefBlackWhite(TIFFDirectory* td)
136 {
137 	int i;
138 
139         td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float));
140 	if (td->td_refblackwhite == NULL)
141 		return 0;
142         if (td->td_photometric == PHOTOMETRIC_YCBCR) {
143 		/*
144 		 * YCbCr (Class Y) images must have the ReferenceBlackWhite
145 		 * tag set. Fix the broken images, which lacks that tag.
146 		 */
147 		td->td_refblackwhite[0] = 0.0F;
148 		td->td_refblackwhite[1] = td->td_refblackwhite[3] =
149 			td->td_refblackwhite[5] = 255.0F;
150 		td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
151 	} else {
152 		/*
153 		 * Assume RGB (Class R)
154 		 */
155 		for (i = 0; i < 3; i++) {
156 		    td->td_refblackwhite[2*i+0] = 0;
157 		    td->td_refblackwhite[2*i+1] =
158 			    (float)((1L<<td->td_bitspersample)-1L);
159 		}
160 	}
161 	return 1;
162 }
163 
164 /*
165  * Like TIFFGetField, but return any default
166  * value if the tag is not present in the directory.
167  *
168  * NB:	We use the value in the directory, rather than
169  *	explicit values so that defaults exist only one
170  *	place in the library -- in TIFFDefaultDirectory.
171  */
172 int
173 TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
174 {
175 	TIFFDirectory *td = &tif->tif_dir;
176 
177 	if (TIFFVGetField(tif, tag, ap))
178 		return (1);
179 	switch (tag) {
180 	case TIFFTAG_SUBFILETYPE:
181 		*va_arg(ap, uint32 *) = td->td_subfiletype;
182 		return (1);
183 	case TIFFTAG_BITSPERSAMPLE:
184 		*va_arg(ap, uint16 *) = td->td_bitspersample;
185 		return (1);
186 	case TIFFTAG_THRESHHOLDING:
187 		*va_arg(ap, uint16 *) = td->td_threshholding;
188 		return (1);
189 	case TIFFTAG_FILLORDER:
190 		*va_arg(ap, uint16 *) = td->td_fillorder;
191 		return (1);
192 	case TIFFTAG_ORIENTATION:
193 		*va_arg(ap, uint16 *) = td->td_orientation;
194 		return (1);
195 	case TIFFTAG_SAMPLESPERPIXEL:
196 		*va_arg(ap, uint16 *) = td->td_samplesperpixel;
197 		return (1);
198 	case TIFFTAG_ROWSPERSTRIP:
199 		*va_arg(ap, uint32 *) = td->td_rowsperstrip;
200 		return (1);
201 	case TIFFTAG_MINSAMPLEVALUE:
202 		*va_arg(ap, uint16 *) = td->td_minsamplevalue;
203 		return (1);
204 	case TIFFTAG_MAXSAMPLEVALUE:
205 		*va_arg(ap, uint16 *) = td->td_maxsamplevalue;
206 		return (1);
207 	case TIFFTAG_PLANARCONFIG:
208 		*va_arg(ap, uint16 *) = td->td_planarconfig;
209 		return (1);
210 	case TIFFTAG_RESOLUTIONUNIT:
211 		*va_arg(ap, uint16 *) = td->td_resolutionunit;
212 		return (1);
213 	case TIFFTAG_PREDICTOR:
214     {
215         TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
216         if( sp == NULL )
217         {
218             TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
219                          "Cannot get \"Predictor\" tag as plugin is not configured");
220             *va_arg(ap, uint16*) = 0;
221             return 0;
222         }
223         *va_arg(ap, uint16*) = (uint16) sp->predictor;
224         return 1;
225     }
226 	case TIFFTAG_DOTRANGE:
227 		*va_arg(ap, uint16 *) = 0;
228 		*va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
229 		return (1);
230 	case TIFFTAG_INKSET:
231 		*va_arg(ap, uint16 *) = INKSET_CMYK;
232 		return 1;
233 	case TIFFTAG_NUMBEROFINKS:
234 		*va_arg(ap, uint16 *) = 4;
235 		return (1);
236 	case TIFFTAG_EXTRASAMPLES:
237 		*va_arg(ap, uint16 *) = td->td_extrasamples;
238 		*va_arg(ap, uint16 **) = td->td_sampleinfo;
239 		return (1);
240 	case TIFFTAG_MATTEING:
241 		*va_arg(ap, uint16 *) =
242 		    (td->td_extrasamples == 1 &&
243 		     td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
244 		return (1);
245 	case TIFFTAG_TILEDEPTH:
246 		*va_arg(ap, uint32 *) = td->td_tiledepth;
247 		return (1);
248 	case TIFFTAG_DATATYPE:
249 		*va_arg(ap, uint16 *) = td->td_sampleformat-1;
250 		return (1);
251 	case TIFFTAG_SAMPLEFORMAT:
252 		*va_arg(ap, uint16 *) = td->td_sampleformat;
253                 return(1);
254 	case TIFFTAG_IMAGEDEPTH:
255 		*va_arg(ap, uint32 *) = td->td_imagedepth;
256 		return (1);
257 	case TIFFTAG_YCBCRCOEFFICIENTS:
258 		{
259 			/* defaults are from CCIR Recommendation 601-1 */
260 			static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
261 			*va_arg(ap, float **) = ycbcrcoeffs;
262 			return 1;
263 		}
264 	case TIFFTAG_YCBCRSUBSAMPLING:
265 		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
266 		*va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
267 		return (1);
268 	case TIFFTAG_YCBCRPOSITIONING:
269 		*va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
270 		return (1);
271 	case TIFFTAG_WHITEPOINT:
272 		{
273 			static float whitepoint[2];
274 
275 			/* TIFF 6.0 specification tells that it is no default
276 			   value for the WhitePoint, but AdobePhotoshop TIFF
277 			   Technical Note tells that it should be CIE D50. */
278 			whitepoint[0] =	D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
279 			whitepoint[1] =	D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
280 			*va_arg(ap, float **) = whitepoint;
281 			return 1;
282 		}
283 	case TIFFTAG_TRANSFERFUNCTION:
284 		if (!td->td_transferfunction[0] &&
285 		    !TIFFDefaultTransferFunction(td)) {
286 			TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
287 			return (0);
288 		}
289 		*va_arg(ap, uint16 **) = td->td_transferfunction[0];
290 		if (td->td_samplesperpixel - td->td_extrasamples > 1) {
291 			*va_arg(ap, uint16 **) = td->td_transferfunction[1];
292 			*va_arg(ap, uint16 **) = td->td_transferfunction[2];
293 		}
294 		return (1);
295 	case TIFFTAG_REFERENCEBLACKWHITE:
296 		if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
297 			return (0);
298 		*va_arg(ap, float **) = td->td_refblackwhite;
299 		return (1);
300 	}
301 	return 0;
302 }
303 
304 /*
305  * Like TIFFGetField, but return any default
306  * value if the tag is not present in the directory.
307  */
308 int
309 TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...)
310 {
311 	int ok;
312 	va_list ap;
313 
314 	va_start(ap, tag);
315 	ok =  TIFFVGetFieldDefaulted(tif, tag, ap);
316 	va_end(ap);
317 	return (ok);
318 }
319 
320 struct _Int64Parts {
321 	int32 low, high;
322 };
323 
324 typedef union {
325 	struct _Int64Parts part;
326 	int64 value;
327 } _Int64;
328 
329 float
330 _TIFFUInt64ToFloat(uint64 ui64)
331 {
332 	_Int64 i;
333 
334 	i.value = ui64;
335 	if (i.part.high >= 0) {
336 		return (float)i.value;
337 	} else {
338 		long double df;
339 		df = (long double)i.value;
340 		df += 18446744073709551616.0; /* adding 2**64 */
341 		return (float)df;
342 	}
343 }
344 
345 double
346 _TIFFUInt64ToDouble(uint64 ui64)
347 {
348 	_Int64 i;
349 
350 	i.value = ui64;
351 	if (i.part.high >= 0) {
352 		return (double)i.value;
353 	} else {
354 		long double df;
355 		df = (long double)i.value;
356 		df += 18446744073709551616.0; /* adding 2**64 */
357 		return (double)df;
358 	}
359 }
360 
361 int _TIFFSeekOK(TIFF* tif, toff_t off)
362 {
363     /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
364     /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
365     return off <= (~(uint64)0)/2 && TIFFSeekFile(tif,off,SEEK_SET)==off;
366 }
367 
368 /* vim: set ts=8 sts=8 sw=8 noet: */
369 /*
370  * Local Variables:
371  * mode: c
372  * c-basic-offset: 8
373  * fill-column: 78
374  * End:
375  */
376