/* * 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); }
/* * Setup a directory entry with either a SHORT * or LONG type according to the value. */ static void TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v) { dir->tdir_tag = (uint16) tag; dir->tdir_count = 1; if (v > 0xffffL) { dir->tdir_type = (short) TIFF_LONG; dir->tdir_offset = v; } else { dir->tdir_type = (short) TIFF_SHORT; dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); } }
/* * Process tags that are not special cased. */ static int TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) { u_short wc = (u_short) fip->field_writecount; uint32 wc2; 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) switch (fip->field_type) { case TIFF_SHORT: case TIFF_SSHORT: if (wc > 1) { uint16* wp; 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 { 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 || fip->field_passcount) TIFFGetField(tif, fip->field_tag, &wc, &lp); else TIFFGetField(tif, fip->field_tag, &lp); if (!WRITEF(TIFFWriteLongArray, lp)) return (0); } else { 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 || fip->field_passcount) TIFFGetField(tif, fip->field_tag, &wc, &fp); else TIFFGetField(tif, fip->field_tag, &fp); if (!WRITEF(TIFFWriteRationalArray, fp)) return (0); } else { 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 || fip->field_passcount) TIFFGetField(tif, fip->field_tag, &wc, &fp); else TIFFGetField(tif, fip->field_tag, &fp); if (!WRITEF(TIFFWriteFloatArray, fp)) return (0); } else { 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 || fip->field_passcount) TIFFGetField(tif, fip->field_tag, &wc, &dp); else TIFFGetField(tif, fip->field_tag, &dp); if (!WRITEF(TIFFWriteDoubleArray, dp)) return (0); } else { 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: { char* cp; TIFFGetField(tif, fip->field_tag, &cp); dir->tdir_count = (uint32) (strlen(cp) + 1); if (!TIFFWriteByteArray(tif, dir, cp)) return (0); } break; /* added based on patch request from [email protected], correctness not verified (FW, 99/08) */ case TIFF_BYTE: case TIFF_SBYTE: 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 { 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; case TIFF_UNDEFINED: { char* cp; if (wc == (u_short) TIFF_VARIABLE) { 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); } break; case TIFF_NOTYPE: break; } return (1); }
/* * Process tags that are not special cased. */ static int TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) { uint16 wc = (uint16) fip->field_writecount; uint32 wc2; dir->tdir_tag = (uint16) fip->field_tag; dir->tdir_type = (uint16) fip->field_type; dir->tdir_count = wc; switch (fip->field_type) { case TIFF_SHORT: case TIFF_SSHORT: if (fip->field_passcount) { uint16* wp; 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); dir->tdir_count = wc; } if (!TIFFWriteShortArray(tif, dir, 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 (fip->field_passcount) { uint32* lp; 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); dir->tdir_count = wc; } if (!TIFFWriteLongArray(tif, dir, 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 (fip->field_passcount) { float* fp; 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); dir->tdir_count = wc; } if (!TIFFWriteRationalArray(tif, dir, fp)) return 0; } else { if (wc == 1) { float fv; TIFFGetField(tif, fip->field_tag, &fv); 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 (fip->field_passcount) { float* fp; 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); dir->tdir_count = wc; } if (!TIFFWriteFloatArray(tif, dir, fp)) return 0; } else { if (wc == 1) { float fv; TIFFGetField(tif, fip->field_tag, &fv); 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 (fip->field_passcount) { double* dp; 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); dir->tdir_count = wc; } if (!TIFFWriteDoubleArray(tif, dir, dp)) return 0; } else { if (wc == 1) { double dv; TIFFGetField(tif, fip->field_tag, &dv); if (!TIFFWriteDoubleArray(tif, dir, &dv)) return 0; } else { double* dp; TIFFGetField(tif, fip->field_tag, &dp); if (!TIFFWriteDoubleArray(tif, dir, dp)) return 0; } } break; case TIFF_ASCII: { char* cp; if (fip->field_passcount) TIFFGetField(tif, fip->field_tag, &wc, &cp); else TIFFGetField(tif, fip->field_tag, &cp); dir->tdir_count = (uint32) (strlen(cp) + 1); if (!TIFFWriteByteArray(tif, dir, cp)) return (0); } break; case TIFF_BYTE: case TIFF_SBYTE: if (fip->field_passcount) { char* cp; if (wc == (uint16) TIFF_VARIABLE2) { TIFFGetField(tif, fip->field_tag, &wc2, &cp); dir->tdir_count = wc2; } else { /* Assume TIFF_VARIABLE */ TIFFGetField(tif, fip->field_tag, &wc, &cp); dir->tdir_count = wc; } if (!TIFFWriteByteArray(tif, dir, cp)) return 0; } else { if (wc == 1) { char cv; TIFFGetField(tif, fip->field_tag, &cv); if (!TIFFWriteByteArray(tif, dir, &cv)) return 0; } else { char* cp; TIFFGetField(tif, fip->field_tag, &cp); if (!TIFFWriteByteArray(tif, dir, cp)) return 0; } } break; case TIFF_UNDEFINED: { char* cp; if (wc == (unsigned short) TIFF_VARIABLE) { TIFFGetField(tif, fip->field_tag, &wc, &cp); dir->tdir_count = wc; } else if (wc == (unsigned 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); } break; case TIFF_NOTYPE: break; } return (1); }
/* * Process tags that are not special cased. */ static int TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) { u_short wc = (u_short) fip->field_writecount; uint32 wc2; 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) switch (fip->field_type) { case TIFF_SHORT: case TIFF_SSHORT: if (wc > 1) { uint16* wp; if (wc == (u_short) TIFF_VARIABLE) 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); } break; case TIFF_LONG: case TIFF_SLONG: if (wc > 1) { uint32* lp; if (wc == (u_short) TIFF_VARIABLE) 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); } break; case TIFF_RATIONAL: case TIFF_SRATIONAL: if (wc > 1) { float* fp; if (wc == (u_short) TIFF_VARIABLE) 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); } break; case TIFF_FLOAT: if (wc > 1) { float* fp; if (wc == (u_short) TIFF_VARIABLE) 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); } break; case TIFF_DOUBLE: if (wc > 1) { double* dp; if (wc == (u_short) TIFF_VARIABLE) 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); } break; case TIFF_ASCII: { char* cp; TIFFGetField(tif, fip->field_tag, &cp); dir->tdir_count = (uint32) (strlen(cp) + 1); if (!TIFFWriteByteArray(tif, dir, cp)) return (0); } break; case TIFF_UNDEFINED: { char* cp; if (wc == (u_short) TIFF_VARIABLE) { 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); } break; } return (1); }
/* The standard function TIFFWriteNormalTag() could definitely be replaced with a simple call to this function, just adding TIFFGetField() as the last argument. */ static int TIFFWriteNormalSubTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip, int (*getFieldFn)(TIFF *tif, ttag_t tag, ...)) { u_short wc = (u_short) fip->field_writecount; dir->tdir_tag = 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) switch (fip->field_type) { case TIFF_SHORT: case TIFF_SSHORT: if (wc > 1) { uint16* wp; if (wc == (u_short) TIFF_VARIABLE) { (*getFieldFn)(tif, fip->field_tag, &wc, &wp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &wp); if (!WRITEF(TIFFWriteShortArray, wp)) return (0); } else { uint16 sv; (*getFieldFn)(tif, fip->field_tag, &sv); dir->tdir_offset = TIFFInsertData(tif, dir->tdir_type, sv); } break; case TIFF_LONG: case TIFF_SLONG: if (wc > 1) { uint32* lp; if (wc == (u_short) TIFF_VARIABLE) { (*getFieldFn)(tif, fip->field_tag, &wc, &lp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &lp); if (!WRITEF(TIFFWriteLongArray, lp)) return (0); } else { /* XXX handle LONG->SHORT conversion */ (*getFieldFn)(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) { (*getFieldFn)(tif, fip->field_tag, &wc, &fp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &fp); if (!WRITEF(TIFFWriteRationalArray, fp)) return (0); } else { float fv; (*getFieldFn)(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) { (*getFieldFn)(tif, fip->field_tag, &wc, &fp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &fp); if (!WRITEF(TIFFWriteFloatArray, fp)) return (0); } else { float fv; (*getFieldFn)(tif, fip->field_tag, &fv); if (!WRITEF(TIFFWriteFloatArray, &fv)) return (0); } break; case TIFF_DOUBLE: /* Hey - I think this is a bug, or at least a "gross inconsistency", in the TIFF library. Look at the original TIFF library code below within the "#if (0) ... #else". Just from the type of *dp, you can see that this code expects TIFFGetField() to be handed a double ** for any TIFF_DOUBLE tag, even for the constant wc==1 case. This is totally inconsistent with other fields (like TIFF_FLOAT, above) and is also inconsistent with the TIFFSetField() function for TIFF_DOUBLEs, which expects to be passed a single double by value for the wc==1 case. (See the handling of TIFFFetchNormalTag() in tif_dirread.c for an example.) Maybe this function was written before TIFFWriteDoubleArray() was written, not that that's an excuse. Anyway, the new code below is a trivial modification of the TIFF_FLOAT code above. The fact that even single doubles get written out in the data segment and get an offset value stored is irrelevant here - that is all handled by TIFFWriteDoubleArray(). */ #if (0) { double* dp; if (wc == (u_short) TIFF_VARIABLE) { (*getFieldFn)(tif, fip->field_tag, &wc, &dp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &dp); TIFFCvtNativeToIEEEDouble(tif, wc, dp); if (!TIFFWriteData(tif, dir, (char*) dp)) return (0); } #else if (wc > 1) { double* dp; if (wc == (u_short) TIFF_VARIABLE) { (*getFieldFn)(tif, fip->field_tag, &wc, &dp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &dp); if (!WRITEF(TIFFWriteDoubleArray, dp)) return (0); } else { double dv; (*getFieldFn)(tif, fip->field_tag, &dv); if (!WRITEF(TIFFWriteDoubleArray, &dv)) return (0); } #endif break; case TIFF_ASCII: { char* cp; (*getFieldFn)(tif, fip->field_tag, &cp); dir->tdir_count = (uint32) (strlen(cp) + 1); if (!TIFFWriteByteArray(tif, dir, cp)) return (0); } break; case TIFF_UNDEFINED: { char* cp; if (wc == (u_short) TIFF_VARIABLE) { (*getFieldFn)(tif, fip->field_tag, &wc, &cp); dir->tdir_count = wc; } else (*getFieldFn)(tif, fip->field_tag, &cp); if (!TIFFWriteByteArray(tif, dir, cp)) return (0); } break; } return (1); }