/* * Setup a directory entry for an NxM table of shorts, * where M is known to be 2**bitspersample, and write * the associated indirect data. */ static int TIFFWriteShortTable(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) { uint32 i, off; dir->tdir_tag = tag; dir->tdir_type = (short) TIFF_SHORT; /* XXX -- yech, fool TIFFWriteData */ dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample); off = tif->tif_dataoff; #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ for (i = 0; i < n; i++) if (!TIFFWriteData(tif, dir, (char *)table[i])) return (0); dir->tdir_count *= n; dir->tdir_offset = off; return (1); }
/* * Write/copy data associated with an ASCII or opaque tag value. */ static int TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) { if (dir->tdir_count <= 4) { if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { dir->tdir_offset = (uint32)cp[0] << 24; if (dir->tdir_count >= 2) dir->tdir_offset |= (uint32)cp[1] << 16; if (dir->tdir_count >= 3) dir->tdir_offset |= (uint32)cp[2] << 8; if (dir->tdir_count == 4) dir->tdir_offset |= cp[3]; } else { dir->tdir_offset = cp[0]; if (dir->tdir_count >= 2) dir->tdir_offset |= (uint32) cp[1] << 8; if (dir->tdir_count >= 3) dir->tdir_offset |= (uint32) cp[2] << 16; if (dir->tdir_count == 4) dir->tdir_offset |= (uint32) cp[3] << 24; } return 1; } else return TIFFWriteData(tif, dir, cp); }
/* * Setup a directory entry of an array of LONG * or SLONG and write the associated indirect values. */ static int TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) { if (dir->tdir_count == 1) { dir->tdir_offset = v[0]; return (1); } else return (TIFFWriteData(tif, dir, (char*) v)); }
/* * Setup a directory entry of an array of RATIONAL * or SRATIONAL and write the associated indirect values. */ static int TIFFWriteRationalArray(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) { uint32 i; uint32* t; int status; dir->tdir_tag = tag; dir->tdir_type = (short) type; dir->tdir_count = n; t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32)); #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ for (i = 0; i < n; i++) { float fv = v[i]; int sign = 1; uint32 den; if (fv < 0) { if (type == TIFF_RATIONAL) { TIFFWarning(tif->tif_name, "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", _TIFFFieldWithTag(tif,tag)->field_name, v); fv = 0; } else fv = -fv, sign = -1; } den = 1L; if (fv > 0) { #if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */ # pragma ivdep # pragma swp # pragma unroll # pragma prefetch # if 0 # pragma simd noassert # endif #endif /* VDM auto patch */ 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+1] = den; } status = TIFFWriteData(tif, dir, (char *)t); _TIFFfree((char*) t); return (status); }
/* * Setup a directory entry of an array of LONG8 or SLONG8 * and write the associated indirect values. */ static int TIFFWriteLong8Array(TIFF* tif, TIFFDirEntry* dir, uint64* v) { if (TDIRGetEntryCount(tif,dir) <= TDIREntryOffLen(tif) / sizeof(uint64)) { _TIFFmemcpy(TDIRAddrEntryOff(tif,dir), v, TDIRGetEntryCount(tif,dir) * sizeof(uint64)); return (1); } return (TIFFWriteData(tif, dir, (char*) v)); }
static int TIFFWriteDoubleArray(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, 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)); }
/* * Write/copy data associated with an ASCII or opaque tag value. */ static int TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) { if (dir->tdir_count > 4) { if (!TIFFWriteData(tif, dir, cp)) return (0); } else _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count); return (1); }
static int TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) { TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v); if (dir->tdir_count == 1) { dir->tdir_offset = *(uint32*) &v[0]; return (1); } else return (TIFFWriteData(tif, dir, (char*) v)); }
/* * Write/copy data associated with an ASCII or opaque tag value. */ static int TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) { if (TDIRGetEntryCount(tif,dir) <= TDIREntryOffLen(tif)) { _TIFFmemcpy(TDIRAddrEntryOff(tif,dir), cp, TDIRGetEntryCount(tif,dir)); return (1); } return (TIFFWriteData(tif, dir, cp)); }
static int TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) { TIFFCvtNativeToIEEEDouble(tif, dir->s.tdir_count, v); if (TDIRGetEntryCount(tif,dir) <= TDIREntryOffLen(tif) / sizeof(double)) { _TIFFmemcpy(TDIRAddrEntryOff(tif,dir), v, TDIRGetEntryCount(tif,dir) * sizeof(double)); return (1); } return (TIFFWriteData(tif, dir, (char*) v)); }
/* * Setup a directory entry of an array of LONG * or SLONG and write the associated indirect values. */ static int TIFFWriteLongArray(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v) { dir->tdir_tag = (uint16) tag; dir->tdir_type = (short) type; dir->tdir_count = n; if (n == 1) { dir->tdir_offset = v[0]; return (1); } else return (TIFFWriteData(tif, dir, (char*) v)); }
static int TIFFWriteFloatArray(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) { dir->tdir_tag = (uint16) tag; dir->tdir_type = (short) type; dir->tdir_count = n; TIFFCvtNativeToIEEEFloat(tif, n, v); if (n == 1) { dir->tdir_offset = *(uint32*) &v[0]; return (1); } else return (TIFFWriteData(tif, dir, (char*) v)); }
/* * Setup a directory entry for an NxM table of shorts, * where M is known to be 2**bitspersample, and write * the associated indirect data. */ static int TIFFWriteShortTable(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) { uint32 i; dir->s.tdir_tag = (uint16) tag; dir->s.tdir_type = (short) TIFF_SHORT; /* XXX -- yech, fool TIFFWriteData */ TDIRSetEntryCount(tif,dir, (uint32) (1L<<tif->tif_dir.td_bitspersample)); for (i = 0; i < n; i++) if (!TIFFWriteData(tif, dir, (char *)table[i])) return (0); TDIRSetEntryCount(tif,dir, TDIRGetEntryCount(tif,dir) * n); return (1); }
/* * Setup a directory entry of an array of SHORT * or SSHORT and write the associated indirect values. */ static int TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) { if (dir->tdir_count <= 2) { if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { dir->tdir_offset = (uint32) ((long) v[0] << 16); if (dir->tdir_count == 2) dir->tdir_offset |= v[1] & 0xffff; } else { dir->tdir_offset = v[0] & 0xffff; if (dir->tdir_count == 2) dir->tdir_offset |= (long) v[1] << 16; } return (1); } else return (TIFFWriteData(tif, dir, (char*) v)); }
/* * Setup a directory entry for an NxM table of shorts, * where M is known to be 2**bitspersample, and write * the associated indirect data. */ static int TIFFWriteShortTable(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) { uint32 i, off; 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); off = tif->tif_dataoff; for (i = 0; i < n; i++) if (!TIFFWriteData(tif, dir, (char *)table[i])) return (0); dir->tdir_count *= n; dir->tdir_offset = off; return (1); }
/* * Setup a directory entry of an array of RATIONAL * or SRATIONAL and write the associated indirect values. */ static int TIFFWriteRationalArray(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, 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)); 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; uint32 den; if (fv < 0) { if (type == TIFF_RATIONAL) { TIFFWarning(tif->tif_name, "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", _TIFFFieldWithTag(tif,tag)->field_name, fv); fv = 0; } else fv = -fv, sign = -1; } den = 1L; if (fv > 0) { while (fv < 1L<<(31-3) && den < 1L<<(31-3)) fv *= 1<<3, den *= 1L<<3; } t[2*i+0] = (uint32) (sign * (fv + 0.5)); t[2*i+1] = den; } status = TIFFWriteData(tif, dir, (char *)t); _TIFFfree((char*) t); return (status); }
/* * Setup a directory entry of an array of SHORT * or SSHORT and write the associated indirect values. */ static int TIFFWriteShortArray(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v) { dir->tdir_tag = (uint16) tag; dir->tdir_type = (short) type; dir->tdir_count = n; if (n <= 2) { if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { dir->tdir_offset = (uint32) ((long) v[0] << 16); if (n == 2) dir->tdir_offset |= v[1] & 0xffff; } else { dir->tdir_offset = v[0] & 0xffff; if (n == 2) dir->tdir_offset |= (long) v[1] << 16; } return (1); } else return (TIFFWriteData(tif, dir, (char*) v)); }
static int TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) { TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v); return (TIFFWriteData(tif, dir, (char*) v)); }
/* 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); }