From dc65ed605ac168b3e3bc1f2cb12e2f14601a45d4 Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Sat, 30 Oct 2004 17:07:01 +0000 Subject: [PATCH] Improvements in tag writing code. --- libtiff/tif_dirwrite.c | 375 ++++++++++++++++++++--------------------- 1 file changed, 183 insertions(+), 192 deletions(-) diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c index 578b6ada..be66e116 100644 --- a/libtiff/tif_dirwrite.c +++ b/libtiff/tif_dirwrite.c @@ -1,4 +1,4 @@ -/* $Id: tif_dirwrite.c,v 1.25 2004-10-29 10:15:13 dron Exp $ */ +/* $Id: tif_dirwrite.c,v 1.26 2004-10-30 17:07:01 dron Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler @@ -46,16 +46,11 @@ static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*); static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*); static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*); static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**); -static int TIFFWriteShortArray(TIFF*, - TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*); -static int TIFFWriteLongArray(TIFF *, - TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*); -static int TIFFWriteRationalArray(TIFF *, - TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); -static int TIFFWriteFloatArray(TIFF *, - TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); -static int TIFFWriteDoubleArray(TIFF *, - TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); +static int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*); +static int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*); +static int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*); +static int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*); +static int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*); static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*); static int TIFFWriteAnyArray(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); @@ -65,18 +60,16 @@ static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*); static int TIFFLinkDirectory(TIFF*); #define WriteRationalPair(type, tag1, v1, tag2, v2) { \ - if (!TIFFWriteRational(tif, type, tag1, dir, v1)) \ - goto bad; \ - if (!TIFFWriteRational(tif, type, tag2, dir+1, v2)) \ - goto bad; \ - dir++; \ + TIFFWriteRational((tif), (type), (tag1), (dir), (v1)) \ + TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \ + (dir)++; \ } -#define TIFFWriteRational(tif, type, tag, dir, v) \ - TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v)) -#ifndef TIFFWriteRational -static int TIFFWriteRational(TIFF*, - TIFFDataType, ttag_t, TIFFDirEntry*, float); -#endif +#define TIFFWriteRational(tif, type, tag, dir, v) \ + (dir)->tdir_tag = (tag); \ + (dir)->tdir_type = (type); \ + (dir)->tdir_count = 1; \ + if (!TIFFWriteRationalArray((tif), (dir), &(v))) \ + goto bad; /* * Write the contents of the current directory @@ -219,8 +212,11 @@ _TIFFWriteDirectory(TIFF* tif, int done) TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS; if (tag != fip->field_tag) continue; - if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir, - (uint32) td->td_nstrips, td->td_stripoffset)) + + dir->tdir_tag = (uint16) tag; + dir->tdir_type = (uint16) TIFF_LONG; + dir->tdir_count = (uint32) td->td_nstrips; + if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset)) goto bad; break; case FIELD_STRIPBYTECOUNTS: @@ -234,8 +230,12 @@ _TIFFWriteDirectory(TIFF* tif, int done) TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS; if (tag != fip->field_tag) continue; - if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir, - (uint32) td->td_nstrips, td->td_stripbytecount)) + + dir->tdir_tag = (uint16) tag; + dir->tdir_type = (uint16) TIFF_LONG; + dir->tdir_count = (uint32) td->td_nstrips; + if (!TIFFWriteLongArray(tif, dir, + td->td_stripbytecount)) goto bad; break; case FIELD_ROWSPERSTRIP: @@ -429,130 +429,140 @@ TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) uint32 wc2; dir->tdir_tag = (uint16) fip->field_tag; - dir->tdir_type = (unsigned short) fip->field_type; + dir->tdir_type = (uint16) fip->field_type; dir->tdir_count = wc; -#define WRITEF(x,y) x(tif, fip->field_type, fip->field_tag, dir, wc, y) + switch (fip->field_type) { case TIFF_SHORT: case TIFF_SSHORT: - if (wc > 1) { + if (fip->field_passcount) { uint16* wp; - if (wc == (unsigned short) TIFF_VARIABLE - || fip->field_passcount) + if (wc == (uint16) TIFF_VARIABLE2) { + TIFFGetField(tif, fip->field_tag, &wc2, &wp); + dir->tdir_count = wc2; + } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &wp); - else - TIFFGetField(tif, fip->field_tag, &wp); - if (!WRITEF(TIFFWriteShortArray, wp)) - return (0); + dir->tdir_count = wc; + } + if (!TIFFWriteShortArray(tif, dir, wp)) + return 0; } else { - if (fip->field_passcount) { - uint16* wp; - TIFFGetField(tif, fip->field_tag, &wc, &wp); - if (!WRITEF(TIFFWriteShortArray, wp)) - return 0; - } else { + if (wc == 1) { uint16 sv; TIFFGetField(tif, fip->field_tag, &sv); dir->tdir_offset = TIFFInsertData(tif, dir->tdir_type, sv); + } else { + uint16* wp; + TIFFGetField(tif, fip->field_tag, &wp); + if (!TIFFWriteShortArray(tif, dir, wp)) + return 0; } } break; case TIFF_LONG: case TIFF_SLONG: case TIFF_IFD: - if (wc > 1) { + if (fip->field_passcount) { uint32* lp; - if (wc == (unsigned short) TIFF_VARIABLE - || fip->field_passcount) + if (wc == (uint16) TIFF_VARIABLE2) { + TIFFGetField(tif, fip->field_tag, &wc2, &lp); + dir->tdir_count = wc2; + } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &lp); - else - TIFFGetField(tif, fip->field_tag, &lp); - if (!WRITEF(TIFFWriteLongArray, lp)) - return (0); + dir->tdir_count = wc; + } + if (!TIFFWriteLongArray(tif, dir, lp)) + return 0; } else { - if (fip->field_passcount) { - uint32* lp; - TIFFGetField(tif, fip->field_tag, &wc, &lp); - if (!WRITEF(TIFFWriteLongArray, lp)) - return 0; - } else { + if (wc == 1) { /* XXX handle LONG->SHORT conversion */ TIFFGetField(tif, fip->field_tag, &dir->tdir_offset); + } else { + uint32* lp; + TIFFGetField(tif, fip->field_tag, &lp); + if (!TIFFWriteLongArray(tif, dir, lp)) + return 0; } } break; case TIFF_RATIONAL: case TIFF_SRATIONAL: - if (wc > 1) { + if (fip->field_passcount) { float* fp; - if (wc == (unsigned short) TIFF_VARIABLE - || fip->field_passcount) + if (wc == (uint16) TIFF_VARIABLE2) { + TIFFGetField(tif, fip->field_tag, &wc2, &fp); + dir->tdir_count = wc2; + } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &fp); - else - TIFFGetField(tif, fip->field_tag, &fp); - if (!WRITEF(TIFFWriteRationalArray, fp)) - return (0); + dir->tdir_count = wc; + } + if (!TIFFWriteRationalArray(tif, dir, fp)) + return 0; } else { - if (fip->field_passcount) { - float* fp; - TIFFGetField(tif, fip->field_tag, &wc, &fp); - if (!WRITEF(TIFFWriteRationalArray, fp)) - return 0; - } else { + if (wc == 1) { float fv; TIFFGetField(tif, fip->field_tag, &fv); - if (!WRITEF(TIFFWriteRationalArray, &fv)) - return (0); + if (!TIFFWriteRationalArray(tif, dir, &fv)) + return 0; + } else { + float* fp; + TIFFGetField(tif, fip->field_tag, &fp); + if (!TIFFWriteRationalArray(tif, dir, fp)) + return 0; } } break; case TIFF_FLOAT: - if (wc > 1) { + if (fip->field_passcount) { float* fp; - if (wc == (unsigned short) TIFF_VARIABLE - || fip->field_passcount) + if (wc == (uint16) TIFF_VARIABLE2) { + TIFFGetField(tif, fip->field_tag, &wc2, &fp); + dir->tdir_count = wc2; + } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &fp); - else - TIFFGetField(tif, fip->field_tag, &fp); - if (!WRITEF(TIFFWriteFloatArray, fp)) - return (0); + dir->tdir_count = wc; + } + if (!TIFFWriteFloatArray(tif, dir, fp)) + return 0; } else { - if (fip->field_passcount) { - float* fp; - TIFFGetField(tif, fip->field_tag, &wc, &fp); - if (!WRITEF(TIFFWriteFloatArray, fp)) - return 0; - } else { + if (wc == 1) { float fv; TIFFGetField(tif, fip->field_tag, &fv); - if (!WRITEF(TIFFWriteFloatArray, &fv)) - return (0); + if (!TIFFWriteFloatArray(tif, dir, &fv)) + return 0; + } else { + float* fp; + TIFFGetField(tif, fip->field_tag, &fp); + if (!TIFFWriteFloatArray(tif, dir, fp)) + return 0; } } break; case TIFF_DOUBLE: - if (wc > 1) { + if (fip->field_passcount) { double* dp; - if (wc == (unsigned short) TIFF_VARIABLE - || fip->field_passcount) + if (wc == (uint16) TIFF_VARIABLE2) { + TIFFGetField(tif, fip->field_tag, &wc2, &dp); + dir->tdir_count = wc2; + } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &dp); - else - TIFFGetField(tif, fip->field_tag, &dp); - if (!WRITEF(TIFFWriteDoubleArray, dp)) - return (0); + dir->tdir_count = wc; + } + if (!TIFFWriteDoubleArray(tif, dir, dp)) + return 0; } else { - if (fip->field_passcount) { - double* dp; - TIFFGetField(tif, fip->field_tag, &wc, &dp); - if (!WRITEF(TIFFWriteDoubleArray, dp)) - return 0; - } else { + if (wc == 1) { double dv; TIFFGetField(tif, fip->field_tag, &dv); - if (!WRITEF(TIFFWriteDoubleArray, &dv)) - return (0); + if (!TIFFWriteDoubleArray(tif, dir, &dv)) + return 0; + } else { + double* dp; + TIFFGetField(tif, fip->field_tag, &dp); + if (!TIFFWriteDoubleArray(tif, dir, dp)) + return 0; } } break; @@ -577,7 +587,7 @@ TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) if (wc == (uint16) TIFF_VARIABLE2) { TIFFGetField(tif, fip->field_tag, &wc2, &cp); dir->tdir_count = wc2; - } else { + } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &cp); dir->tdir_count = wc; } @@ -618,7 +628,6 @@ TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) } return (1); } -#undef WRITEF /* * Setup a directory entry with either a SHORT @@ -651,19 +660,6 @@ TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v) } #undef MakeShortDirent -#ifndef TIFFWriteRational -/* - * Setup a RATIONAL directory entry and - * write the associated indirect value. - */ -static int -TIFFWriteRational(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v) -{ - return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v)); -} -#endif - #define NITEMS(x) (sizeof (x) / sizeof (x[0])) /* * Setup a directory entry that references a @@ -689,7 +685,11 @@ TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) TIFFGetField(tif, tag, &v); for (i = 0; i < samples; i++) w[i] = v; - status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w); + + dir->tdir_tag = (uint16) tag; + dir->tdir_type = (uint16) TIFF_SHORT; + dir->tdir_count = samples; + status = TIFFWriteShortArray(tif, dir, w); if (w != buf) _TIFFfree((char*) w); return (status); @@ -737,7 +737,11 @@ TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) uint16 v[2]; TIFFGetField(tif, tag, &v[0], &v[1]); - return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v)); + + dir->tdir_tag = (uint16) tag; + dir->tdir_type = (uint16) TIFF_SHORT; + dir->tdir_count = 2; + return (TIFFWriteShortArray(tif, dir, v)); } /* @@ -783,20 +787,16 @@ TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) * or SSHORT and write the associated indirect values. */ static int -TIFFWriteShortArray(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v) +TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) { - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; - if (n <= 2) { + if (dir->tdir_count <= 2) { if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { dir->tdir_offset = (uint32) ((long) v[0] << 16); - if (n == 2) + if (dir->tdir_count == 2) dir->tdir_offset |= v[1] & 0xffff; } else { dir->tdir_offset = v[0] & 0xffff; - if (n == 2) + if (dir->tdir_count == 2) dir->tdir_offset |= (long) v[1] << 16; } return (1); @@ -809,13 +809,9 @@ TIFFWriteShortArray(TIFF* tif, * or SLONG and write the associated indirect values. */ static int -TIFFWriteLongArray(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v) +TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) { - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; - if (n == 1) { + if (dir->tdir_count == 1) { dir->tdir_offset = v[0]; return (1); } else @@ -827,32 +823,29 @@ TIFFWriteLongArray(TIFF* tif, * or SRATIONAL and write the associated indirect values. */ static int -TIFFWriteRationalArray(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) +TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) { uint32 i; uint32* t; int status; - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; - t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32)); + t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32)); if (t == NULL) { TIFFError(tif->tif_name, "No space to write RATIONAL array"); return (0); } - for (i = 0; i < n; i++) { + for (i = 0; i < dir->tdir_count; i++) { float fv = v[i]; int sign = 1; uint32 den; if (fv < 0) { - if (type == TIFF_RATIONAL) { + if (dir->tdir_type == TIFF_RATIONAL) { TIFFWarning(tif->tif_name, "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", - _TIFFFieldWithTag(tif,tag)->field_name, fv); + _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name, + fv); fv = 0; } else fv = -fv, sign = -1; @@ -871,14 +864,10 @@ TIFFWriteRationalArray(TIFF* tif, } static int -TIFFWriteFloatArray(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) +TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) { - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; - TIFFCvtNativeToIEEEFloat(tif, n, v); - if (n == 1) { + TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v); + if (dir->tdir_count == 1) { dir->tdir_offset = *(uint32*) &v[0]; return (1); } else @@ -886,12 +875,8 @@ TIFFWriteFloatArray(TIFF* tif, } static int -TIFFWriteDoubleArray(TIFF* tif, - TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) +TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) { - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; TIFFCvtNativeToIEEEDouble(tif, n, v); return (TIFFWriteData(tif, dir, (char*) v)); } @@ -921,71 +906,77 @@ TIFFWriteAnyArray(TIFF* tif, return (0); } } + + dir->tdir_tag = (uint16) tag; + dir->tdir_type = (uint16) type; + dir->tdir_count = n; + switch (type) { case TIFF_BYTE: - { uint8* bp = (uint8*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (uint8) v[i]; - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; - if (!TIFFWriteByteArray(tif, dir, (char*) bp)) - goto out; + { + uint8* bp = (uint8*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (uint8) v[i]; + if (!TIFFWriteByteArray(tif, dir, (char*) bp)) + goto out; } break; case TIFF_SBYTE: - { int8* bp = (int8*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (int8) v[i]; - dir->tdir_tag = (uint16) tag; - dir->tdir_type = (short) type; - dir->tdir_count = n; - if (!TIFFWriteByteArray(tif, dir, (char*) bp)) - goto out; + { + int8* bp = (int8*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (int8) v[i]; + if (!TIFFWriteByteArray(tif, dir, (char*) bp)) + goto out; } break; case TIFF_SHORT: - { uint16* bp = (uint16*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (uint16) v[i]; - if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) + { + uint16* bp = (uint16*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (uint16) v[i]; + if (!TIFFWriteShortArray(tif, dir, (uint16*)bp)) goto out; } break; case TIFF_SSHORT: - { int16* bp = (int16*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (int16) v[i]; - if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) - goto out; + { + int16* bp = (int16*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (int16) v[i]; + if (!TIFFWriteShortArray(tif, dir, (uint16*)bp)) + goto out; } break; case TIFF_LONG: - { uint32* bp = (uint32*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (uint32) v[i]; - if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp)) - goto out; + { + uint32* bp = (uint32*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (uint32) v[i]; + if (!TIFFWriteLongArray(tif, dir, bp)) + goto out; } break; case TIFF_SLONG: - { int32* bp = (int32*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (int32) v[i]; - if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp)) - goto out; + { + int32* bp = (int32*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (int32) v[i]; + if (!TIFFWriteLongArray(tif, dir, (uint32*) bp)) + goto out; } break; case TIFF_FLOAT: - { float* bp = (float*) w; - for (i = 0; i < (int) n; i++) - bp[i] = (float) v[i]; - if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp)) - goto out; + { + float* bp = (float*) w; + for (i = 0; i < (int) n; i++) + bp[i] = (float) v[i]; + if (!TIFFWriteFloatArray(tif, dir, bp)) + goto out; } break; case TIFF_DOUBLE: - return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v)); + return (TIFFWriteDoubleArray(tif, dir, v)); default: /* TIFF_NOTYPE */ /* TIFF_ASCII */