📄 tif_dirwrite.c
字号:
#undef WriteRationalPair/* * Process tags that are not special cased. */static intTIFFWriteNormalTag(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; /* added based on patch request from MARTIN.MCBRIDE.MM@agfa.co.uk, 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 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); } 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);}#undef WRITEF/* * Setup a directory entry with either a SHORT * or LONG type according to the value. */static voidTIFFSetupShortLong(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); }}#undef MakeShortDirent#ifndef TIFFWriteRational/* * Setup a RATIONAL directory entry and * write the associated indirect value. */static intTIFFWriteRational(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 * samples/pixel array of SHORT values and * (potentially) write the associated indirect * values. */static intTIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir){ uint16 buf[10], v; uint16* w = buf; int i, status, samples = tif->tif_dir.td_samplesperpixel; if (samples > NITEMS(buf)) w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); TIFFGetField(tif, tag, &v); for (i = 0; i < samples; i++) w[i] = v; status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w); if (w != buf) _TIFFfree((char*) w); return (status);}/* * Setup a directory entry that references a samples/pixel array of ``type'' * values and (potentially) write the associated indirect values. The source * data from TIFFGetField() for the specified tag must be returned as double. */static intTIFFWritePerSampleAnys(TIFF* tif, TIFFDataType type, ttag_t tag, TIFFDirEntry* dir){ double buf[10], v; double* w = buf; int i, status; int samples = (int) tif->tif_dir.td_samplesperpixel; if (samples > NITEMS(buf)) w = (double*) _TIFFmalloc(samples * sizeof (double)); TIFFGetField(tif, tag, &v); for (i = 0; i < samples; i++) w[i] = v; status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w); if (w != buf) _TIFFfree(w); return (status);}#undef NITEMS/* * Setup a pair of shorts that are returned by * value, rather than as a reference to an array. */static intTIFFSetupShortPair(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));}/* * 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 intTIFFWriteShortTable(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);}/* * Write/copy data associated with an ASCII or opaque tag value. */static intTIFFWriteByteArray(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);}/* * Setup a directory entry of an array of SHORT * or SSHORT and write the associated indirect values. */static intTIFFWriteShortArray(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));}/* * Setup a directory entry of an array of LONG * or SLONG and write the associated indirect values. */static intTIFFWriteLongArray(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));}/* * Setup a directory entry of an array of RATIONAL * or SRATIONAL and write the associated indirect values. */static intTIFFWriteRationalArray(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)); 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -