static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
+static void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
* handle overwriting a directory with auxiliary
* storage that's been changed.
*/
-int
-TIFFWriteDirectory(TIFF* tif)
+static int
+_TIFFWriteDirectory(TIFF* tif, int done)
{
uint16 dircount;
- uint32 diroff;
+ toff_t diroff;
ttag_t tag;
uint32 nfields;
tsize_t dirsize;
* different characteristics get the right buffers
* setup for them.
*/
- if (tif->tif_flags & TIFF_POSTENCODE) {
- tif->tif_flags &= ~TIFF_POSTENCODE;
- if (!(*tif->tif_postencode)(tif)) {
- TIFFError(tif->tif_name,
- "Error post-encoding before directory write");
- return (0);
- }
+ if (done)
+ {
+ if (tif->tif_flags & TIFF_POSTENCODE) {
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ if (!(*tif->tif_postencode)(tif)) {
+ TIFFError(tif->tif_name,
+ "Error post-encoding before directory write");
+ return (0);
+ }
+ }
+ (*tif->tif_close)(tif); /* shutdown encoder */
+ /*
+ * Flush any data that might have been written
+ * by the compression close+cleanup routines.
+ */
+ if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
+ TIFFError(tif->tif_name,
+ "Error flushing data before directory write");
+ return (0);
+ }
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawcc = 0;
+ tif->tif_rawdatasize = 0;
+ }
+ tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
}
- (*tif->tif_close)(tif); /* shutdown encoder */
- /*
- * Flush any data that might have been written
- * by the compression close+cleanup routines.
- */
- if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
- TIFFError(tif->tif_name,
- "Error flushing data before directory write");
- return (0);
- }
- if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
- _TIFFfree(tif->tif_rawdata);
- tif->tif_rawdata = NULL;
- tif->tif_rawcc = 0;
- }
- tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
td = &tif->tif_dir;
/*
*/
nfields = 0;
for (b = 0; b <= FIELD_LAST; b++)
- if (TIFFFieldSet(tif, b))
+ if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
+ nfields += td->td_customValueCount;
dirsize = nfields * sizeof (TIFFDirEntry);
data = (char*) _TIFFmalloc(dirsize);
if (data == NULL) {
} /*XXX*/
for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
- if (!FieldSet(fields, fip->field_bit))
- continue;
- switch (fip->field_bit) {
+
+ /*
+ ** For custom fields, we test to see if the custom field
+ ** is set or not. For normal fields, we just use the
+ ** FieldSet test.
+ */
+ if( fip->field_bit == FIELD_CUSTOM )
+ {
+ int ci, is_set = FALSE;
+
+ for( ci = 0; ci < td->td_customValueCount; ci++ )
+ is_set |= (td->td_customValues[ci].info == fip);
+
+ if( !is_set )
+ continue;
+ }
+ else if (!FieldSet(fields, fip->field_bit))
+ continue;
+
+
+ /*
+ ** Handle other fields.
+ */
+ switch (fip->field_bit)
+ {
case FIELD_STRIPOFFSETS:
/*
* We use one field bit for both strip and tile
+
* offsets, and so must be careful in selecting
* the appropriate field descriptor (so that tags
* are written in sorted order).
TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
dir, td->td_tilelength);
break;
+ case FIELD_COMPRESSION:
+ TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
+ dir, td->td_compression);
+ break;
+ case FIELD_PHOTOMETRIC:
+ TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
+ dir, td->td_photometric);
+ break;
case FIELD_POSITION:
WriteRationalPair(TIFF_RATIONAL,
TIFFTAG_XPOSITION, td->td_xposition,
*/
if (dir->tdir_count > 0) {
tif->tif_flags |= TIFF_INSUBIFD;
- tif->tif_nsubifd = dir->tdir_count;
+ tif->tif_nsubifd = (uint16) dir->tdir_count;
if (dir->tdir_count > 1)
tif->tif_subifdoff = dir->tdir_offset;
else
break;
}
dir++;
- ResetFieldBit(fields, fip->field_bit);
+
+ if( fip->field_bit != FIELD_CUSTOM )
+ ResetFieldBit(fields, fip->field_bit);
}
+
/*
* Write directory.
*/
TIFFError(tif->tif_name, "Error writing directory link");
goto bad;
}
- TIFFFreeDirectory(tif);
- _TIFFfree(data);
- tif->tif_flags &= ~TIFF_DIRTYDIRECT;
- (*tif->tif_cleanup)(tif);
+ if (done) {
+ TIFFFreeDirectory(tif);
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+ (*tif->tif_cleanup)(tif);
- /*
- * Reset directory-related state for subsequent
- * directories.
- */
- TIFFDefaultDirectory(tif);
- tif->tif_diroff = 0;
- tif->tif_curoff = 0;
- tif->tif_row = (uint32) -1;
- tif->tif_curstrip = (tstrip_t) -1;
+ /*
+ * Reset directory-related state for subsequent
+ * directories.
+ */
+ TIFFCreateDirectory(tif);
+ }
+ _TIFFfree(data);
return (1);
bad:
_TIFFfree(data);
}
#undef WriteRationalPair
+int
+TIFFWriteDirectory(TIFF* tif)
+{
+ return _TIFFWriteDirectory(tif, TRUE);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), writes the directory out
+ * but leaves all data structures in memory so that it can be
+ * written again. This will make a partially written TIFF file
+ * readable before it is successfully completed/closed.
+ */
+int
+TIFFCheckpointDirectory(TIFF* tif)
+{
+ int rc;
+ /* Setup the strips arrays, if they haven't already been. */
+ if (tif->tif_dir.td_stripoffset == NULL)
+ (void) TIFFSetupStrips(tif);
+ rc = _TIFFWriteDirectory(tif, FALSE);
+ (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
+ return rc;
+}
+
/*
* Process tags that are not special cased.
*/
u_short wc = (u_short) fip->field_writecount;
uint32 wc2;
- dir->tdir_tag = fip->field_tag;
+ dir->tdir_tag = (uint16) fip->field_tag;
dir->tdir_type = (u_short) fip->field_type;
dir->tdir_count = wc;
#define WRITEF(x,y) x(tif, fip->field_type, fip->field_tag, dir, wc, y)
case TIFF_SSHORT:
if (wc > 1) {
uint16* wp;
- if (wc == (u_short) TIFF_VARIABLE)
+ if (wc == (u_short) TIFF_VARIABLE
+ || fip->field_passcount)
TIFFGetField(tif, fip->field_tag, &wc, &wp);
else
TIFFGetField(tif, fip->field_tag, &wp);
if (!WRITEF(TIFFWriteShortArray, wp))
return (0);
} else {
- uint16 sv;
- TIFFGetField(tif, fip->field_tag, &sv);
- dir->tdir_offset =
- TIFFInsertData(tif, dir->tdir_type, sv);
+ if (fip->field_passcount) {
+ uint16* wp;
+ TIFFGetField(tif, fip->field_tag, &wc, &wp);
+ if (!WRITEF(TIFFWriteShortArray, wp))
+ return 0;
+ } else {
+ uint16 sv;
+ TIFFGetField(tif, fip->field_tag, &sv);
+ dir->tdir_offset =
+ TIFFInsertData(tif, dir->tdir_type, sv);
+ }
}
break;
case TIFF_LONG:
case TIFF_SLONG:
+ case TIFF_IFD:
if (wc > 1) {
uint32* lp;
- if (wc == (u_short) TIFF_VARIABLE)
+ if (wc == (u_short) TIFF_VARIABLE
+ || fip->field_passcount)
TIFFGetField(tif, fip->field_tag, &wc, &lp);
else
TIFFGetField(tif, fip->field_tag, &lp);
if (!WRITEF(TIFFWriteLongArray, lp))
return (0);
} else {
- /* XXX handle LONG->SHORT conversion */
- TIFFGetField(tif, fip->field_tag, &dir->tdir_offset);
+ if (fip->field_passcount) {
+ uint32* lp;
+ TIFFGetField(tif, fip->field_tag, &wc, &lp);
+ if (!WRITEF(TIFFWriteLongArray, lp))
+ return 0;
+ } else {
+ /* XXX handle LONG->SHORT conversion */
+ TIFFGetField(tif, fip->field_tag,
+ &dir->tdir_offset);
+ }
}
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
if (wc > 1) {
float* fp;
- if (wc == (u_short) TIFF_VARIABLE)
+ if (wc == (u_short) TIFF_VARIABLE
+ || fip->field_passcount)
TIFFGetField(tif, fip->field_tag, &wc, &fp);
else
TIFFGetField(tif, fip->field_tag, &fp);
if (!WRITEF(TIFFWriteRationalArray, fp))
return (0);
} else {
- float fv;
- TIFFGetField(tif, fip->field_tag, &fv);
- if (!WRITEF(TIFFWriteRationalArray, &fv))
- return (0);
+ if (fip->field_passcount) {
+ float* fp;
+ TIFFGetField(tif, fip->field_tag, &wc, &fp);
+ if (!WRITEF(TIFFWriteRationalArray, fp))
+ return 0;
+ } else {
+ float fv;
+ TIFFGetField(tif, fip->field_tag, &fv);
+ if (!WRITEF(TIFFWriteRationalArray, &fv))
+ return (0);
+ }
}
break;
case TIFF_FLOAT:
if (wc > 1) {
float* fp;
- if (wc == (u_short) TIFF_VARIABLE)
+ if (wc == (u_short) TIFF_VARIABLE
+ || fip->field_passcount)
TIFFGetField(tif, fip->field_tag, &wc, &fp);
else
TIFFGetField(tif, fip->field_tag, &fp);
if (!WRITEF(TIFFWriteFloatArray, fp))
return (0);
} else {
- float fv;
- TIFFGetField(tif, fip->field_tag, &fv);
- if (!WRITEF(TIFFWriteFloatArray, &fv))
- return (0);
+ if (fip->field_passcount) {
+ float* fp;
+ TIFFGetField(tif, fip->field_tag, &wc, &fp);
+ if (!WRITEF(TIFFWriteFloatArray, fp))
+ return 0;
+ } else {
+ float fv;
+ TIFFGetField(tif, fip->field_tag, &fv);
+ if (!WRITEF(TIFFWriteFloatArray, &fv))
+ return (0);
+ }
}
break;
case TIFF_DOUBLE:
if (wc > 1) {
double* dp;
- if (wc == (u_short) TIFF_VARIABLE)
+ if (wc == (u_short) TIFF_VARIABLE
+ || fip->field_passcount)
TIFFGetField(tif, fip->field_tag, &wc, &dp);
else
TIFFGetField(tif, fip->field_tag, &dp);
if (!WRITEF(TIFFWriteDoubleArray, dp))
return (0);
} else {
- double dv;
- TIFFGetField(tif, fip->field_tag, &dv);
- if (!WRITEF(TIFFWriteDoubleArray, &dv))
- return (0);
+ if (fip->field_passcount) {
+ double* dp;
+ TIFFGetField(tif, fip->field_tag, &wc, &dp);
+ if (!WRITEF(TIFFWriteDoubleArray, dp))
+ return 0;
+ } else {
+ double dv;
+ TIFFGetField(tif, fip->field_tag, &dv);
+ if (!WRITEF(TIFFWriteDoubleArray, &dv))
+ return (0);
+ }
}
break;
case TIFF_ASCII:
correctness not verified (FW, 99/08) */
case TIFF_BYTE:
case TIFF_SBYTE:
- if (wc > 1) {
- char* cp;
- if (wc == (u_short) TIFF_VARIABLE) {
- TIFFGetField(tif, fip->field_tag, &wc, &cp);
- dir->tdir_count = wc;
- } else
- TIFFGetField(tif, fip->field_tag, &cp);
- if (!TIFFWriteByteArray(tif, dir, cp))
- return (0);
+ if (wc > 1) {
+ char* cp;
+ if (wc == (u_short) TIFF_VARIABLE
+ || fip->field_passcount) {
+ TIFFGetField(tif, fip->field_tag, &wc, &cp);
+ dir->tdir_count = wc;
+ } else if (wc == (u_short) TIFF_VARIABLE2) {
+ TIFFGetField(tif, fip->field_tag, &wc2, &cp);
+ dir->tdir_count = wc2;
+ } else
+ TIFFGetField(tif, fip->field_tag, &cp);
+ if (!TIFFWriteByteArray(tif, dir, cp))
+ return (0);
} else {
- char cv;
- TIFFGetField(tif, fip->field_tag, &cv);
- if (!TIFFWriteByteArray(tif, dir, &cv))
- return (0);
+ if (fip->field_passcount) {
+ char* cp;
+ TIFFGetField(tif, fip->field_tag, &wc, &cp);
+ dir->tdir_count = wc;
+ if (!TIFFWriteByteArray(tif, dir, cp))
+ return 0;
+ } else {
+ char cv;
+ TIFFGetField(tif, fip->field_tag, &cv);
+ if (!TIFFWriteByteArray(tif, dir, &cv))
+ return (0);
+ }
}
break;
static void
TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
{
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_count = 1;
if (v > 0xffffL) {
dir->tdir_type = (short) TIFF_LONG;
dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
}
}
+
+/*
+ * Setup a SHORT directory entry
+ */
+static void
+TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
+{
+ dir->tdir_tag = (uint16) tag;
+ dir->tdir_count = 1;
+ dir->tdir_type = (short) TIFF_SHORT;
+ dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
+}
#undef MakeShortDirent
#ifndef TIFFWriteRational
uint16* w = buf;
int i, status, samples = tif->tif_dir.td_samplesperpixel;
- if (samples > NITEMS(buf))
+ if (samples > NITEMS(buf)) {
w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
+ if (w == NULL) {
+ TIFFError(tif->tif_name,
+ "No space to write per-sample shorts");
+ return (0);
+ }
+ }
TIFFGetField(tif, tag, &v);
for (i = 0; i < samples; i++)
w[i] = v;
int i, status;
int samples = (int) tif->tif_dir.td_samplesperpixel;
- if (samples > NITEMS(buf))
+ if (samples > NITEMS(buf)) {
w = (double*) _TIFFmalloc(samples * sizeof (double));
+ if (w == NULL) {
+ TIFFError(tif->tif_name,
+ "No space to write per-sample values");
+ return (0);
+ }
+ }
TIFFGetField(tif, tag, &v);
for (i = 0; i < samples; i++)
w[i] = v;
{
uint32 i, off;
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) TIFF_SHORT;
/* XXX -- yech, fool TIFFWriteData */
dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
TIFFWriteShortArray(TIFF* tif,
TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v)
{
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
if (n <= 2) {
TIFFWriteLongArray(TIFF* tif,
TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v)
{
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
if (n == 1) {
uint32* t;
int status;
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32));
+ if (t == NULL) {
+ TIFFError(tif->tif_name,
+ "No space to write RATIONAL array");
+ return (0);
+ }
for (i = 0; i < n; i++) {
float fv = v[i];
int sign = 1;
while (fv < 1L<<(31-3) && den < 1L<<(31-3))
fv *= 1<<3, den *= 1L<<3;
}
- t[2*i+0] = sign * (fv + 0.5);
+ t[2*i+0] = (uint32) (sign * (fv + 0.5));
t[2*i+1] = den;
}
status = TIFFWriteData(tif, dir, (char *)t);
TIFFWriteFloatArray(TIFF* tif,
TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
{
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
TIFFCvtNativeToIEEEFloat(tif, n, v);
TIFFWriteDoubleArray(TIFF* tif,
TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
{
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
TIFFCvtNativeToIEEEDouble(tif, n, v);
char* w = buf;
int i, status = 0;
- if (n * tiffDataWidth[type] > sizeof buf)
- w = (char*) _TIFFmalloc(n * tiffDataWidth[type]);
+ if (n * TIFFDataWidth(type) > sizeof buf) {
+ w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
+ if (w == NULL) {
+ TIFFError(tif->tif_name,
+ "No space to write array");
+ return (0);
+ }
+ }
switch (type) {
case TIFF_BYTE:
{ uint8* bp = (uint8*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (uint8) v[i];
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
if (!TIFFWriteByteArray(tif, dir, (char*) bp))
break;
case TIFF_SBYTE:
{ int8* bp = (int8*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (int8) v[i];
- dir->tdir_tag = tag;
+ dir->tdir_tag = (uint16) tag;
dir->tdir_type = (short) type;
dir->tdir_count = n;
if (!TIFFWriteByteArray(tif, dir, (char*) bp))
break;
case TIFF_SHORT:
{ uint16* bp = (uint16*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (uint16) v[i];
if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
goto out;
break;
case TIFF_SSHORT:
{ int16* bp = (int16*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (int16) v[i];
if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
goto out;
break;
case TIFF_LONG:
{ uint32* bp = (uint32*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (uint32) v[i];
if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp))
goto out;
break;
case TIFF_SLONG:
{ int32* bp = (int32*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (int32) v[i];
if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp))
goto out;
break;
case TIFF_FLOAT:
{ float* bp = (float*) w;
- for (i = 0; i < n; i++)
+ for (i = 0; i < (int) n; i++)
bp[i] = (float) v[i];
if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp))
goto out;
}
}
dir->tdir_offset = tif->tif_dataoff;
- cc = dir->tdir_count * tiffDataWidth[dir->tdir_type];
+ cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
if (SeekOK(tif, dir->tdir_offset) &&
WriteOK(tif, cp, cc)) {
tif->tif_dataoff += (cc + 1) & ~1;
return (0);
}
+/*
+ * Similar to TIFFWriteDirectory(), but if the directory has already
+ * been written once, it is relocated to the end of the file, in case it
+ * has changed in size. Note that this will result in the loss of the
+ * previously used directory space.
+ */
+
+int
+TIFFRewriteDirectory( TIFF *tif )
+{
+ static const char module[] = "TIFFRewriteDirectory";
+
+ /* We don't need to do anything special if it hasn't been written. */
+ if( tif->tif_diroff == 0 )
+ return TIFFWriteDirectory( tif );
+
+ /*
+ ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
+ ** will cause it to be added after this directories current pre-link.
+ */
+
+ /* Is it the first directory in the file? */
+ if (tif->tif_header.tiff_diroff == tif->tif_diroff)
+ {
+ tif->tif_header.tiff_diroff = 0;
+ tif->tif_diroff = 0;
+
+#if defined(__hpux) && defined(__LP64__)
+#define HDROFF(f) ((toff_t)(unsigned long) &(((TIFFHeader*) 0)->f))
+#else
+#define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f))
+#endif
+ TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET);
+ if (!WriteOK(tif, &(tif->tif_header.tiff_diroff),
+ sizeof (tif->tif_diroff)))
+ {
+ TIFFError(tif->tif_name, "Error updating TIFF header");
+ return (0);
+ }
+ }
+ else
+ {
+ toff_t nextdir, off;
+
+ nextdir = tif->tif_header.tiff_diroff;
+ do {
+ uint16 dircount;
+
+ if (!SeekOK(tif, nextdir) ||
+ !ReadOK(tif, &dircount, sizeof (dircount))) {
+ TIFFError(module, "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ (void) TIFFSeekFile(tif,
+ dircount * sizeof (TIFFDirEntry), SEEK_CUR);
+ if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
+ TIFFError(module, "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir);
+ } while (nextdir != tif->tif_diroff && nextdir != 0);
+ off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
+ (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
+ tif->tif_diroff = 0;
+ if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
+ TIFFError(module, "Error writing directory link");
+ return (0);
+ }
+ }
+
+ /*
+ ** Now use TIFFWriteDirectory() normally.
+ */
+
+ return TIFFWriteDirectory( tif );
+}
+
+
/*
* Link the current directory into the
* directory chain for the file.
TIFFLinkDirectory(TIFF* tif)
{
static const char module[] = "TIFFLinkDirectory";
- uint32 nextdir;
- uint32 diroff;
+ toff_t nextdir;
+ toff_t diroff, off;
tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
- diroff = (uint32) tif->tif_diroff;
+ diroff = tif->tif_diroff;
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong(&diroff);
#if SUBIFD_SUPPORT
/*
* First directory, overwrite offset in header.
*/
- tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff;
+ tif->tif_header.tiff_diroff = tif->tif_diroff;
#define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f))
(void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET);
if (!WriteOK(tif, &diroff, sizeof (diroff))) {
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong(&nextdir);
} while (nextdir != 0);
- (void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR);
+ off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
+ (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
if (!WriteOK(tif, &diroff, sizeof (diroff))) {
TIFFError(module, "Error writing directory link");
return (0);