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
32void _TIFFSetDefaultCompressionState(TIFF* tif);
33
34static 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};
49static 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};
64static 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 */
85static void
86TIFFInitOrder(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
100int
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
124TIFF*
125TIFFClientOpen(
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	}
383bad:
384	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
385	TIFFClose(tif);
386	return ((TIFF*)0);
387bad2:
388	(void) (*closeproc)(clientdata);
389bad3:
390	return ((TIFF*)0);
391}
392
393/*
394 * Query functions to access private data.
395 */
396
397/*
398 * Return open file's name.
399 */
400const char *
401TIFFFileName(TIFF* tif)
402{
403	return (tif->tif_name);
404}
405
406/*
407 * Return open file's I/O descriptor.
408 */
409int
410TIFFFileno(TIFF* tif)
411{
412	return (tif->tif_fd);
413}
414
415/*
416 * Return read/write mode.
417 */
418int
419TIFFGetMode(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 */
428int
429TIFFIsTiled(TIFF* tif)
430{
431	return (isTiled(tif));
432}
433
434/*
435 * Return current row being read/written.
436 */
437uint32
438TIFFCurrentRow(TIFF* tif)
439{
440	return (tif->tif_row);
441}
442
443/*
444 * Return index of the current directory.
445 */
446tdir_t
447TIFFCurrentDirectory(TIFF* tif)
448{
449	return (tif->tif_curdir);
450}
451
452/*
453 * Return current strip.
454 */
455tstrip_t
456TIFFCurrentStrip(TIFF* tif)
457{
458	return (tif->tif_curstrip);
459}
460
461/*
462 * Return current tile.
463 */
464ttile_t
465TIFFCurrentTile(TIFF* tif)
466{
467	return (tif->tif_curtile);
468}
469
470/*
471 * Return nonzero if the file has byte-swapped data.
472 */
473int
474TIFFIsByteSwapped(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 */
482int
483TIFFIsUpSampled(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 */
491int
492TIFFIsMSB2LSB(TIFF* tif)
493{
494	return (isFillOrder(tif, FILLORDER_MSB2LSB));
495}
496