diff -ru ../../tiff-3.7.2/libtiff/tif_dir.c ./tif_dir.c
--- ../../tiff-3.7.2/libtiff/tif_dir.c	2004-12-03 23:46:55.000000000 +1030
+++ ./tif_dir.c	2005-03-17 23:39:54.000000000 +1030
@@ -1334,6 +1334,24 @@
 }
 
 /*
+ * Set the current directory to be the IFD located at the specified
+ * file offset, but make no assumptions about its content beyond being
+ * an IFD with count, tags and tail pointer.  This may be used to read
+ * Exif or other private IFD's.
+ */
+int
+TIFFSetIFD(TIFF* tif, uint32 diroff)
+{
+	tif->tif_nextdiroff = diroff;
+	/*
+	 * Reset tif_dirnumber counter and start new list of seen directories.
+	 * We need this to prevent IFD loops.
+	 */
+	tif->tif_dirnumber = 0;
+	return (TIFFReadIFD(tif));
+}
+
+/*
  * Return file offset of the current directory.
  */
 uint32
diff -ru ../../tiff-3.7.2/libtiff/tif_dirinfo.c ./tif_dirinfo.c
--- ../../tiff-3.7.2/libtiff/tif_dirinfo.c	2004-11-11 21:52:04.000000000 +1030
+++ ./tif_dirinfo.c	2005-03-18 00:33:09.000000000 +1030
@@ -249,10 +249,16 @@
       FALSE,    TRUE,   "RichTIFFIPTC" },
     { TIFFTAG_PHOTOSHOP,    -1,-3, TIFF_BYTE,   FIELD_PHOTOSHOP, 
       FALSE,    TRUE,   "Photoshop" },
+    { TIFFTAG_EXIFIFD,		-1, -1, TIFF_LONG,	FIELD_CUSTOM,
+      TRUE,	TRUE,	"Exif IFD offset" },
     { TIFFTAG_ICCPROFILE,	-1,-3, TIFF_UNDEFINED,	FIELD_ICCPROFILE,
       FALSE,	TRUE,	"ICC Profile" },
+    { TIFFTAG_GPSIFD,		-1, -1, TIFF_LONG,	FIELD_CUSTOM,
+      TRUE,	TRUE,	"Exif GPS IFD" },
     { TIFFTAG_STONITS,		 1, 1, TIFF_DOUBLE,	FIELD_STONITS,
       FALSE,	FALSE,	"StoNits" },
+    { TIFFTAG_EXIFINTEROPIFD,	-1, -1, TIFF_LONG,	FIELD_CUSTOM,
+      TRUE,	TRUE,	"Exif Interoperability IFD" },
 };
 #define	N(a)	(sizeof (a) / sizeof (a[0]))
 
diff -ru ../../tiff-3.7.2/libtiff/tif_dirread.c ./tif_dirread.c
--- ../../tiff-3.7.2/libtiff/tif_dirread.c	2005-03-05 19:36:00.000000000 +1030
+++ ./tif_dirread.c	2005-03-18 00:21:45.000000000 +1030
@@ -686,6 +686,235 @@
 	return (0);
 }
 
+/*
+ * Read the next TIFF directory from a file, but make no assumptions
+ * about its content beyond being an IFD with count, tags and tail
+ * pointer.  This may be used to read an Exif or other private IFD.
+ * We read directories sequentially.
+ */
+int
+TIFFReadIFD(TIFF* tif)
+{
+	static const char module[] = "TIFFReadIFD";
+
+	register TIFFDirEntry* dp;
+	register int n;
+	register TIFFDirectory* td;
+	TIFFDirEntry* dir;
+	const TIFFFieldInfo* fip;
+	int fix;
+	uint16 dircount;
+	toff_t nextdiroff;
+	int diroutoforderwarning = 0;
+	toff_t* new_dirlist;
+
+	tif->tif_diroff = tif->tif_nextdiroff;
+	if (tif->tif_diroff == 0)		/* no more directories */
+		return (0);
+
+	/*
+	 * XXX: Trick to prevent IFD looping. The one can create TIFF file
+	 * with looped directory pointers. We will maintain a list of already
+	 * seen directories and check every IFD offset against this list.
+	 */
+	for (n = 0; n < tif->tif_dirnumber; n++) {
+		if (tif->tif_dirlist[n] == tif->tif_diroff)
+			return (0);
+	}
+	tif->tif_dirnumber++;
+	new_dirlist = _TIFFrealloc(tif->tif_dirlist,
+				   tif->tif_dirnumber * sizeof(toff_t));
+	if (!new_dirlist) {
+		TIFFError(module,
+			  "%s: Failed to allocate space for IFD list",
+			  tif->tif_name);
+		return (0);
+	}
+	tif->tif_dirlist = new_dirlist;
+	tif->tif_dirlist[tif->tif_dirnumber - 1] = tif->tif_diroff;
+
+	/*
+	 * Cleanup any previous compression state.
+	 */
+	(*tif->tif_cleanup)(tif);
+	tif->tif_curdir++;
+	nextdiroff = 0;
+	if (!isMapped(tif)) {
+		if (!SeekOK(tif, tif->tif_diroff)) {
+			TIFFError(module,
+			    "%s: Seek error accessing TIFF directory",
+                            tif->tif_name);
+			return (0);
+		}
+		if (!ReadOK(tif, &dircount, sizeof (uint16))) {
+			TIFFError(module,
+			    "%s: Can not read TIFF directory count",
+                            tif->tif_name);
+			return (0);
+		}
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabShort(&dircount);
+		dir = (TIFFDirEntry *)CheckMalloc(tif,
+						  dircount,
+						  sizeof (TIFFDirEntry),
+						  "to read TIFF directory");
+		if (dir == NULL)
+			return (0);
+		if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
+			TIFFError(module,
+                                  "%.100s: Can not read TIFF directory",
+                                  tif->tif_name);
+			goto bad;
+		}
+		/*
+		 * Read offset to next directory for sequential scans.
+		 */
+		(void) ReadOK(tif, &nextdiroff, sizeof (uint32));
+	} else {
+		toff_t off = tif->tif_diroff;
+
+		if (off + sizeof (uint16) > tif->tif_size) {
+			TIFFError(module,
+			    "%s: Can not read TIFF directory count",
+                            tif->tif_name);
+			return (0);
+		} else
+			_TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
+		off += sizeof (uint16);
+		if (tif->tif_flags & TIFF_SWAB)
+			TIFFSwabShort(&dircount);
+		dir = (TIFFDirEntry *)CheckMalloc(tif,
+		    dircount, sizeof (TIFFDirEntry), "to read TIFF directory");
+		if (dir == NULL)
+			return (0);
+		if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) {
+			TIFFError(module,
+                                  "%s: Can not read TIFF directory",
+                                  tif->tif_name);
+			goto bad;
+		} else {
+			_TIFFmemcpy(dir, tif->tif_base + off,
+				    dircount*sizeof (TIFFDirEntry));
+		}
+		off += dircount* sizeof (TIFFDirEntry);
+		if (off + sizeof (uint32) <= tif->tif_size)
+			_TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32));
+	}
+	if (tif->tif_flags & TIFF_SWAB)
+		TIFFSwabLong(&nextdiroff);
+	tif->tif_nextdiroff = nextdiroff;
+
+	tif->tif_flags &= ~TIFF_BEENWRITING;	/* reset before new dir */
+	td = &tif->tif_dir;
+	/* free any old stuff and reinit default values */
+	TIFFFreeDirectory(tif);
+	TIFFDefaultDirectory(tif);
+
+	/*
+	 * Read in the IFD tags.
+	 */
+	fix = 0;
+	for (dp = dir, n = dircount; n > 0; n--, dp++) {
+
+		if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
+			continue;
+
+		/*
+		 * Silicon Beach (at least) writes unordered
+		 * directory tags (violating the spec).  Handle
+		 * it here, but be obnoxious (maybe they'll fix it?).
+		 */
+		if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
+			if (!diroutoforderwarning) {
+				TIFFWarning(module,
+"%s: invalid TIFF directory; tags are not sorted in ascending order",
+                                            tif->tif_name);
+				diroutoforderwarning = 1;
+			}
+			fix = 0;			/* O(n^2) */
+		}
+		while (fix < tif->tif_nfields &&
+		       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
+			fix++;
+		if (fix >= tif->tif_nfields ||
+		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
+
+                    TIFFWarning(module,
+                        "%s: unknown field with tag %d (0x%x) encountered",
+                                tif->tif_name, dp->tdir_tag, dp->tdir_tag,
+                                dp->tdir_type);
+
+                    TIFFMergeFieldInfo( tif,
+                                        _TIFFCreateAnonFieldInfo( tif,
+                                              dp->tdir_tag,
+					      (TIFFDataType) dp->tdir_type ),
+                                        1 );
+                    fix = 0;
+                    while (fix < tif->tif_nfields &&
+                           tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
+			fix++;
+		}
+		/*
+		 * Null out old tags that we ignore.
+		 */
+		if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
+	ignore:
+			dp->tdir_tag = IGNORE;
+			continue;
+		}
+		/*
+		 * Check data type.
+		 */
+		fip = tif->tif_fieldinfo[fix];
+		while (dp->tdir_type != (unsigned short) fip->field_type
+                       && fix < tif->tif_nfields) {
+			if (fip->field_type == TIFF_ANY)	/* wildcard */
+				break;
+                        fip = tif->tif_fieldinfo[++fix];
+			if (fix >= tif->tif_nfields ||
+			    fip->field_tag != dp->tdir_tag) {
+				TIFFWarning(module,
+			"%s: wrong data type %d for \"%s\"; tag ignored",
+					    tif->tif_name, dp->tdir_type,
+					    tif->tif_fieldinfo[fix-1]->field_name);
+				goto ignore;
+			}
+		}
+		/*
+		 * Check count if known in advance.
+		 */
+		if (fip->field_readcount != TIFF_VARIABLE
+		    && fip->field_readcount != TIFF_VARIABLE2) {
+			uint32 expected = (fip->field_readcount == TIFF_SPP) ?
+			    (uint32) td->td_samplesperpixel :
+			    (uint32) fip->field_readcount;
+			if (!CheckDirCount(tif, dp, expected))
+				goto ignore;
+		}
+		(void) TIFFFetchNormalTag(tif, dp);
+	}
+
+	if (dir)
+		_TIFFfree(dir);
+
+	/*
+	 * Reinitialize i/o since we are starting on a new directory.
+	 */
+	tif->tif_row = (uint32) -1;
+	tif->tif_curstrip = (tstrip_t) -1;
+	tif->tif_col = (uint32) -1;
+	tif->tif_curtile = (ttile_t) -1;
+	tif->tif_tilesize = (tsize_t) -1;
+
+	tif->tif_scanlinesize = TIFFScanlineSize(tif);
+
+	return (1);
+bad:
+	if (dir)
+		_TIFFfree(dir);
+	return (0);
+}
+
 static int
 EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
 {
diff -ru ../../tiff-3.7.2/libtiff/tif_open.c ./tif_open.c
--- ../../tiff-3.7.2/libtiff/tif_open.c	2005-01-30 22:35:20.000000000 +1030
+++ ./tif_open.c	2005-03-17 18:01:18.000000000 +1030
@@ -136,7 +136,7 @@
 }
 
 TIFF*
