📄 tif_dirread.c
字号:
switch (dir->tdir_type) { case TIFF_SHORT: case TIFF_SSHORT: TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); break; case TIFF_LONG: case TIFF_SLONG: case TIFF_FLOAT: TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); break; case TIFF_DOUBLE: TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); break; } } return (cc);bad: TIFFError(tif->tif_name, "Error fetching data for field \"%s\"", _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); return ((tsize_t) 0);}/* * Fetch an ASCII item from the file. */static tsize_tTIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp){ if (dir->tdir_count <= 4) { uint32 l = dir->tdir_offset; if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong(&l); _TIFFmemcpy(cp, &l, dir->tdir_count); return (1); } return (TIFFFetchData(tif, dir, cp));}/* * Convert numerator+denominator to float. */static intcvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv){ if (denom == 0) { TIFFError(tif->tif_name, "%s: Rational with zero denominator (num = %lu)", _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num); return (0); } else { if (dir->tdir_type == TIFF_RATIONAL) *rv = ((float)num / (float)denom); else *rv = ((float)(int32)num / (float)(int32)denom); return (1); }}/* * Fetch a rational item from the file * at offset off and return the value * as a floating point number. */static floatTIFFFetchRational(TIFF* tif, TIFFDirEntry* dir){ uint32 l[2]; float v; return (!TIFFFetchData(tif, dir, (char *)l) || !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);}/* * Fetch a single floating point value * from the offset field and return it * as a native float. */static floatTIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir){ float v; int32 l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset); _TIFFmemcpy(&v, &l, sizeof(float)); TIFFCvtIEEEFloatToNative(tif, 1, &v); return (v);}/* * Fetch an array of BYTE or SBYTE values. */static intTIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v){ if (dir->tdir_count <= 4) { /* * Extract data from offset field. */ if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { if (dir->tdir_type == TIFF_SBYTE) switch (dir->tdir_count) { case 4: v[3] = (signed char)(dir->tdir_offset & 0xff); case 3: v[2] = (signed char)((dir->tdir_offset >> 8) & 0xff); case 2: v[1] = (signed char)((dir->tdir_offset >> 16) & 0xff); case 1: v[0] = (signed char)(dir->tdir_offset >> 24); } else switch (dir->tdir_count) { case 4: v[3] = (uint16)(dir->tdir_offset & 0xff); case 3: v[2] = (uint16)((dir->tdir_offset >> 8) & 0xff); case 2: v[1] = (uint16)((dir->tdir_offset >> 16) & 0xff); case 1: v[0] = (uint16)(dir->tdir_offset >> 24); } } else { if (dir->tdir_type == TIFF_SBYTE) switch (dir->tdir_count) { case 4: v[3] = (signed char)(dir->tdir_offset >> 24); case 3: v[2] = (signed char)((dir->tdir_offset >> 16) & 0xff); case 2: v[1] = (signed char)((dir->tdir_offset >> 8) & 0xff); case 1: v[0] = (signed char)(dir->tdir_offset & 0xff); } else switch (dir->tdir_count) { case 4: v[3] = (uint16)(dir->tdir_offset >> 24); case 3: v[2] = (uint16)((dir->tdir_offset >> 16) & 0xff); case 2: v[1] = (uint16)((dir->tdir_offset >> 8) & 0xff); case 1: v[0] = (uint16)(dir->tdir_offset & 0xff); } } return (1); } else return (TIFFFetchData(tif, dir, (char*) v) != 0); /* XXX */}/* * Fetch an array of SHORT or SSHORT values. */static intTIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v){ if (dir->tdir_count <= 2) { if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { switch (dir->tdir_count) { case 2: v[1] = (uint16) (dir->tdir_offset & 0xffff); case 1: v[0] = (uint16) (dir->tdir_offset >> 16); } } else { switch (dir->tdir_count) { case 2: v[1] = (uint16) (dir->tdir_offset >> 16); case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff); } } return (1); } else return (TIFFFetchData(tif, dir, (char *)v) != 0);}/* * Fetch a pair of SHORT or BYTE values. */static intTIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir){ uint16 v[4]; int ok = 0; switch (dir->tdir_type) { case TIFF_SHORT: case TIFF_SSHORT: ok = TIFFFetchShortArray(tif, dir, v); break; case TIFF_BYTE: case TIFF_SBYTE: ok = TIFFFetchByteArray(tif, dir, v); break; } if (ok) TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); return (ok);}/* * Fetch an array of LONG or SLONG values. */static intTIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v){ if (dir->tdir_count == 1) { v[0] = dir->tdir_offset; return (1); } else return (TIFFFetchData(tif, dir, (char*) v) != 0);}/* * Fetch an array of RATIONAL or SRATIONAL values. */static intTIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v){ int ok = 0; uint32* l; l = (uint32*)CheckMalloc(tif, dir->tdir_count, TIFFDataWidth((TIFFDataType) dir->tdir_type), "to fetch array of rationals"); if (l) { if (TIFFFetchData(tif, dir, (char *)l)) { uint32 i; for (i = 0; i < dir->tdir_count; i++) { ok = cvtRational(tif, dir, l[2*i+0], l[2*i+1], &v[i]); if (!ok) break; } } _TIFFfree((char *)l); } return (ok);}/* * Fetch an array of FLOAT values. */static intTIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v){ if (dir->tdir_count == 1) { v[0] = *(float*) &dir->tdir_offset; TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); return (1); } else if (TIFFFetchData(tif, dir, (char*) v)) { TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v); return (1); } else return (0);}/* * Fetch an array of DOUBLE values. */static intTIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v){ if (TIFFFetchData(tif, dir, (char*) v)) { TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v); return (1); } else return (0);}/* * Fetch an array of ANY values. The actual values are * returned as doubles which should be able hold all the * types. Yes, there really should be an tany_t to avoid * this potential non-portability ... Note in particular * that we assume that the double return value vector is * large enough to read in any fundamental type. We use * that vector as a buffer to read in the base type vector * and then convert it in place to double (from end * to front of course). */static intTIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v){ int i; switch (dir->tdir_type) { case TIFF_BYTE: case TIFF_SBYTE: if (!TIFFFetchByteArray(tif, dir, (uint16*) v)) return (0); if (dir->tdir_type == TIFF_BYTE) { uint16* vp = (uint16*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } else { int16* vp = (int16*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } break; case TIFF_SHORT: case TIFF_SSHORT: if (!TIFFFetchShortArray(tif, dir, (uint16*) v)) return (0); if (dir->tdir_type == TIFF_SHORT) { uint16* vp = (uint16*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } else { int16* vp = (int16*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } break; case TIFF_LONG: case TIFF_SLONG: if (!TIFFFetchLongArray(tif, dir, (uint32*) v)) return (0); if (dir->tdir_type == TIFF_LONG) { uint32* vp = (uint32*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } else { int32* vp = (int32*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } break; case TIFF_RATIONAL: case TIFF_SRATIONAL: if (!TIFFFetchRationalArray(tif, dir, (float*) v)) return (0); { float* vp = (float*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } break; case TIFF_FLOAT: if (!TIFFFetchFloatArray(tif, dir, (float*) v)) return (0); { float* vp = (float*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } break; case TIFF_DOUBLE: return (TIFFFetchDoubleArray(tif, dir, (double*) v)); default: /* TIFF_NOTYPE */ /* TIFF_ASCII */ /* TIFF_UNDEFINED */ TIFFError(tif->tif_name, "cannot read TIFF_ANY type %d for field \"%s\"", _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); return (0); } return (1);}/* * Fetch a tag that is not handled by special case code. */static intTIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp){ static const char mesg[] = "to fetch tag value"; int ok = 0; const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag); if (dp->tdir_count > 1) { /* array of values */ char* cp = NULL; switch (dp->tdir_type) { case TIFF_BYTE: case TIFF_SBYTE: /* NB: always expand BYTE values to shorts */ cp = CheckMalloc(tif, dp->tdir_count, sizeof (uint16), mesg); ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp); break; case TIFF_SHORT: case TIFF_SSHORT: cp = CheckMalloc(tif, dp->tdir_count, sizeof (uint16), mesg); ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp); break; case TIFF_LONG: case TIFF_SLONG: cp = CheckMalloc(tif, dp->tdir_count, sizeof (uint32), mesg); ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: cp = CheckMalloc(tif, dp->tdir_count, sizeof (float), mesg); ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp); break; case TIFF_FLOAT: cp = CheckMalloc(tif, dp->tdir_count, sizeof (float), mesg); ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp); break; case TIFF_DOUBLE: cp = CheckMalloc(tif, dp->tdir_count, sizeof (double), mesg); ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp); break; case TIFF_ASCII: case TIFF_UNDEFINED: /* bit of a cheat... */ /* * Some vendors write strings w/o the trailing * NULL byte, so always append one just in case. */ cp = CheckMalloc(tif, dp->tdir_count+1, 1, mesg); if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 ) cp[dp->tdir_count] = '\0'; /* XXX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -