1 /* $Header$ */
2 
3 /*
4  * Copyright (c) 1988-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 #include "tiffiop.h"
31 
32 void _TIFFSetDefaultCompressionState(TIFF* tif);
33 
34 static const long typemask[13] = {
35 	(long)0L,		/* TIFF_NOTYPE */
36 	(long)0x000000ffL,	/* TIFF_BYTE */
37 	(long)0xffffffffL,	/* TIFF_ASCII */
38 	(long)0x0000ffffL,	/* TIFF_SHORT */
39 	(long)0xffffffffL,	/* TIFF_LONG */
40 	(long)0xffffffffL,	/* TIFF_RATIONAL */
41 	(long)0x000000ffL,	/* TIFF_SBYTE */
42 	(long)0x000000ffL,	/* TIFF_UNDEFINED */
43 	(long)0x0000ffffL,	/* TIFF_SSHORT */
44 	(long)0xffffffffL,	/* TIFF_SLONG */
45 	(long)0xffffffffL,	/* TIFF_SRATIONAL */
46 	(long)0xffffffffL,	/* TIFF_FLOAT */
47 	(long)0xffffffffL,	/* TIFF_DOUBLE */
48 };
49 static const int bigTypeshift[13] = {
50 	0,		/* TIFF_NOTYPE */
51 	24,		/* TIFF_BYTE */
52 	0,		/* TIFF_ASCII */
53 	16,		/* TIFF_SHORT */
54 	0,		/* TIFF_LONG */
55 	0,		/* TIFF_RATIONAL */
56 	24,		/* TIFF_SBYTE */
57 	24,		/* TIFF_UNDEFINED */
58 	16,		/* TIFF_SSHORT */
59 	0,		/* TIFF_SLONG */
60 	0,		/* TIFF_SRATIONAL */
61 	0,		/* TIFF_FLOAT */
62 	0,		/* TIFF_DOUBLE */
63 };
64 static const int litTypeshift[13] = {
65 	0,		/* TIFF_NOTYPE */
66 	0,		/* TIFF_BYTE */
67 	0,		/* TIFF_ASCII */
68 	0,		/* TIFF_SHORT */
69 	0,		/* TIFF_LONG */
70 	0,		/* TIFF_RATIONAL */
71 	0,		/* TIFF_SBYTE */
72 	0,		/* TIFF_UNDEFINED */
73 	0,		/* TIFF_SSHORT */
74 	0,		/* TIFF_SLONG */
75 	0,		/* TIFF_SRATIONAL */
76 	0,		/* TIFF_FLOAT */
77 	0,		/* TIFF_DOUBLE */
78 };
79 
80 /*
81  * Initialize the shift & mask tables, and the
82  * byte swapping state according to the file
83  * contents and the machine architecture.
84  */
85 static void
TIFFInitOrder(TIFF * tif,int magic,int bigendian)86 TIFFInitOrder(TIFF* tif, int magic, int bigendian)
87 {
88 	tif->tif_typemask = typemask;
89 	if (magic == TIFF_BIGENDIAN) {
90 		tif->tif_typeshift = bigTypeshift;
91 		if (!bigendian)
92 			tif->tif_flags |= TIFF_SWAB;
93 	} else {
94 		tif->tif_typeshift = litTypeshift;
95 		if (bigendian)
96 			tif->tif_flags |= TIFF_SWAB;
97 	}
98 }
99 
100 int
_TIFFgetMode(const char * mode,const char * module)101 _TIFFgetMode(const char* mode, const char* module)
102 {
103 	int m = -1;
104 
105 	switch (mode[0]) {
106 	case 'r':
107 		m = O_RDONLY;
108 		if (mode[1] == '+')
109 			m = O_RDWR;
110 		break;
111 	case 'w':
112 	case 'a':
113 		m = O_RDWR|O_CREAT;
114 		if (mode[0] == 'w')
115 			m |= O_TRUNC;
116 		break;
117 	default:
118 		TIFFError(module, "\"%s\": Bad mode", mode);
119 		break;
120 	}
121 	return (m);
122 }
123 
124 TIFF*
TIFFClientOpen(const char * name,const char * mode,thandle_t clientdata,TIFFReadWriteProc readproc,TIFFReadWriteProc writeproc,TIFFSeekProc seekproc,TIFFCloseProc closeproc,TIFFSizeProc sizeproc,TIFFMapFileProc mapproc,TIFFUnmapFileProc unmapproc)125 TIFFClientOpen(
126 	const char* name, const char* mode,
127 	thandle_t clientdata,
128 	TIFFReadWriteProc readproc,
129 	TIFFReadWriteProc writeproc,
130 	TIFFSeekProc seekproc,
131 	TIFFCloseProc closeproc,
132 	TIFFSizeProc sizeproc,
133 	TIFFMapFileProc mapproc,
134 	TIFFUnmapFileProc unmapproc
135 )
136 {
137 	static const char module[] = "TIFFClientOpen";
138 	TIFF *tif;
139 	int m, bigendian;
140 	const char* cp;
141 
142 	m = _TIFFgetMode(mode, module);
143 	if (m == -1)
144 		goto bad2;
145 	tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
146 	if (tif == NULL) {
147 		TIFFError(module, "%s: Out of memory (TIFF structure)", name);
148 		goto bad2;
149 	}
150 	_TIFFmemset(tif, 0, sizeof (*tif));
151 	tif->tif_name = (char *)tif + sizeof (TIFF);
152 	strcpy(tif->tif_name, name);
153 	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
154 	tif->tif_curdir = (tdir_t) -1;		/* non-existent directory */
155 	tif->tif_curoff = 0;
156 	tif->tif_curstrip = (tstrip_t) -1;	/* invalid strip */
157 	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
158 	tif->tif_clientdata = clientdata;
159 	if (!readproc || !writeproc || !seekproc || !closeproc
160 			|| !sizeproc || !mapproc || !unmapproc) {
161 		TIFFError(module, "One of the client procedures are NULL pointer");
162 		goto bad3;
163 	}
164 	tif->tif_readproc = readproc;
165 	tif->tif_writeproc = writeproc;
166 	tif->tif_seekproc = seekproc;
167 	tif->tif_closeproc = closeproc;
168 	tif->tif_sizeproc = sizeproc;
169 	tif->tif_mapproc = mapproc;
170 	tif->tif_unmapproc = unmapproc;
171 	_TIFFSetDefaultCompressionState(tif);	/* setup default state */
172 	/*
173 	 * Default is to return data MSB2LSB and enable the
174 	 * use of memory-mapped files and strip chopping when
175 	 * a file is opened read-only.
176 	 */
177 	tif->tif_flags = FILLORDER_MSB2LSB;
178 	if (m == O_RDONLY )
179             tif->tif_flags |= TIFF_MAPPED;
180 
181 #ifdef STRIPCHOP_DEFAULT
182 	if (m == O_RDONLY || m == O_RDWR)
183 		tif->tif_flags |= STRIPCHOP_DEFAULT;
184 #endif
185 
186 	{ union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; }
187 	/*
188 	 * Process library-specific flags in the open mode string.
189 	 * The following flags may be used to control intrinsic library
190 	 * behaviour that may or may not be desirable (usually for
191 	 * compatibility with some application that claims to support
192 	 * TIFF but only supports some braindead idea of what the
193 	 * vendor thinks TIFF is):
194 	 *
195 	 * 'l'		use little-endian byte order for creating a file
196 	 * 'b'		use big-endian byte order for creating a file
197 	 * 'L'		read/write information using LSB2MSB bit order
198 	 * 'B'		read/write information using MSB2LSB bit order
199 	 * 'H'		read/write information using host bit order
200 	 * 'M'		enable use of memory-mapped files when supported
201 	 * 'm'		disable use of memory-mapped files
202 	 * 'C'		enable strip chopping support when reading
203 	 * 'c'		disable strip chopping support
204 	 *
205 	 * The use of the 'l' and 'b' flags is strongly discouraged.
206 	 * These flags are provided solely because numerous vendors,
207 	 * typically on the PC, do not correctly support TIFF; they
208 	 * only support the Intel little-endian byte order.  This
209 	 * support is not configured by default because it supports
210 	 * the violation of the TIFF spec that says that readers *MUST*
211 	 * support both byte orders.  It is strongly recommended that
212 	 * you not use this feature except to deal with busted apps
213 	 * that write invalid TIFF.  And even in those cases you should
214 	 * bang on the vendors to fix their software.
215 	 *
216 	 * The 'L', 'B', and 'H' flags are intended for applications
217 	 * that can optimize operations on data by using a particular
218 	 * bit order.  By default the library returns data in MSB2LSB
219 	 * bit order for compatibility with older versions of this
220 	 * library.  Returning data in the bit order of the native cpu
221 	 * makes the most sense but also requires applications to check
222 	 * the value of the FillOrder tag; something they probabyl do
223 	 * not do right now.
224 	 *
225 	 * The 'M' and 'm' flags are provided because some virtual memory
226 	 * systems exhibit poor behaviour when large images are mapped.
227 	 * These options permit clients to control the use of memory-mapped
228 	 * files on a per-file basis.
229 	 *
230 	 * The 'C' and 'c' flags are provided because the library support
231 	 * for chopping up large strips into multiple smaller strips is not
232 	 * application-transparent and as such can cause problems.  The 'c'
233 	 * option permits applications that only want to look at the tags,
234 	 * for example, to get the unadulterated TIFF tag information.
235 	 */
236 	for (cp = mode; *cp; cp++)
237 		switch (*cp) {
238 		case 'b':
239 			if ((m&O_CREAT) && !bigendian)
240 				tif->tif_flags |= TIFF_SWAB;
241 			break;
242 		case 'l':
243 			if ((m&O_CREAT) && bigendian)
244 				tif->tif_flags |= TIFF_SWAB;
245 			break;
246 		case 'B':
247 			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
248 			    FILLORDER_MSB2LSB;
249 			break;
250 		case 'L':
251 			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
252 			    FILLORDER_LSB2MSB;
253 			break;
254 		case 'H':
255 			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
256 			    HOST_FILLORDER;
257 			break;
258 		case 'M':
259 			if (m == O_RDONLY)
260 				tif->tif_flags |= TIFF_MAPPED;
261 			break;
262 		case 'm':
263 			if (m == O_RDONLY)
264 				tif->tif_flags &= ~TIFF_MAPPED;
265 			break;
266 		case 'C':
267 			if (m == O_RDONLY)
268 				tif->tif_flags |= TIFF_STRIPCHOP;
269 			break;
270 		case 'c':
271 			if (m == O_RDONLY)
272 				tif->tif_flags &= ~TIFF_STRIPCHOP;
273 			break;
274 		}
275 	/*
276 	 * Read in TIFF header.
277 	 */
278 	if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
279 		if (tif->tif_mode == O_RDONLY) {
280 			TIFFError(name, "Cannot read TIFF header");
281 			goto bad;
282 		}
283 		/*
284 		 * Setup header and write.
285 		 */
286 		tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
287 		    ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN)
288 		    : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN);
289 		tif->tif_header.tiff_version = TIFF_VERSION;
290 		if (tif->tif_flags & TIFF_SWAB)
291 			TIFFSwabShort(&tif->tif_header.tiff_version);
292 		tif->tif_header.tiff_diroff = 0;	/* filled in later */
293 
294                 /*
295                  * This seek shouldn't be necessary, but I have had some
296                  * crazy problems with a failed fseek() on Solaris leaving
297                  * the current file pointer out of whack when an fwrite()
298                  * is done.
299                  */
300                 TIFFSeekFile( tif, 0, SEEK_SET );
301 
302 		if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
303 			TIFFError(name, "Error writing TIFF header");
304 			goto bad;
305 		}
306 		/*
307 		 * Setup the byte order handling.
308 		 */
309 		TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
310 		/*
311 		 * Setup default directory.
312 		 */
313 		if (!TIFFDefaultDirectory(tif))
314 			goto bad;
315 		tif->tif_diroff = 0;
316 		tif->tif_dirlist = NULL;
317 		tif->tif_dirnumber = 0;
318 		return (tif);
319 	}
320 	/*
321 	 * Setup the byte order handling.
322 	 */
323 	if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
324 	    tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
325 		TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
326 		    tif->tif_header.tiff_magic,
327 		    tif->tif_header.tiff_magic);
328 		goto bad;
329 	}
330 	TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
331 	/*
332 	 * Swap header if required.
333 	 */
334 	if (tif->tif_flags & TIFF_SWAB) {
335 		TIFFSwabShort(&tif->tif_header.tiff_version);
336 		TIFFSwabLong(&tif->tif_header.tiff_diroff);
337 	}
338 	/*
339 	 * Now check version (if needed, it's been byte-swapped).
340 	 * Note that this isn't actually a version number, it's a
341 	 * magic number that doesn't change (stupid).
342 	 */
343 	if (tif->tif_header.tiff_version != TIFF_VERSION) {
344 		TIFFError(name,
345 		    "Not a TIFF file, bad version number %d (0x%x)",
346 		    tif->tif_header.tiff_version,
347 		    tif->tif_header.tiff_version);
348 		goto bad;
349 	}
350 	tif->tif_flags |= TIFF_MYBUFFER;
351 	tif->tif_rawcp = tif->tif_rawdata = 0;
352 	tif->tif_rawdatasize = 0;
353 	/*
354 	 * Setup initial directory.
355 	 */
356 	switch (mode[0]) {
357 	case 'r':
358 		tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
359 		/*
360 		 * Try to use a memory-mapped file if the client
361 		 * has not explicitly suppressed usage with the
362 		 * 'm' flag in the open mode (see above).
363 		 */
364 		if ((tif->tif_flags & TIFF_MAPPED) &&
365 	!TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
366 			tif->tif_flags &= ~TIFF_MAPPED;
367 		if (TIFFReadDirectory(tif)) {
368 			tif->tif_rawcc = -1;
369 			tif->tif_flags |= TIFF_BUFFERSETUP;
370 			return (tif);
371 		}
372 		break;
373 	case 'a':
374 		/*
375 		 * New directories are automatically append
376 		 * to the end of the directory chain when they
377 		 * are written out (see TIFFWriteDirectory).
378 		 */
379 		if (!TIFFDefaultDirectory(tif))
380 			goto bad;
381 		return (tif);
382 	}
383 bad:
384 	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
385 	TIFFClose(tif);
386 	return ((TIFF*)0);
387 bad2:
388 	(void) (*closeproc)(clientdata);
389 bad3:
390 	return ((TIFF*)0);
391 }
392 
393 /*
394  * Query functions to access private data.
395  */
396 
397 /*
398  * Return open file's name.
399  */
400 const char *
TIFFFileName(TIFF * tif)401 TIFFFileName(TIFF* tif)
402 {
403 	return (tif->tif_name);
404 }
405 
406 /*
407  * Return open file's I/O descriptor.
408  */
409 int
TIFFFileno(TIFF * tif)410 TIFFFileno(TIFF* tif)
411 {
412 	return (tif->tif_fd);
413 }
414 
415 /*
416  * Return read/write mode.
417  */
418 int
TIFFGetMode(TIFF * tif)419 TIFFGetMode(TIFF* tif)
420 {
421 	return (tif->tif_mode);
422 }
423 
424 /*
425  * Return nonzero if file is organized in
426  * tiles; zero if organized as strips.
427  */
428 int
TIFFIsTiled(TIFF * tif)429 TIFFIsTiled(TIFF* tif)
430 {
431 	return (isTiled(tif));
432 }
433 
434 /*
435  * Return current row being read/written.
436  */
437 uint32
TIFFCurrentRow(TIFF * tif)438 TIFFCurrentRow(TIFF* tif)
439 {
440 	return (tif->tif_row);
441 }
442 
443 /*
444  * Return index of the current directory.
445  */
446 tdir_t
TIFFCurrentDirectory(TIFF * tif)447 TIFFCurrentDirectory(TIFF* tif)
448 {
449 	return (tif->tif_curdir);
450 }
451 
452 /*
453  * Return current strip.
454  */
455 tstrip_t
TIFFCurrentStrip(TIFF * tif)456 TIFFCurrentStrip(TIFF* tif)
457 {
458 	return (tif->tif_curstrip);
459 }
460 
461 /*
462  * Return current tile.
463  */
464 ttile_t
TIFFCurrentTile(TIFF * tif)465 TIFFCurrentTile(TIFF* tif)
466 {
467 	return (tif->tif_curtile);
468 }
469 
470 /*
471  * Return nonzero if the file has byte-swapped data.
472  */
473 int
TIFFIsByteSwapped(TIFF * tif)474 TIFFIsByteSwapped(TIFF* tif)
475 {
476 	return ((tif->tif_flags & TIFF_SWAB) != 0);
477 }
478 
479 /*
480  * Return nonzero if the data is returned up-sampled.
481  */
482 int
TIFFIsUpSampled(TIFF * tif)483 TIFFIsUpSampled(TIFF* tif)
484 {
485 	return (isUpSampled(tif));
486 }
487 
488 /*
489  * Return nonzero if the data is returned in MSB-to-LSB bit order.
490  */
491 int
TIFFIsMSB2LSB(TIFF * tif)492 TIFFIsMSB2LSB(TIFF* tif)
493 {
494 	return (isFillOrder(tif, FILLORDER_MSB2LSB));
495 }
496