1/* $Id: tif_open.c 276 2010-06-30 12:18:30Z nijtmans $ */
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
32static const long typemask[13] = {
33	(long)0L,		/* TIFF_NOTYPE */
34	(long)0x000000ffL,	/* TIFF_BYTE */
35	(long)0xffffffffL,	/* TIFF_ASCII */
36	(long)0x0000ffffL,	/* TIFF_SHORT */
37	(long)0xffffffffL,	/* TIFF_LONG */
38	(long)0xffffffffL,	/* TIFF_RATIONAL */
39	(long)0x000000ffL,	/* TIFF_SBYTE */
40	(long)0x000000ffL,	/* TIFF_UNDEFINED */
41	(long)0x0000ffffL,	/* TIFF_SSHORT */
42	(long)0xffffffffL,	/* TIFF_SLONG */
43	(long)0xffffffffL,	/* TIFF_SRATIONAL */
44	(long)0xffffffffL,	/* TIFF_FLOAT */
45	(long)0xffffffffL,	/* TIFF_DOUBLE */
46};
47static const int bigTypeshift[13] = {
48	0,		/* TIFF_NOTYPE */
49	24,		/* TIFF_BYTE */
50	0,		/* TIFF_ASCII */
51	16,		/* TIFF_SHORT */
52	0,		/* TIFF_LONG */
53	0,		/* TIFF_RATIONAL */
54	24,		/* TIFF_SBYTE */
55	24,		/* TIFF_UNDEFINED */
56	16,		/* TIFF_SSHORT */
57	0,		/* TIFF_SLONG */
58	0,		/* TIFF_SRATIONAL */
59	0,		/* TIFF_FLOAT */
60	0,		/* TIFF_DOUBLE */
61};
62static const int litTypeshift[13] = {
63	0,		/* TIFF_NOTYPE */
64	0,		/* TIFF_BYTE */
65	0,		/* TIFF_ASCII */
66	0,		/* TIFF_SHORT */
67	0,		/* TIFF_LONG */
68	0,		/* TIFF_RATIONAL */
69	0,		/* TIFF_SBYTE */
70	0,		/* TIFF_UNDEFINED */
71	0,		/* TIFF_SSHORT */
72	0,		/* TIFF_SLONG */
73	0,		/* TIFF_SRATIONAL */
74	0,		/* TIFF_FLOAT */
75	0,		/* TIFF_DOUBLE */
76};
77
78/*
79 * Dummy functions to fill the omitted client procedures.
80 */
81static int
82_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
83{
84	(void) fd; (void) pbase; (void) psize;
85	return (0);
86}
87
88static void
89_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
90{
91	(void) fd; (void) base; (void) size;
92}
93
94/*
95 * Initialize the shift & mask tables, and the
96 * byte swapping state according to the file
97 * contents and the machine architecture.
98 */
99static void
100TIFFInitOrder(TIFF* tif, int magic)
101{
102	tif->tif_typemask = typemask;
103	if (magic == TIFF_BIGENDIAN) {
104		tif->tif_typeshift = bigTypeshift;
105#ifndef WORDS_BIGENDIAN
106		tif->tif_flags |= TIFF_SWAB;
107#endif
108	} else {
109		tif->tif_typeshift = litTypeshift;
110#ifdef WORDS_BIGENDIAN
111		tif->tif_flags |= TIFF_SWAB;
112#endif
113	}
114}
115
116int
117_TIFFgetMode(const char* mode, const char* module)
118{
119	int m = -1;
120
121	switch (mode[0]) {
122	case 'r':
123		m = O_RDONLY;
124		if (mode[1] == '+')
125			m = O_RDWR;
126		break;
127	case 'w':
128	case 'a':
129		m = O_RDWR|O_CREAT;
130		if (mode[0] == 'w')
131			m |= O_TRUNC;
132		break;
133	default:
134		TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
135		break;
136	}
137	return (m);
138}
139
140TIFF*
141TIFFClientOpen(
142	const char* name, const char* mode,
143	thandle_t clientdata,
144	TIFFReadWriteProc readproc,
145	TIFFReadWriteProc writeproc,
146	TIFFSeekProc seekproc,
147	TIFFCloseProc closeproc,
148	TIFFSizeProc sizeproc,
149	TIFFMapFileProc mapproc,
150	TIFFUnmapFileProc unmapproc
151)
152{
153	static const char module[] = "TIFFClientOpen";
154	TIFF *tif;
155	int m;
156	const char* cp;
157
158	m = _TIFFgetMode(mode, module);
159	if (m == -1)
160		goto bad2;
161	tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
162	if (tif == NULL) {
163		TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
164		goto bad2;
165	}
166	_TIFFmemset(tif, 0, sizeof (*tif));
167	tif->tif_name = (char *)tif + sizeof (TIFF);
168	strcpy(tif->tif_name, name);
169	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
170	tif->tif_curdir = (tdir_t) -1;		/* non-existent directory */
171	tif->tif_curoff = 0;
172	tif->tif_curstrip = (tstrip_t) -1;	/* invalid strip */
173	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
174	tif->tif_clientdata = clientdata;
175	if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
176		TIFFErrorExt(clientdata, module,
177			  "One of the client procedures is NULL pointer.");
178		goto bad2;
179	}
180	tif->tif_readproc = readproc;
181	tif->tif_writeproc = writeproc;
182	tif->tif_seekproc = seekproc;
183	tif->tif_closeproc = closeproc;
184	tif->tif_sizeproc = sizeproc;
185        if (mapproc)
186		tif->tif_mapproc = mapproc;
187	else
188		tif->tif_mapproc = _tiffDummyMapProc;
189	if (unmapproc)
190		tif->tif_unmapproc = unmapproc;
191	else
192		tif->tif_unmapproc = _tiffDummyUnmapProc;
193	_TIFFSetDefaultCompressionState(tif);	/* setup default state */
194	/*
195	 * Default is to return data MSB2LSB and enable the
196	 * use of memory-mapped files and strip chopping when
197	 * a file is opened read-only.
198	 */
199	tif->tif_flags = FILLORDER_MSB2LSB;
200	if (m == O_RDONLY )
201		tif->tif_flags |= TIFF_MAPPED;
202
203#ifdef STRIPCHOP_DEFAULT
204	if (m == O_RDONLY || m == O_RDWR)
205		tif->tif_flags |= STRIPCHOP_DEFAULT;
206#endif
207
208	/*
209	 * Process library-specific flags in the open mode string.
210	 * The following flags may be used to control intrinsic library
211	 * behaviour that may or may not be desirable (usually for
212	 * compatibility with some application that claims to support
213	 * TIFF but only supports some braindead idea of what the
214	 * vendor thinks TIFF is):
215	 *
216	 * 'l'		use little-endian byte order for creating a file
217	 * 'b'		use big-endian byte order for creating a file
218	 * 'L'		read/write information using LSB2MSB bit order
219	 * 'B'		read/write information using MSB2LSB bit order
220	 * 'H'		read/write information using host bit order
221	 * 'M'		enable use of memory-mapped files when supported
222	 * 'm'		disable use of memory-mapped files
223	 * 'C'		enable strip chopping support when reading
224	 * 'c'		disable strip chopping support
225	 * 'h'		read TIFF header only, do not load the first IFD
226	 *
227	 * The use of the 'l' and 'b' flags is strongly discouraged.
228	 * These flags are provided solely because numerous vendors,
229	 * typically on the PC, do not correctly support TIFF; they
230	 * only support the Intel little-endian byte order.  This
231	 * support is not configured by default because it supports
232	 * the violation of the TIFF spec that says that readers *MUST*
233	 * support both byte orders.  It is strongly recommended that
234	 * you not use this feature except to deal with busted apps
235	 * that write invalid TIFF.  And even in those cases you should
236	 * bang on the vendors to fix their software.
237	 *
238	 * The 'L', 'B', and 'H' flags are intended for applications
239	 * that can optimize operations on data by using a particular
240	 * bit order.  By default the library returns data in MSB2LSB
241	 * bit order for compatibiltiy with older versions of this
242	 * library.  Returning data in the bit order of the native cpu
243	 * makes the most sense but also requires applications to check
244	 * the value of the FillOrder tag; something they probably do
245	 * not do right now.
246	 *
247	 * The 'M' and 'm' flags are provided because some virtual memory
248	 * systems exhibit poor behaviour when large images are mapped.
249	 * These options permit clients to control the use of memory-mapped
250	 * files on a per-file basis.
251	 *
252	 * The 'C' and 'c' flags are provided because the library support
253	 * for chopping up large strips into multiple smaller strips is not
254	 * application-transparent and as such can cause problems.  The 'c'
255	 * option permits applications that only want to look at the tags,
256	 * for example, to get the unadulterated TIFF tag information.
257	 */
258	for (cp = mode; *cp; cp++)
259		switch (*cp) {
260		case 'b':
261#ifndef WORDS_BIGENDIAN
262		    if (m&O_CREAT)
263				tif->tif_flags |= TIFF_SWAB;
264#endif
265			break;
266		case 'l':
267#ifdef WORDS_BIGENDIAN
268			if ((m&O_CREAT))
269				tif->tif_flags |= TIFF_SWAB;
270#endif
271			break;
272		case 'B':
273			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
274			    FILLORDER_MSB2LSB;
275			break;
276		case 'L':
277			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
278			    FILLORDER_LSB2MSB;
279			break;
280		case 'H':
281			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
282			    HOST_FILLORDER;
283			break;
284		case 'M':
285			if (m == O_RDONLY)
286				tif->tif_flags |= TIFF_MAPPED;
287			break;
288		case 'm':
289			if (m == O_RDONLY)
290				tif->tif_flags &= ~TIFF_MAPPED;
291			break;
292		case 'C':
293			if (m == O_RDONLY)
294				tif->tif_flags |= TIFF_STRIPCHOP;
295			break;
296		case 'c':
297			if (m == O_RDONLY)
298				tif->tif_flags &= ~TIFF_STRIPCHOP;
299			break;
300		case 'h':
301			tif->tif_flags |= TIFF_HEADERONLY;
302			break;
303		}
304	/*
305	 * Read in TIFF header.
306	 */
307	if (tif->tif_mode & O_TRUNC ||
308	    !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
309		if (tif->tif_mode == O_RDONLY) {
310			TIFFErrorExt(tif->tif_clientdata, name,
311				     "Cannot read TIFF header");
312			goto bad;
313		}
314		/*
315		 * Setup header and write.
316		 */
317#ifdef WORDS_BIGENDIAN
318		tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
319		    ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
320#else
321		tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
322		    ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
323#endif
324		tif->tif_header.tiff_version = TIFF_VERSION;
325		if (tif->tif_flags & TIFF_SWAB)
326			TIFFSwabShort(&tif->tif_header.tiff_version);
327		tif->tif_header.tiff_diroff = 0;	/* filled in later */
328
329
330                /*
331                 * The doc for "fopen" for some STD_C_LIBs says that if you
332                 * open a file for modify ("+"), then you must fseek (or
333                 * fflush?) between any freads and fwrites.  This is not
334                 * necessary on most systems, but has been shown to be needed
335                 * on Solaris.
336                 */
337                TIFFSeekFile( tif, 0, SEEK_SET );
338
339		if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
340			TIFFErrorExt(tif->tif_clientdata, name,
341				     "Error writing TIFF header");
342			goto bad;
343		}
344		/*
345		 * Setup the byte order handling.
346		 */
347		TIFFInitOrder(tif, tif->tif_header.tiff_magic);
348		/*
349		 * Setup default directory.
350		 */
351		if (!TIFFDefaultDirectory(tif))
352			goto bad;
353		tif->tif_diroff = 0;
354		tif->tif_dirlist = NULL;
355		tif->tif_dirlistsize = 0;
356		tif->tif_dirnumber = 0;
357		return (tif);
358	}
359	/*
360	 * Setup the byte order handling.
361	 */
362	if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
363	    tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN
364#if MDI_SUPPORT
365	    &&
366#if HOST_BIGENDIAN
367	    tif->tif_header.tiff_magic != MDI_BIGENDIAN
368#else
369	    tif->tif_header.tiff_magic != MDI_LITTLEENDIAN
370#endif
371	    ) {
372		TIFFErrorExt(tif->tif_clientdata, name,
373			"Not a TIFF or MDI file, bad magic number %d (0x%x)",
374#else
375	    ) {
376		TIFFErrorExt(tif->tif_clientdata, name,
377			     "Not a TIFF file, bad magic number %d (0x%x)",
378#endif
379		    tif->tif_header.tiff_magic,
380		    tif->tif_header.tiff_magic);
381		goto bad;
382	}
383	TIFFInitOrder(tif, tif->tif_header.tiff_magic);
384	/*
385	 * Swap header if required.
386	 */
387	if (tif->tif_flags & TIFF_SWAB) {
388		TIFFSwabShort(&tif->tif_header.tiff_version);
389		TIFFSwabLong(&tif->tif_header.tiff_diroff);
390	}
391	/*
392	 * Now check version (if needed, it's been byte-swapped).
393	 * Note that this isn't actually a version number, it's a
394	 * magic number that doesn't change (stupid).
395	 */
396	if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) {
397		TIFFErrorExt(tif->tif_clientdata, name,
398                          "This is a BigTIFF file.  This format not supported\n"
399                          "by this version of libtiff." );
400		goto bad;
401	}
402	if (tif->tif_header.tiff_version != TIFF_VERSION) {
403		TIFFErrorExt(tif->tif_clientdata, name,
404		    "Not a TIFF file, bad version number %d (0x%x)",
405		    tif->tif_header.tiff_version,
406		    tif->tif_header.tiff_version);
407		goto bad;
408	}
409	tif->tif_flags |= TIFF_MYBUFFER;
410	tif->tif_rawcp = tif->tif_rawdata = 0;
411	tif->tif_rawdatasize = 0;
412
413	/*
414	 * Sometimes we do not want to read the first directory (for example,
415	 * it may be broken) and want to proceed to other directories. I this
416	 * case we use the TIFF_HEADERONLY flag to open file and return
417	 * immediately after reading TIFF header.
418	 */
419	if (tif->tif_flags & TIFF_HEADERONLY)
420		return (tif);
421
422	/*
423	 * Setup initial directory.
424	 */
425	switch (mode[0]) {
426	case 'r':
427		tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
428		/*
429		 * Try to use a memory-mapped file if the client
430		 * has not explicitly suppressed usage with the
431		 * 'm' flag in the open mode (see above).
432		 */
433		if ((tif->tif_flags & TIFF_MAPPED) &&
434	!TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
435			tif->tif_flags &= ~TIFF_MAPPED;
436		if (TIFFReadDirectory(tif)) {
437			tif->tif_rawcc = -1;
438			tif->tif_flags |= TIFF_BUFFERSETUP;
439			return (tif);
440		}
441		break;
442	case 'a':
443		/*
444		 * New directories are automatically append
445		 * to the end of the directory chain when they
446		 * are written out (see TIFFWriteDirectory).
447		 */
448		if (!TIFFDefaultDirectory(tif))
449			goto bad;
450		return (tif);
451	}
452bad:
453	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
454        TIFFCleanup(tif);
455bad2:
456	return ((TIFF*)0);
457}
458
459/*
460 * Query functions to access private data.
461 */
462
463/*
464 * Return open file's name.
465 */
466const char *
467TIFFFileName(TIFF* tif)
468{
469	return (tif->tif_name);
470}
471
472/*
473 * Set the file name.
474 */
475const char *
476TIFFSetFileName(TIFF* tif, const char *name)
477{
478	const char* old_name = tif->tif_name;
479	tif->tif_name = (char *)name;
480	return (old_name);
481}
482
483/*
484 * Return open file's I/O descriptor.
485 */
486int
487TIFFFileno(TIFF* tif)
488{
489	return (tif->tif_fd);
490}
491
492/*
493 * Set open file's I/O descriptor, and return previous value.
494 */
495int
496TIFFSetFileno(TIFF* tif, int fd)
497{
498        int old_fd = tif->tif_fd;
499	tif->tif_fd = fd;
500	return old_fd;
501}
502
503/*
504 * Return open file's clientdata.
505 */
506thandle_t
507TIFFClientdata(TIFF* tif)
508{
509	return (tif->tif_clientdata);
510}
511
512/*
513 * Set open file's clientdata, and return previous value.
514 */
515thandle_t
516TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
517{
518	thandle_t m = tif->tif_clientdata;
519	tif->tif_clientdata = newvalue;
520	return m;
521}
522
523/*
524 * Return read/write mode.
525 */
526int
527TIFFGetMode(TIFF* tif)
528{
529	return (tif->tif_mode);
530}
531
532/*
533 * Return read/write mode.
534 */
535int
536TIFFSetMode(TIFF* tif, int mode)
537{
538	int old_mode = tif->tif_mode;
539	tif->tif_mode = mode;
540	return (old_mode);
541}
542
543/*
544 * Return nonzero if file is organized in
545 * tiles; zero if organized as strips.
546 */
547int
548TIFFIsTiled(TIFF* tif)
549{
550	return (isTiled(tif));
551}
552
553/*
554 * Return current row being read/written.
555 */
556uint32
557TIFFCurrentRow(TIFF* tif)
558{
559	return (tif->tif_row);
560}
561
562/*
563 * Return index of the current directory.
564 */
565tdir_t
566TIFFCurrentDirectory(TIFF* tif)
567{
568	return (tif->tif_curdir);
569}
570
571/*
572 * Return current strip.
573 */
574tstrip_t
575TIFFCurrentStrip(TIFF* tif)
576{
577	return (tif->tif_curstrip);
578}
579
580/*
581 * Return current tile.
582 */
583ttile_t
584TIFFCurrentTile(TIFF* tif)
585{
586	return (tif->tif_curtile);
587}
588
589/*
590 * Return nonzero if the file has byte-swapped data.
591 */
592int
593TIFFIsByteSwapped(TIFF* tif)
594{
595	return ((tif->tif_flags & TIFF_SWAB) != 0);
596}
597
598/*
599 * Return nonzero if the data is returned up-sampled.
600 */
601int
602TIFFIsUpSampled(TIFF* tif)
603{
604	return (isUpSampled(tif));
605}
606
607/*
608 * Return nonzero if the data is returned in MSB-to-LSB bit order.
609 */
610int
611TIFFIsMSB2LSB(TIFF* tif)
612{
613	return (isFillOrder(tif, FILLORDER_MSB2LSB));
614}
615
616/*
617 * Return nonzero if given file was written in big-endian order.
618 */
619int
620TIFFIsBigEndian(TIFF* tif)
621{
622	return (tif->tif_header.tiff_magic == TIFF_BIGENDIAN);
623}
624
625/*
626 * Return pointer to file read method.
627 */
628TIFFReadWriteProc
629TIFFGetReadProc(TIFF* tif)
630{
631	return (tif->tif_readproc);
632}
633
634/*
635 * Return pointer to file write method.
636 */
637TIFFReadWriteProc
638TIFFGetWriteProc(TIFF* tif)
639{
640	return (tif->tif_writeproc);
641}
642
643/*
644 * Return pointer to file seek method.
645 */
646TIFFSeekProc
647TIFFGetSeekProc(TIFF* tif)
648{
649	return (tif->tif_seekproc);
650}
651
652/*
653 * Return pointer to file close method.
654 */
655TIFFCloseProc
656TIFFGetCloseProc(TIFF* tif)
657{
658	return (tif->tif_closeproc);
659}
660
661/*
662 * Return pointer to file size requesting method.
663 */
664TIFFSizeProc
665TIFFGetSizeProc(TIFF* tif)
666{
667	return (tif->tif_sizeproc);
668}
669
670/*
671 * Return pointer to memory mapping method.
672 */
673TIFFMapFileProc
674TIFFGetMapFileProc(TIFF* tif)
675{
676	return (tif->tif_mapproc);
677}
678
679/*
680 * Return pointer to memory unmapping method.
681 */
682TIFFUnmapFileProc
683TIFFGetUnmapFileProc(TIFF* tif)
684{
685	return (tif->tif_unmapproc);
686}
687
688/* vim: set ts=8 sts=8 sw=8 noet: */
689/*
690 * Local Variables:
691 * mode: c
692 * c-basic-offset: 8
693 * fill-column: 78
694 * End:
695 */
696