-TIFFClientOpen(
+TIFFBasicOpen(
 	const char* name, const char* mode,
 	thandle_t clientdata,
 	TIFFReadWriteProc readproc,
@@ -148,7 +148,7 @@
 	TIFFUnmapFileProc unmapproc
 )
 {
-	static const char module[] = "TIFFClientOpen";
+	static const char module[] = "TIFFBasicOpen";
 	TIFF *tif;
 	int m, bigendian;
 	const char* cp;
@@ -362,17 +362,15 @@
 		TIFFError(name,
 		    "Not a TIFF file, bad version number %d (0x%x)",
 		    tif->tif_header.tiff_version,
-		    tif->tif_header.tiff_version); 
+		    tif->tif_header.tiff_version);
 		goto bad;
 	}
 	tif->tif_flags |= TIFF_MYBUFFER;
 	tif->tif_rawcp = tif->tif_rawdata = 0;
 	tif->tif_rawdatasize = 0;
-	/*
-	 * Setup initial directory.
-	 */
-	switch (mode[0]) {
-	case 'r':
+
+	if( mode[0] == 'r' )
+	{
 		tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
 		/*
 		 * Try to use a memory-mapped file if the client
@@ -380,8 +378,46 @@
 		 * 'm' flag in the open mode (see above).
 		 */
 		if ((tif->tif_flags & TIFF_MAPPED) &&
-	!TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
+		    !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base,
+					&tif->tif_size))
 			tif->tif_flags &= ~TIFF_MAPPED;
+	}
+	return tif;
+
+bad:
+	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
+        TIFFCleanup(tif);
+bad2:
+	return ((TIFF*)0);
+}
+
+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
+)
+{
+	TIFF *tif = TIFFBasicOpen( name, mode,
+				   clientdata,
+				   readproc,
+				   writeproc,
+				   seekproc,
+				   closeproc,
+				   sizeproc,
+				   mapproc,
+				   unmapproc );
+	/*
+	 * Setup initial directory.
+	 */
+	switch (mode[0]) {
+	case 'r':
 		if (TIFFReadDirectory(tif)) {
 			tif->tif_rawcc = -1;
 			tif->tif_flags |= TIFF_BUFFERSETUP;
@@ -394,14 +430,16 @@
 		 * to the end of the directory chain when they
 		 * are written out (see TIFFWriteDirectory).
 		 */
-		if (!TIFFDefaultDirectory(tif))
-			goto bad;
-		return (tif);
+		if (TIFFDefaultDirectory(tif))
+			return (tif);
+		break;
+	}
+
+	if( tif )
+	{
+		tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
+		TIFFCleanup(tif);
 	}
-bad:
-	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
-        TIFFCleanup(tif);
-bad2:
 	return ((TIFF*)0);
 }
 
diff -ru ../../tiff-3.7.2/libtiff/tiff.h ./tiff.h
--- ../../tiff-3.7.2/libtiff/tiff.h	2005-03-05 19:36:08.000000000 +1030
+++ ./tiff.h	2005-03-17 19:38:39.000000000 +1030
@@ -497,6 +497,12 @@
 #define TIFFTAG_CALIBRATIONILLUMINANT2	50779	/* &illuminant 2 */
 #define TIFFTAG_BESTQUALITYSCALE	50780	/* &best quality multiplier */
 
+/* tags defined by the Exif standard */
+#define TIFFTAG_EXIFIFD			34665	/* Exif IFD pointer */
+#define TIFFTAG_GPSIFD			34853	/* Exif GPS IFD pointer */
+#define TIFFTAG_EXIFINTEROPIFD		40965	/* Exif 'interoperability' */
+
+
 /*
  * The following are ``pseudo tags'' that can be used to control
  * codec-specific functionality.  These tags are not written to file.
diff -ru ../../tiff-3.7.2/libtiff/tiffio.h ./tiffio.h
--- ../../tiff-3.7.2/libtiff/tiffio.h	2005-02-04 20:23:01.000000000 +1030
+++ ./tiffio.h	2005-03-17 23:22:03.000000000 +1030
@@ -289,6 +289,7 @@
 extern	int TIFFGetFieldDefaulted(TIFF*, ttag_t, ...);
 extern	int TIFFVGetFieldDefaulted(TIFF*, ttag_t, va_list);
 extern	int TIFFReadDirectory(TIFF*);
+extern	int TIFFReadIFD(TIFF*);
 extern	tsize_t TIFFScanlineSize(TIFF*);
 extern	tsize_t TIFFRasterScanlineSize(TIFF*);
 extern	tsize_t TIFFStripSize(TIFF*);
@@ -331,6 +332,7 @@
 extern	int TIFFLastDirectory(TIFF*);
 extern	int TIFFSetDirectory(TIFF*, tdir_t);
 extern	int TIFFSetSubDirectory(TIFF*, uint32);
+extern	int TIFFSetIFD(TIFF*, uint32);
 extern	int TIFFUnlinkDirectory(TIFF*, tdir_t);
 extern	int TIFFSetField(TIFF*, ttag_t, ...);
 extern	int TIFFVSetField(TIFF*, ttag_t, va_list);
@@ -365,6 +367,12 @@
 extern	TIFF* TIFFOpenW(const wchar_t*, const char*);
 # endif /* __WIN32__ */
 extern	TIFF* TIFFFdOpen(int, const char*, const char*);
+extern	TIFF* TIFFBasicOpen(const char*, const char*,
+	    thandle_t,
+	    TIFFReadWriteProc, TIFFReadWriteProc,
+	    TIFFSeekProc, TIFFCloseProc,
+	    TIFFSizeProc,
+	    TIFFMapFileProc, TIFFUnmapFileProc);
 extern	TIFF* TIFFClientOpen(const char*, const char*,
 	    thandle_t,
 	    TIFFReadWriteProc, TIFFReadWriteProc,
