📄 tif_dirread.c
字号:
} cc = cc * dp->tdir_count; if (cc > sizeof (uint32)) space += cc; } space = filesize - space; if (td->td_planarconfig == PLANARCONFIG_SEPARATE) space /= td->td_samplesperpixel; for (i = 0; i < td->td_nstrips; i++) td->td_stripbytecount[i] = space; /* * This gross hack handles the case were the offset to * the last strip is past the place where we think the strip * should begin. Since a strip of data must be contiguous, * it's safe to assume that we've overestimated the amount * of data in the strip and trim this number back accordingly. */ i--; if (((toff_t)(td->td_stripoffset[i]+td->td_stripbytecount[i])) > filesize) td->td_stripbytecount[i] = filesize - td->td_stripoffset[i]; } else { uint32 rowbytes = TIFFScanlineSize(tif); uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage; for (i = 0; i < td->td_nstrips; i++) td->td_stripbytecount[i] = rowbytes*rowsperstrip; } TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) td->td_rowsperstrip = td->td_imagelength; return 1;}static voidMissingRequired(TIFF* tif, const char* tagname){ static const char module[] = "MissingRequired"; TIFFErrorExt(tif->tif_clientdata, module, "%s: TIFF directory is missing required \"%s\" field", tif->tif_name, tagname);}/* * Check the count field of a directory * entry against a known value. The caller * is expected to skip/ignore the tag if * there is a mismatch. */static intCheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count){ if (count > dir->tdir_count) { TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored", _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, dir->tdir_count, count); return (0); } else if (count < dir->tdir_count) { TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed", _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, dir->tdir_count, count); return (1); } return (1);}/* * Fetch a contiguous directory item. */static tsize_tTIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp){ int w = TIFFDataWidth((TIFFDataType) dir->tdir_type); tsize_t cc = dir->tdir_count * w; /* Check for overflow. */ if (!dir->tdir_count || !w || cc / w != (tsize_t)dir->tdir_count) goto bad; if (!isMapped(tif)) { if (!SeekOK(tif, dir->tdir_offset)) goto bad; if (!ReadOK(tif, cp, cc)) goto bad; } else { /* Check for overflow. */ if ((tsize_t)dir->tdir_offset + cc < (tsize_t)dir->tdir_offset || (tsize_t)dir->tdir_offset + cc < cc || (tsize_t)dir->tdir_offset + cc > (tsize_t)tif->tif_size) goto bad; _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc); } if (tif->tif_flags & TIFF_SWAB) { 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: TIFFErrorExt(tif->tif_clientdata, 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) { TIFFErrorExt(tif->tif_clientdata, 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, uint8* 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] = dir->tdir_offset & 0xff; case 3: v[2] = (dir->tdir_offset >> 8) & 0xff; case 2: v[1] = (dir->tdir_offset >> 16) & 0xff; case 1: v[0] = dir->tdir_offset >> 24; } else switch (dir->tdir_count) { case 4: v[3] = dir->tdir_offset & 0xff; case 3: v[2] = (dir->tdir_offset >> 8) & 0xff; case 2: v[1] = (dir->tdir_offset >> 16) & 0xff; case 1: v[0] = dir->tdir_offset >> 24; } } else { if (dir->tdir_type == TIFF_SBYTE) switch (dir->tdir_count) { case 4: v[3] = dir->tdir_offset >> 24; case 3: v[2] = (dir->tdir_offset >> 16) & 0xff; case 2: v[1] = (dir->tdir_offset >> 8) & 0xff; case 1: v[0] = dir->tdir_offset & 0xff; } else switch (dir->tdir_count) { case 4: v[3] = dir->tdir_offset >> 24; case 3: v[2] = (dir->tdir_offset >> 16) & 0xff; case 2: v[1] = (dir->tdir_offset >> 8) & 0xff; case 1: v[0] = 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. Some tags may have either BYTE * or SHORT type and this function works with both ones. */static intTIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir){ switch (dir->tdir_type) { case TIFF_BYTE: case TIFF_SBYTE: { uint8 v[4]; return TIFFFetchByteArray(tif, dir, v) && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); } case TIFF_SHORT: case TIFF_SSHORT: { uint16 v[2]; return TIFFFetchShortArray(tif, dir, v) && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]); } default: return 0; }}/* * 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*)_TIFFCheckMalloc(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, (uint8*) v)) return (0); if (dir->tdir_type == TIFF_BYTE) { uint8* vp = (uint8*) v; for (i = dir->tdir_count-1; i >= 0; i--) v[i] = vp[i]; } else { int8* vp = (int8*) 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 */ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "cannot read TIFF_ANY type %d for field \"%s\"", dir->tdir_type, _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); return (0); } return (1);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -