1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2025-09-26 09:24:38 +03:00
91 changed files with 5339 additions and 1508 deletions
+6 -2
View File
@@ -55,8 +55,12 @@ if(TARGET_ARCH MATCHES "^(ARM|arm|aarch)")
elseif(NOT PNG_ARM_NEON STREQUAL "off")
list(APPEND lib_srcs arm/arm_init.c arm/filter_neon_intrinsics.c arm/palette_neon_intrinsics.c)
if(NOT MSVC)
enable_language(ASM)
list(APPEND lib_srcs arm/filter_neon.S)
if(CMAKE_SYSTEM_NAME STREQUAL "QNX")
message(STATUS "Skipping arm/filter_neon.S on QNX")
else()
enable_language(ASM)
list(APPEND lib_srcs arm/filter_neon.S)
endif()
endif()
if(PNG_ARM_NEON STREQUAL "on")
add_definitions(-DPNG_ARM_NEON_OPT=2)
+2 -2
View File
@@ -359,7 +359,7 @@ endif()
set(LIBTIFF_MAJOR_VERSION "4")
set(LIBTIFF_MINOR_VERSION "7")
set(LIBTIFF_MICRO_VERSION "0")
set(LIBTIFF_MICRO_VERSION "1")
set(LIBTIFF_VERSION "${LIBTIFF_MAJOR_VERSION}.${LIBTIFF_MINOR_VERSION}.${LIBTIFF_MICRO_VERSION}")
file(READ "RELEASE-DATE" LIBTIFF_RELEASE_DATE content)
@@ -480,4 +480,4 @@ if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${TIFF_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
endif()
ocv_install_3rdparty_licenses(libtiff COPYRIGHT)
ocv_install_3rdparty_licenses(libtiff LICENSE.md)
-21
View File
@@ -1,21 +0,0 @@
Copyright (c) 1988-1997 Sam Leffler
Copyright (c) 1991-1997 Silicon Graphics, Inc.
Permission to use, copy, modify, distribute, and sell this software and
its documentation for any purpose is hereby granted without fee, provided
that (i) the above copyright notices and this permission notice appear in
all copies of the software and related documentation, and (ii) the names of
Sam Leffler and Silicon Graphics may not be used in any advertising or
publicity relating to the software without the specific, prior written
permission of Sam Leffler and Silicon Graphics.
THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
+1299 -20
View File
File diff suppressed because it is too large Load Diff
+49
View File
@@ -0,0 +1,49 @@
# LibTIFF license
Copyright © 1988-1997 Sam Leffler\
Copyright © 1991-1997 Silicon Graphics, Inc.
Permission to use, copy, modify, distribute, and sell this software and
its documentation for any purpose is hereby granted without fee, provided
that (i) the above copyright notices and this permission notice appear in
all copies of the software and related documentation, and (ii) the names of
Sam Leffler and Silicon Graphics may not be used in any advertising or
publicity relating to the software without the specific, prior written
permission of Sam Leffler and Silicon Graphics.
THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
# Lempel-Ziv & Welch Compression (tif_lzw.c) license
The code of tif_lzw.c is derived from the compress program whose code is
derived from software contributed to Berkeley by James A. Woods,
derived from original work by Spencer Thomas and Joseph Orost.
The original Berkeley copyright notice appears below in its entirety:
Copyright (c) 1985, 1986 The Regents of the University of California.
All rights reserved.
This code is derived from software contributed to Berkeley by
James A. Woods, derived from original work by Spencer Thomas
and Joseph Orost.
Redistribution and use in source and binary forms are permitted
provided that the above copyright notice and this paragraph are
duplicated in all such forms and that any documentation,
advertising materials, and other materials related to such
distribution and use acknowledge that the software was developed
by the University of California, Berkeley. The name of the
University may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+1 -1
View File
@@ -1 +1 @@
20240911
20250911
+4 -1
View File
@@ -131,7 +131,10 @@ static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
tmsize_t i, n, nbytes;
tf[0] = tf[1] = tf[2] = 0;
if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
// Do not try to generate a default TransferFunction beyond 24 bits.
// This otherwise leads to insane amounts, resulting in denial of service
// See https://github.com/OSGeo/gdal/issues/10875
if (td->td_bitspersample > 24)
return 0;
n = ((tmsize_t)1) << td->td_bitspersample;
-1
View File
@@ -48,7 +48,6 @@ void TIFFCleanup(TIFF *tif)
*/
if (tif->tif_mode != O_RDONLY)
TIFFFlush(tif);
(*tif->tif_cleanup)(tif);
TIFFFreeDirectory(tif);
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
+8 -2
View File
@@ -80,11 +80,17 @@
#cmakedefine HAVE_UNISTD_H 1
/* 8/12 bit libjpeg dual mode enabled */
#cmakedefine JPEG_DUAL_MODE_8_12 1 1
#cmakedefine JPEG_DUAL_MODE_8_12 1
/* 8/12 bit dual mode JPEG built into libjpeg-turbo 3.0+ */
#cmakedefine HAVE_JPEGTURBO_DUAL_MODE_8_12 1
/* Support LERC compression */
#cmakedefine LERC_SUPPORT 1
/* Define to 1 when building a static libtiff with LERC enabled. */
#cmakedefine LERC_STATIC
/* 12bit libjpeg primary include file with path */
#define LIBJPEG_12_PATH "@LIBJPEG_12_PATH@"
@@ -133,7 +139,7 @@
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# cmakedefine WORDS_BIGENDIAN 1
# endif
#endif
+28 -27
View File
@@ -723,10 +723,9 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
{
TIFFTagValue *new_customValues;
td->td_customValueCount++;
new_customValues = (TIFFTagValue *)_TIFFreallocExt(
tif, td->td_customValues,
sizeof(TIFFTagValue) * td->td_customValueCount);
sizeof(TIFFTagValue) * (td->td_customValueCount + 1));
if (!new_customValues)
{
TIFFErrorExtR(tif, module,
@@ -737,6 +736,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
goto end;
}
td->td_customValueCount++;
td->td_customValues = new_customValues;
tv = td->td_customValues + (td->td_customValueCount - 1);
@@ -748,8 +748,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
/*
* Set custom value ... save a copy of the custom tag value.
*/
/*--: Rational2Double: For Rationals evaluate "set_field_type" to
* determine internal storage size. */
/*--: Rational2Double: For Rationals evaluate "set_get_field_type"
* to determine internal storage size. */
tv_size = TIFFFieldSetGetSize(fip);
if (tv_size == 0)
{
@@ -806,14 +806,13 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
if (tv->count == 0)
{
status = 0;
TIFFErrorExtR(tif, module,
"%s: Null count for \"%s\" (type "
"%d, writecount %d, passcount %d)",
tif->tif_name, fip->field_name,
fip->field_type, fip->field_writecount,
fip->field_passcount);
goto end;
TIFFWarningExtR(tif, module,
"%s: Null count for \"%s\" (type "
"%d, writecount %d, passcount %d)",
tif->tif_name, fip->field_name,
fip->field_type, fip->field_writecount,
fip->field_passcount);
break;
}
tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
@@ -843,7 +842,7 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
fip->field_writecount == TIFF_SPP || tv->count > 1)
{
/*--: Rational2Double: For Rationals tv_size is set above to
* 4 or 8 according to fip->set_field_type! */
* 4 or 8 according to fip->set_get_field_type! */
_TIFFmemcpy(tv->value, va_arg(ap, void *),
tv->count * tv_size);
/* Test here for too big values for LONG8, SLONG8 in
@@ -978,7 +977,8 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
/*-- Rational2Double: For Rationals tv_size is set
* above to 4 or 8 according to fip->set_field_type!
* above to 4 or 8 according to
* fip->set_get_field_type!
*/
{
if (tv_size == 8)
@@ -996,11 +996,11 @@ static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
* default. */
if (tv_size != 4)
{
TIFFErrorExtR(
tif, module,
"Rational2Double: .set_field_type "
"in not 4 but %d",
tv_size);
TIFFErrorExtR(tif, module,
"Rational2Double: "
".set_get_field_type "
"in not 4 but %d",
tv_size);
}
}
}
@@ -1527,7 +1527,7 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
case TIFF_SRATIONAL:
{
/*-- Rational2Double: For Rationals evaluate
* "set_field_type" to determine internal
* "set_get_field_type" to determine internal
* storage size and return value size. */
int tv_size = TIFFFieldSetGetSize(fip);
if (tv_size == 8)
@@ -1545,11 +1545,11 @@ static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
* default. */
if (tv_size != 4)
{
TIFFErrorExtR(
tif, "_TIFFVGetField",
"Rational2Double: .set_field_type "
"in not 4 but %d",
tv_size);
TIFFErrorExtR(tif, "_TIFFVGetField",
"Rational2Double: "
".set_get_field_type "
"in not 4 but %d",
tv_size);
}
}
}
@@ -1621,6 +1621,7 @@ void TIFFFreeDirectory(TIFF *tif)
TIFFDirectory *td = &tif->tif_dir;
int i;
(*tif->tif_cleanup)(tif);
_TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
CleanupField(td_sminsamplevalue);
CleanupField(td_smaxsamplevalue);
@@ -2207,7 +2208,7 @@ int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
_TIFFCleanupIFDOffsetAndNumberMaps(tif);
tif->tif_curdir = 0; /* first directory of new chain */
/* add this offset to new IFD list */
_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
retval = _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
}
/* To be able to return from SubIFD or custom-IFD to main-IFD */
tif->tif_setdirectory_force_absolute = TRUE;
@@ -2336,12 +2337,12 @@ int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
* means that the caller can only append to the directory
* chain.
*/
(*tif->tif_cleanup)(tif);
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
{
_TIFFfreeExt(tif, tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawcc = 0;
tif->tif_rawcp = NULL;
tif->tif_rawdataoff = 0;
tif->tif_rawdataloaded = 0;
}
+9 -10
View File
@@ -329,16 +329,15 @@ extern "C"
struct _TIFFField
{
uint32_t field_tag; /* field's tag */
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */
uint32_t
field_anonymous; /* if true, this is a unknown / anonymous tag */
TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField
and TIFFGetField*/
TIFFSetGetFieldType get_field_type; /* not used */
unsigned short field_bit; /* bit in fieldsset bit vector */
uint32_t field_tag; /* field's tag */
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */
uint32_t field_anonymous; /* if true, this is a unknown /
anonymous tag */
TIFFSetGetFieldType set_get_field_type; /* type to be passed to
TIFFSetField, TIFFGetField */
unsigned short field_bit; /* bit in fieldsset bit vector */
unsigned char field_oktochange; /* if true, can change while writing */
unsigned char field_passcount; /* if true, pass dir count on set */
char *field_name; /* ASCII name */
+412 -411
View File
@@ -54,10 +54,10 @@ static const TIFFFieldArray gpsFieldArray;
/*--: Rational2Double: --
* The Rational2Double upgraded libtiff functionality allows the definition and
* achievement of true double-precision accuracy for TIFF tags of RATIONAL type
* and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE.
* and field_bit=FIELD_CUSTOM using the set_get_field_type = TIFF_SETGET_DOUBLE.
* Unfortunately, that changes the old implemented interface for TIFFGetField().
* In order to keep the old TIFFGetField() interface behavior those tags have to
* be redefined with set_field_type = TIFF_SETGET_FLOAT!
* be redefined with set_get_field_type = TIFF_SETGET_FLOAT!
*
* Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay.
*
@@ -65,281 +65,281 @@ static const TIFFFieldArray gpsFieldArray;
/* clang-format off */ /* for better readability of tag comments */
static const TIFFField tiffFields[] = {
{TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL},
{TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL},
{TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL},
{TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL},
{TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL},
{TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL},
{TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL},
{TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL},
{TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellWidth", NULL},
{TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellLength", NULL},
{TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL},
{TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL},
{TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL},
{TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL},
{TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL},
{TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL},
{TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL},
{TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL},
{TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL},
{TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL},
{TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL},
{TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL},
{TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL},
{TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL},
{TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL},
{TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL},
{TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL},
{TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL},
{TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL},
{TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL},
{TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL},
{TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL},
{TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL},
{TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL},
{TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL},
{TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL},
{TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL},
{TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL},
{TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL},
{TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL},
{TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL},
{TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL},
{TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL},
{TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL},
{TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL},
{TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL},
{TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL},
{TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL},
{TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray *)&tiffFieldArray},
{TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL},
{TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL},
{TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL},
{TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL},
{TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL},
{TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL},
{TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL},
{TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL},
{TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL},
{TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL},
{TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL},
{TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL},
{TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL},
{TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL},
{TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL},
{TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL},
{TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "XMLPacket", NULL},
{TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL},
{TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL},
{TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL},
{TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL},
{TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL},
{TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_COMPRESSION, 0, 0, "Compression", NULL},
{TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL},
{TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL},
{TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CellWidth", NULL},
{TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CellLength", NULL},
{TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_FILLORDER, 0, 0, "FillOrder", NULL},
{TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DocumentName", NULL},
{TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL},
{TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Make", NULL},
{TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Model", NULL},
{TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL},
{TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_ORIENTATION, 0, 0, "Orientation", NULL},
{TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL},
{TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL},
{TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL},
{TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL},
{TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL},
{TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_RESOLUTION, 1, 0, "XResolution", NULL},
{TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_RESOLUTION, 1, 0, "YResolution", NULL},
{TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL},
{TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "PageName", NULL},
{TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_POSITION, 1, 0, "XPosition", NULL},
{TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_POSITION, 1, 0, "YPosition", NULL},
{TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL},
{TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL},
{TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL},
{TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL},
{TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL},
{TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL},
{TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL},
{TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL},
{TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Software", NULL},
{TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DateTime", NULL},
{TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Artist", NULL},
{TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "HostComputer", NULL},
{TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL},
{TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL},
{TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, FIELD_COLORMAP, 1, 0, "ColorMap", NULL},
{TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL},
{TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL},
{TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL},
{TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL},
{TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL},
{TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray *)&tiffFieldArray},
{TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 0, 0, "InkSet", NULL},
{TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, FIELD_INKNAMES, 1, 1, "InkNames", NULL},
{TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL},
{TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, FIELD_CUSTOM, 0, 0, "DotRange", NULL},
{TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL},
{TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL},
{TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL},
{TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL},
{TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL},
{TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 0, 1, "ClipPath", NULL},
{TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL},
{TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL},
{TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL},
{TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL},
{TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL},
{TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL},
{TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "XMLPacket", NULL},
/* begin SGI tags */
{TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL},
{TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL},
{TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL},
{TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL},
{TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL},
{TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL},
{TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL},
{TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL},
/* end SGI tags */
/* begin Pixar tags */
{TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL},
{TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL},
{TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL},
{TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL},
{TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL},
{TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL},
{TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL},
{TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL},
{TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL},
{TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL},
{TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL},
{TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL},
{TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL},
{TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL},
{TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL},
{TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Copyright", NULL},
/* end Pixar tags */
{TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RichTIFFIPTC", NULL},
{TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL},
{TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "RichTIFFIPTC", NULL},
{TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "Photoshop", NULL},
/*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. However, for IFD-like tags,
* libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with a special handling procedure in order to write either
* a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */
{TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
{TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL},
{TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
{TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL},
{TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL},
{TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL},
{TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL},
{TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL},
{TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL},
{TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL},
{TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray *)&exifFieldArray},
{TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "ICC Profile", NULL},
{TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray *)&gpsFieldArray},
{TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL},
{TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL},
{TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL},
{TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL},
{TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 0, 0, "StoNits", NULL},
{TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL},
{TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL},
/* begin DNG tags */
{TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGVersion", NULL},
{TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DNGBackwardVersion", NULL},
{TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL},
{TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL},
{TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPlaneColor", NULL},
{TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CFALayout", NULL},
{TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LinearizationTable", NULL},
{TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BlackLevelRepeatDim", NULL},
{TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevel", NULL},
{TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaH", NULL},
{TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaV", NULL},
{TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "WhiteLevel", NULL},
{TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultScale", NULL},
{TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BestQualityScale", NULL},
{TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropOrigin", NULL},
{TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultCropSize", NULL},
{TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix1", NULL},
{TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix2", NULL},
{TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration1", NULL},
{TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration2", NULL},
{TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix1", NULL},
{TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix2", NULL},
{TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AnalogBalance", NULL},
{TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotNeutral", NULL},
{TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AsShotWhiteXY", NULL},
{TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposure", NULL},
{TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineNoise", NULL},
{TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineSharpness", NULL},
{TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BayerGreenSplit", NULL},
{TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LinearResponseLimit", NULL},
{TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL},
{TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensInfo", NULL},
{TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ChromaBlurRadius", NULL},
{TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AntiAliasStrength", NULL},
{TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShadowScale", NULL},
{TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DNGPrivateData", NULL},
{TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MakerNoteSafety", NULL},
{TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant1", NULL},
{TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant2", NULL},
{TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawDataUniqueID", NULL},
{TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL},
{TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileData", NULL},
{TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ActiveArea", NULL},
{TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MaskedAreas", NULL},
{TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotICCProfile", NULL},
{TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotPreProfileMatrix", NULL},
{TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentICCProfile", NULL},
{TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL},
{TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
{TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "DNGVersion", NULL},
{TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "DNGBackwardVersion", NULL},
{TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL},
{TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL},
{TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "CFAPlaneColor", NULL},
{TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CFALayout", NULL},
{TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_CUSTOM, 1, 1, "LinearizationTable", NULL},
{TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, FIELD_CUSTOM, 1, 0, "BlackLevelRepeatDim", NULL},
{TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "BlackLevel", NULL},
{TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaH", NULL},
{TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "BlackLevelDeltaV", NULL},
{TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, FIELD_CUSTOM, 1, 1, "WhiteLevel", NULL},
{TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "DefaultScale", NULL},
{TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "BestQualityScale", NULL},
{TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "DefaultCropOrigin", NULL},
{TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "DefaultCropSize", NULL},
{TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ColorMatrix1", NULL},
{TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ColorMatrix2", NULL},
{TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "CameraCalibration1", NULL},
{TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "CameraCalibration2", NULL},
{TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ReductionMatrix1", NULL},
{TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ReductionMatrix2", NULL},
{TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "AnalogBalance", NULL},
{TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "AsShotNeutral", NULL},
{TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "AsShotWhiteXY", NULL},
{TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "BaselineExposure", NULL},
{TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "BaselineNoise", NULL},
{TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "BaselineSharpness", NULL},
{TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "BayerGreenSplit", NULL},
{TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "LinearResponseLimit", NULL},
{TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL},
{TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "LensInfo", NULL},
{TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ChromaBlurRadius", NULL},
{TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "AntiAliasStrength", NULL},
{TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ShadowScale", NULL},
{TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "DNGPrivateData", NULL},
{TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "MakerNoteSafety", NULL},
{TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant1", NULL},
{TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant2", NULL},
{TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "RawDataUniqueID", NULL},
{TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL},
{TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "OriginalRawFileData", NULL},
{TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "ActiveArea", NULL},
{TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, FIELD_CUSTOM, 1, 1, "MaskedAreas", NULL},
{TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "AsShotICCProfile", NULL},
{TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "AsShotPreProfileMatrix", NULL},
{TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "CurrentICCProfile", NULL},
{TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "CurrentPreProfileMatrix", NULL},
{TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
#if 0
/* begin DNG 1.2.0.0 tags */
{TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL},
{TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL},
{TIFFTAG_PROFILECALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCalibrationSignature", NULL},
{TIFFTAG_EXTRACAMERAPROFILES, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ExtraCameraProfiles", NULL},
{TIFFTAG_ASSHOTPROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AsShotProfileName", NULL},
{TIFFTAG_NOISEREDUCTIONAPPLIED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NoiseReductionApplied", NULL},
{TIFFTAG_PROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileName", NULL},
{TIFFTAG_PROFILEHUESATMAPDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapDims", NULL},
{TIFFTAG_PROFILEHUESATMAPDATA1, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData1", NULL},
{TIFFTAG_PROFILEHUESATMAPDATA2, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData2", NULL},
{TIFFTAG_PROFILETONECURVE, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileToneCurve", NULL},
{TIFFTAG_PROFILEEMBEDPOLICY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileEmbedPolicy", NULL},
{TIFFTAG_PROFILECOPYRIGHT, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileCopyright", NULL},
{TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix1", NULL},
{TIFFTAG_FORWARDMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix2", NULL},
{TIFFTAG_PREVIEWAPPLICATIONNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationName", NULL},
{TIFFTAG_PREVIEWAPPLICATIONVERSION, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewApplicationVersion", NULL},
{TIFFTAG_PREVIEWSETTINGSNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "PreviewSettingsName", NULL},
{TIFFTAG_PREVIEWSETTINGSDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewSettingsDigest", NULL},
{TIFFTAG_PREVIEWCOLORSPACE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewColorSpace", NULL},
{TIFFTAG_PREVIEWDATETIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PreviewDateTime", NULL},
{TIFFTAG_RAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawImageDigest", NULL},
{TIFFTAG_ORIGINALRAWFILEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalRawFileDigest", NULL},
{TIFFTAG_SUBTILEBLOCKSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubTileBlockSize", NULL},
{TIFFTAG_ROWINTERLEAVEFACTOR, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RowInterleaveFactor", NULL},
{TIFFTAG_PROFILELOOKTABLEDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableDims", NULL},
{TIFFTAG_PROFILELOOKTABLEDATA, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileLookTableData", NULL},
{TIFFTAG_COLORIMETRICREFERENCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "ColorimetricReference", NULL},
{TIFFTAG_CAMERACALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "CameraCalibrationSignature", NULL},
{TIFFTAG_PROFILECALIBRATIONSIGNATURE, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "ProfileCalibrationSignature", NULL},
{TIFFTAG_EXTRACAMERAPROFILES, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, FIELD_CUSTOM, 1, 1, "ExtraCameraProfiles", NULL},
{TIFFTAG_ASSHOTPROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "AsShotProfileName", NULL},
{TIFFTAG_NOISEREDUCTIONAPPLIED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "NoiseReductionApplied", NULL},
{TIFFTAG_PROFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "ProfileName", NULL},
{TIFFTAG_PROFILEHUESATMAPDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapDims", NULL},
{TIFFTAG_PROFILEHUESATMAPDATA1, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData1", NULL},
{TIFFTAG_PROFILEHUESATMAPDATA2, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData2", NULL},
{TIFFTAG_PROFILETONECURVE, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ProfileToneCurve", NULL},
{TIFFTAG_PROFILEEMBEDPOLICY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ProfileEmbedPolicy", NULL},
{TIFFTAG_PROFILECOPYRIGHT, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "ProfileCopyright", NULL},
{TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ForwardMatrix1", NULL},
{TIFFTAG_FORWARDMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ForwardMatrix2", NULL},
{TIFFTAG_PREVIEWAPPLICATIONNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "PreviewApplicationName", NULL},
{TIFFTAG_PREVIEWAPPLICATIONVERSION, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "PreviewApplicationVersion", NULL},
{TIFFTAG_PREVIEWSETTINGSNAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "PreviewSettingsName", NULL},
{TIFFTAG_PREVIEWSETTINGSDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "PreviewSettingsDigest", NULL},
{TIFFTAG_PREVIEWCOLORSPACE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "PreviewColorSpace", NULL},
{TIFFTAG_PREVIEWDATETIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "PreviewDateTime", NULL},
{TIFFTAG_RAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "RawImageDigest", NULL},
{TIFFTAG_ORIGINALRAWFILEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "OriginalRawFileDigest", NULL},
{TIFFTAG_SUBTILEBLOCKSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "SubTileBlockSize", NULL},
{TIFFTAG_ROWINTERLEAVEFACTOR, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "RowInterleaveFactor", NULL},
{TIFFTAG_PROFILELOOKTABLEDIMS, 3, 3, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "ProfileLookTableDims", NULL},
{TIFFTAG_PROFILELOOKTABLEDATA, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ProfileLookTableData", NULL},
/* begin DNG 1.3.0.0 tags */
{TIFFTAG_OPCODELIST1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList1", NULL},
{TIFFTAG_OPCODELIST2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList2", NULL},
{TIFFTAG_OPCODELIST3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OpcodeList3", NULL},
{TIFFTAG_NOISEPROFILE, -1, -1, TIFF_DOUBLE, 0, TIFF_SETGET_C16_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "NoiseProfile", NULL},
{TIFFTAG_OPCODELIST1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "OpcodeList1", NULL},
{TIFFTAG_OPCODELIST2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "OpcodeList2", NULL},
{TIFFTAG_OPCODELIST3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "OpcodeList3", NULL},
{TIFFTAG_NOISEPROFILE, -1, -1, TIFF_DOUBLE, 0, TIFF_SETGET_C16_DOUBLE, FIELD_CUSTOM, 1, 1, "NoiseProfile", NULL},
/* begin DNG 1.4.0.0 tags */
{TIFFTAG_DEFAULTUSERCROP, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultUserCrop", NULL},
{TIFFTAG_DEFAULTBLACKRENDER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DefaultBlackRender", NULL},
{TIFFTAG_BASELINEEXPOSUREOFFSET, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BaselineExposureOffset", NULL},
{TIFFTAG_PROFILELOOKTABLEENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileLookTableEncoding", NULL},
{TIFFTAG_PROFILEHUESATMAPENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapEncoding", NULL},
{TIFFTAG_ORIGINALDEFAULTFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultFinalSize", NULL},
{TIFFTAG_ORIGINALBESTQUALITYFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalBestQualityFinalSize", NULL},
{TIFFTAG_ORIGINALDEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OriginalDefaultCropSize", NULL}, /* could also be rational */
{TIFFTAG_NEWRAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NewRawImageDigest", NULL},
{TIFFTAG_RAWTOPREVIEWGAIN, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RawToPreviewGain", NULL},
{TIFFTAG_DEFAULTUSERCROP, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "DefaultUserCrop", NULL},
{TIFFTAG_DEFAULTBLACKRENDER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "DefaultBlackRender", NULL},
{TIFFTAG_BASELINEEXPOSUREOFFSET, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "BaselineExposureOffset", NULL},
{TIFFTAG_PROFILELOOKTABLEENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ProfileLookTableEncoding", NULL},
{TIFFTAG_PROFILEHUESATMAPENCODING, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ProfileHueSatMapEncoding", NULL},
{TIFFTAG_ORIGINALDEFAULTFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "OriginalDefaultFinalSize", NULL},
{TIFFTAG_ORIGINALBESTQUALITYFINALSIZE, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "OriginalBestQualityFinalSize", NULL},
{TIFFTAG_ORIGINALDEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "OriginalDefaultCropSize", NULL}, /* could also be rational */
{TIFFTAG_NEWRAWIMAGEDIGEST, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "NewRawImageDigest", NULL},
{TIFFTAG_RAWTOPREVIEWGAIN, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "RawToPreviewGain", NULL},
/* begin DNG 1.5.0.0 tags */
{TIFFTAG_DEPTHFORMAT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFormat", NULL},
{TIFFTAG_DEPTHNEAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthNear", NULL},
{TIFFTAG_DEPTHFAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthFar", NULL},
{TIFFTAG_DEPTHUNITS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthUnits", NULL},
{TIFFTAG_DEPTHMEASURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DepthMeasureType", NULL},
{TIFFTAG_ENHANCEPARAMS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EnhanceParams", NULL},
{TIFFTAG_DEPTHFORMAT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "DepthFormat", NULL},
{TIFFTAG_DEPTHNEAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "DepthNear", NULL},
{TIFFTAG_DEPTHFAR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "DepthFar", NULL},
{TIFFTAG_DEPTHUNITS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "DepthUnits", NULL},
{TIFFTAG_DEPTHMEASURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "DepthMeasureType", NULL},
{TIFFTAG_ENHANCEPARAMS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "EnhanceParams", NULL},
/* begin DNG 1.6.0.0 tags */
{TIFFTAG_PROFILEGAINTABLEMAP, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileGainTableMap", NULL},
{TIFFTAG_SEMANTICNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticName", NULL},
{TIFFTAG_SEMANTICINSTANCEID, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SemanticInstanceID", NULL},
{TIFFTAG_MASKSUBAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaskSubArea", NULL},
{TIFFTAG_RGBTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "RGBTables", NULL},
{TIFFTAG_CALIBRATIONILLUMINANT3, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant3", NULL},
{TIFFTAG_COLORMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ColorMatrix3", NULL},
{TIFFTAG_CAMERACALIBRATION3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CameraCalibration3", NULL},
{TIFFTAG_REDUCTIONMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ReductionMatrix3", NULL},
{TIFFTAG_PROFILEHUESATMAPDATA3, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData3", NULL},
{TIFFTAG_FORWARDMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ForwardMatrix3", NULL},
{TIFFTAG_ILLUMINANTDATA1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData1", NULL},
{TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL},
{TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL},
{TIFFTAG_PROFILEGAINTABLEMAP, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "ProfileGainTableMap", NULL},
{TIFFTAG_SEMANTICNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SemanticName", NULL},
{TIFFTAG_SEMANTICINSTANCEID, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SemanticInstanceID", NULL},
{TIFFTAG_MASKSUBAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "MaskSubArea", NULL},
{TIFFTAG_RGBTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "RGBTables", NULL},
{TIFFTAG_CALIBRATIONILLUMINANT3, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CalibrationIlluminant3", NULL},
{TIFFTAG_COLORMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ColorMatrix3", NULL},
{TIFFTAG_CAMERACALIBRATION3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "CameraCalibration3", NULL},
{TIFFTAG_REDUCTIONMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ReductionMatrix3", NULL},
{TIFFTAG_PROFILEHUESATMAPDATA3, -1, -1, TIFF_FLOAT, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ProfileHueSatMapData3", NULL},
{TIFFTAG_FORWARDMATRIX3, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "ForwardMatrix3", NULL},
{TIFFTAG_ILLUMINANTDATA1, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "IlluminantData1", NULL},
{TIFFTAG_ILLUMINANTDATA2, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "IlluminantData2", NULL},
{TIFFTAG_ILLUMINANTDATA3, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "IlluminantData3", NULL},
/* end DNG tags */
#endif
/* begin TIFF/EP tags */
{TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL},
{TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL},
{TIFFTAG_EP_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, FIELD_CUSTOM, 1, 0, "EP CFARepeatPatternDim", NULL},
{TIFFTAG_EP_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "EP CFAPattern", NULL},
#if 0
/* TIFFTAG_EP_BATTERYLEVEL can be RATIONAL or ASCII.
* LibTiff defines it as ASCII and converts RATIONAL to an ASCII string. */
{TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL},
{TIFFTAG_EP_INTERLACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Interlace", NULL},
{TIFFTAG_EP_BATTERYLEVEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "EP BatteryLevel", NULL},
{TIFFTAG_EP_INTERLACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP Interlace", NULL},
/* TIFFTAG_EP_IPTC_NAA and TIFFTAG_RICHTIFFIPTC share the same tag number (33723)
* LibTIFF type is UNDEFINED or BYTE, but often times incorrectly specified as LONG, because TIFF/EP (ISO/DIS 12234-2) specifies type LONG or ASCII. */
{TIFFTAG_EP_TIMEZONEOFFSET, -1, -1, TIFF_SSHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP TimeZoneOffset", NULL},
{TIFFTAG_EP_SELFTIMERMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SelfTimerMode", NULL},
{TIFFTAG_EP_FLASHENERGY, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FlashEnergy", NULL},
{TIFFTAG_EP_SPATIALFREQUENCYRESPONSE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SpatialFrequencyResponse", NULL},
{TIFFTAG_EP_NOISE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP Noise", NULL},
{TIFFTAG_EP_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneXResolution", NULL},
{TIFFTAG_EP_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneYResolution", NULL},
{TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP FocalPlaneResolutionUnit", NULL},
{TIFFTAG_EP_IMAGENUMBER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageNumber", NULL}, /* or SHORT */
{TIFFTAG_EP_SECURITYCLASSIFICATION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SecurityClassification", NULL},
{TIFFTAG_EP_IMAGEHISTORY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ImageHistory", NULL},
{TIFFTAG_EP_EXPOSUREINDEX, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureIndex", NULL},
{TIFFTAG_EP_STANDARDID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP StandardId", NULL},
{TIFFTAG_EP_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SensingMethod", NULL},
{TIFFTAG_EP_TIMEZONEOFFSET, -1, -1, TIFF_SSHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_CUSTOM, 1, 1, "EP TimeZoneOffset", NULL},
{TIFFTAG_EP_SELFTIMERMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP SelfTimerMode", NULL},
{TIFFTAG_EP_FLASHENERGY, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP FlashEnergy", NULL},
{TIFFTAG_EP_SPATIALFREQUENCYRESPONSE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "EP SpatialFrequencyResponse", NULL},
{TIFFTAG_EP_NOISE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "EP Noise", NULL},
{TIFFTAG_EP_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "EP FocalPlaneXResolution", NULL},
{TIFFTAG_EP_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "EP FocalPlaneYResolution", NULL},
{TIFFTAG_EP_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP FocalPlaneResolutionUnit", NULL},
{TIFFTAG_EP_IMAGENUMBER, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "EP ImageNumber", NULL}, /* or SHORT */
{TIFFTAG_EP_SECURITYCLASSIFICATION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "EP SecurityClassification", NULL},
{TIFFTAG_EP_IMAGEHISTORY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "EP ImageHistory", NULL},
{TIFFTAG_EP_EXPOSUREINDEX, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP ExposureIndex", NULL},
{TIFFTAG_EP_STANDARDID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "EP StandardId", NULL},
{TIFFTAG_EP_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP SensingMethod", NULL},
/* TIFF/EP tags equivalent to EXIF tags, sometimes defined differently. */
{TIFFTAG_EP_EXPOSURETIME, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureTime", NULL}, /*N=1 or 2 */
{TIFFTAG_EP_FNUMBER, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FNumber", NULL},
{TIFFTAG_EP_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ExposureProgram", NULL},
{TIFFTAG_EP_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP SpectralSensitivity", NULL},
{TIFFTAG_EP_ISOSPEEDRATINGS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ISOSpeedRatings", NULL},
{TIFFTAG_EP_OECF, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP OptoelectricConversionFactor", NULL},
{TIFFTAG_EP_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP DateTimeOriginal", NULL},
{TIFFTAG_EP_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP CompressedBitsPerPixel", NULL},
{TIFFTAG_EP_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ShutterSpeedValue", NULL},
{TIFFTAG_EP_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP ApertureValue", NULL},
{TIFFTAG_EP_BRIGHTNESSVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP BrightnessValue", NULL},
{TIFFTAG_EP_EXPOSUREBIASVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP ExposureBiasValue", NULL}, /*N=1 or 2 */
{TIFFTAG_EP_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MaxApertureValue", NULL},
{TIFFTAG_EP_SUBJECTDISTANCE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectDistance", NULL},
{TIFFTAG_EP_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP MeteringMode", NULL},
{TIFFTAG_EP_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP LightSource", NULL},
{TIFFTAG_EP_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EP Flash", NULL},
{TIFFTAG_EP_FOCALLENGTH, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP FocalLength", NULL},
{TIFFTAG_EP_SUBJECTLOCATION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "EP SubjectLocation", NULL},
{TIFFTAG_EP_EXPOSURETIME, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP ExposureTime", NULL}, /*N=1 or 2 */
{TIFFTAG_EP_FNUMBER, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP FNumber", NULL},
{TIFFTAG_EP_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP ExposureProgram", NULL},
{TIFFTAG_EP_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "EP SpectralSensitivity", NULL},
{TIFFTAG_EP_ISOSPEEDRATINGS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP ISOSpeedRatings", NULL},
{TIFFTAG_EP_OECF, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, FIELD_CUSTOM, 1, 1, "EP OptoelectricConversionFactor", NULL},
{TIFFTAG_EP_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "EP DateTimeOriginal", NULL},
{TIFFTAG_EP_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "EP CompressedBitsPerPixel", NULL},
{TIFFTAG_EP_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "EP ShutterSpeedValue", NULL},
{TIFFTAG_EP_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "EP ApertureValue", NULL},
{TIFFTAG_EP_BRIGHTNESSVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP BrightnessValue", NULL},
{TIFFTAG_EP_EXPOSUREBIASVALUE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP ExposureBiasValue", NULL}, /*N=1 or 2 */
{TIFFTAG_EP_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "EP MaxApertureValue", NULL},
{TIFFTAG_EP_SUBJECTDISTANCE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP SubjectDistance", NULL},
{TIFFTAG_EP_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP MeteringMode", NULL},
{TIFFTAG_EP_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP LightSource", NULL},
{TIFFTAG_EP_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "EP Flash", NULL},
{TIFFTAG_EP_FOCALLENGTH, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "EP FocalLength", NULL},
{TIFFTAG_EP_SUBJECTLOCATION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_CUSTOM, 1, 1, "EP SubjectLocation", NULL},
/* end TIFF/EP tags */
#endif
/* begin TIFF/FX tags */
{TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Indexed", NULL},
{TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GlobalParametersIFD", NULL},
{TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ProfileType", NULL},
{TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FaxProfile", NULL},
{TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CodingMethods", NULL},
{TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "VersionYear", NULL},
{TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ModeNumber", NULL},
{TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Decode", NULL},
{TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ImageBaseColor", NULL},
{TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "T82Options", NULL},
{TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "StripRowCounts", NULL},
{TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageLayer", NULL},
{TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "Indexed", NULL},
{TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, FIELD_CUSTOM, 1, 0, "GlobalParametersIFD", NULL},
{TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ProfileType", NULL},
{TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "FaxProfile", NULL},
{TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "CodingMethods", NULL},
{TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "VersionYear", NULL},
{TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "ModeNumber", NULL},
{TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, FIELD_CUSTOM, 1, 1, "Decode", NULL},
{TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_CUSTOM, 1, 1, "ImageBaseColor", NULL},
{TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "T82Options", NULL},
{TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, FIELD_CUSTOM, 1, 1, "StripRowCounts", NULL},
{TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, FIELD_CUSTOM, 1, 0, "ImageLayer", NULL},
/* end TIFF/FX tags */
/* begin pseudo tags */
};
@@ -348,91 +348,91 @@ static const TIFFField tiffFields[] = {
* EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019)
*/
static const TIFFField exifFields[] = {
{EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL},
{EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL},
{EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL},
{EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL},
{EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL},
{EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "FNumber", NULL},
{EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL},
{EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL},
/* After EXIF 2.2.1 ISOSpeedRatings is named PhotographicSensitivity. In addition, while "Count=Any", only 1 count should be used. */
{EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL},
{EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL},
{EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL},
{EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL},
{EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL},
{EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL},
{EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL},
{EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL},
{EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL},
{EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL},
{EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL},
{EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL},
{EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL},
{EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL},
{EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL},
{EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL},
{EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL},
{EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL},
{EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL},
{EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL},
{EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL},
{EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL},
{EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL},
{EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL},
{EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL},
{EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL},
{EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL},
{EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL},
{EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL},
{EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL},
{EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL},
{EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL},
{EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL},
{EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL},
{EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL},
{EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL},
{EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL},
{EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL},
{EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL},
{EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL},
{EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL},
{EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL},
/*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance!
* However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values,
* which are not treated within LibTiff!! */
{EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL},
{EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL},
{EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL},
{EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL},
{EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL},
{EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL},
{EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL},
{EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL},
{EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL},
{EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL},
{EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL},
{EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL},
{EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL},
{EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL},
{EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL},
{EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL},
{EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL},
{EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL},
{EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL},
{EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL},
{EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL},
{EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL},
{EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL},
{EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL},
{EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL},
{EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL},
{EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL},
{EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL},
{EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL},
{EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL},
{EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL},
{EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL},
{EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL},
{EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL},
{EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL},
{EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL},
{EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL},
{EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL},
{EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL},
{EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL},
{EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL},
{EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL},
{EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL},
{EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL},
{EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL},
{EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL},
{EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL},
{EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL},
{EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL},
{EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL},
{EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL},
{EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL},
{EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL},
{EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL},
{EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL},
{EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1,
{EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL},
{EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL},
{EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "LightSource", NULL},
{EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "Flash", NULL},
{EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "FocalLength", NULL},
{EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL},
{EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "MakerNote", NULL},
{EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "UserComment", NULL},
{EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL},
{EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL},
{EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL},
{EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "Temperature", NULL},
{EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "Humidity", NULL},
{EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "Pressure", NULL},
{EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL},
{EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "Acceleration", NULL},
{EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL},
{EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL},
{EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL},
{EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL},
{EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL},
{EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL},
{EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL},
{EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL},
{EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL},
{EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL},
{EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL},
{EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL},
{EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL},
{EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL},
{EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "FileSource", NULL},
{EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "SceneType", NULL},
{EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL},
{EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL},
{EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL},
{EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL},
{EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL},
{EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL},
{EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL},
{EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "GainControl", NULL},
{EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "Contrast", NULL},
{EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "Saturation", NULL},
{EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "Sharpness", NULL},
{EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL},
{EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL},
{EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL},
{EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL},
{EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL},
{EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL},
{EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "LensMake", NULL},
{EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "LensModel", NULL},
{EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL},
{EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, FIELD_CUSTOM, 1, 0, "Gamma", NULL},
{EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL},
{EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL},
{EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1,
"SourceExposureTimesOfCompositeImage", NULL}};
/*
* EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May
@@ -445,38 +445,38 @@ static const TIFFField gpsFields[] = {
* In order to achieve double precision for GPS tags: Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE
* and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE.
*/
{GPSTAG_VERSIONID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "VersionID", NULL},
{GPSTAG_LATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LatitudeRef", NULL},
{GPSTAG_LATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Latitude", NULL},
{GPSTAG_LONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LongitudeRef", NULL},
{GPSTAG_LONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Longitude", NULL},
{GPSTAG_ALTITUDEREF, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AltitudeRef", NULL},
{GPSTAG_ALTITUDE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Altitude", NULL},
{GPSTAG_TIMESTAMP, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TimeStamp", NULL},
{GPSTAG_SATELLITES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Satellites", NULL},
{GPSTAG_STATUS, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Status", NULL},
{GPSTAG_MEASUREMODE, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeasureMode", NULL},
{GPSTAG_DOP, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DOP", NULL},
{GPSTAG_SPEEDREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpeedRef", NULL},
{GPSTAG_SPEED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Speed", NULL},
{GPSTAG_TRACKREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TrackRef", NULL},
{GPSTAG_TRACK, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Track", NULL},
{GPSTAG_IMGDIRECTIONREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirectionRef", NULL},
{GPSTAG_IMGDIRECTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirection", NULL},
{GPSTAG_MAPDATUM, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MapDatum", NULL},
{GPSTAG_DESTLATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitudeRef", NULL},
{GPSTAG_DESTLATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitude", NULL},
{GPSTAG_DESTLONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitudeRef", NULL},
{GPSTAG_DESTLONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitude", NULL},
{GPSTAG_DESTBEARINGREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearingRef", NULL},
{GPSTAG_DESTBEARING, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearing", NULL},
{GPSTAG_DESTDISTANCEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistanceRef", NULL},
{GPSTAG_DESTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistance", NULL},
{GPSTAG_PROCESSINGMETHOD, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProcessingMethod", NULL},
{GPSTAG_AREAINFORMATION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AreaInformation", NULL},
{GPSTAG_DATESTAMP, 11, 11, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateStamp", NULL},
{GPSTAG_DIFFERENTIAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Differential", NULL},
{GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}};
{GPSTAG_VERSIONID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, FIELD_CUSTOM, 1, 0, "VersionID", NULL},
{GPSTAG_LATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "LatitudeRef", NULL},
{GPSTAG_LATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, FIELD_CUSTOM, 1, 0, "Latitude", NULL},
{GPSTAG_LONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "LongitudeRef", NULL},
{GPSTAG_LONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, FIELD_CUSTOM, 1, 0, "Longitude", NULL},
{GPSTAG_ALTITUDEREF, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "AltitudeRef", NULL},
{GPSTAG_ALTITUDE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "Altitude", NULL},
{GPSTAG_TIMESTAMP, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, FIELD_CUSTOM, 1, 0, "TimeStamp", NULL},
{GPSTAG_SATELLITES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Satellites", NULL},
{GPSTAG_STATUS, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "Status", NULL},
{GPSTAG_MEASUREMODE, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "MeasureMode", NULL},
{GPSTAG_DOP, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "DOP", NULL},
{GPSTAG_SPEEDREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "SpeedRef", NULL},
{GPSTAG_SPEED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "Speed", NULL},
{GPSTAG_TRACKREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "TrackRef", NULL},
{GPSTAG_TRACK, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "Track", NULL},
{GPSTAG_IMGDIRECTIONREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "ImgDirectionRef", NULL},
{GPSTAG_IMGDIRECTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "ImgDirection", NULL},
{GPSTAG_MAPDATUM, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "MapDatum", NULL},
{GPSTAG_DESTLATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DestLatitudeRef", NULL},
{GPSTAG_DESTLATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, FIELD_CUSTOM, 1, 0, "DestLatitude", NULL},
{GPSTAG_DESTLONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DestLongitudeRef", NULL},
{GPSTAG_DESTLONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, FIELD_CUSTOM, 1, 0, "DestLongitude", NULL},
{GPSTAG_DESTBEARINGREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DestBearingRef", NULL},
{GPSTAG_DESTBEARING, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "DestBearing", NULL},
{GPSTAG_DESTDISTANCEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DestDistanceRef", NULL},
{GPSTAG_DESTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "DestDistance", NULL},
{GPSTAG_PROCESSINGMETHOD, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "ProcessingMethod", NULL},
{GPSTAG_AREAINFORMATION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1, 1, "AreaInformation", NULL},
{GPSTAG_DATESTAMP, 11, 11, TIFF_ASCII, 0, TIFF_SETGET_ASCII, FIELD_CUSTOM, 1, 0, "DateStamp", NULL},
{GPSTAG_DIFFERENTIAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, FIELD_CUSTOM, 1, 0, "Differential", NULL},
{GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", NULL}};
/* clang-format on */ /* was off for better readability of tag comments */
static const TIFFFieldArray tiffFieldArray = {
@@ -674,18 +674,19 @@ int TIFFFieldSetGetSize(const TIFFField *fip)
{
/*
* TIFFSetField() and TIFFGetField() must provide the parameter accordingly
* to the definition of "set_field_type" of the tag definition in
* to the definition of "set_get_field_type" of the tag definition in
* dir_info.c. This function returns the data size for that purpose.
*
* Furthermore, this data size is also used for the internal storage,
* even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored
* internally as 4-byte float, but some of them should be stored internally
* as 8-byte double, depending on the "set_field_type" _FLOAT_ or _DOUBLE_.
* as 8-byte double, depending on the "set_get_field_type" _FLOAT_ or
* _DOUBLE_.
*/
if (fip == NULL)
return 0;
switch (fip->set_field_type)
switch (fip->set_get_field_type)
{
case TIFF_SETGET_UNDEFINED:
case TIFF_SETGET_ASCII:
@@ -758,7 +759,7 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip)
if (fip == NULL)
return 0;
switch (fip->set_field_type)
switch (fip->set_get_field_type)
{
case TIFF_SETGET_C16_ASCII:
case TIFF_SETGET_C16_UINT8:
@@ -793,7 +794,7 @@ int TIFFFieldSetGetCountSize(const TIFFField *fip)
const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
{
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL};
TIFFField *pkey = &key;
const TIFFField **ret;
if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
@@ -817,7 +818,7 @@ const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt)
static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name,
TIFFDataType dt)
{
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, NULL, NULL};
TIFFField *pkey = &key;
const TIFFField **ret;
if (tif->tif_foundfield &&
@@ -915,59 +916,46 @@ TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag,
{
case TIFF_BYTE:
case TIFF_UNDEFINED:
fld->set_field_type = TIFF_SETGET_C32_UINT8;
fld->get_field_type = TIFF_SETGET_C32_UINT8;
fld->set_get_field_type = TIFF_SETGET_C32_UINT8;
break;
case TIFF_ASCII:
fld->set_field_type = TIFF_SETGET_C32_ASCII;
fld->get_field_type = TIFF_SETGET_C32_ASCII;
fld->set_get_field_type = TIFF_SETGET_C32_ASCII;
break;
case TIFF_SHORT:
fld->set_field_type = TIFF_SETGET_C32_UINT16;
fld->get_field_type = TIFF_SETGET_C32_UINT16;
fld->set_get_field_type = TIFF_SETGET_C32_UINT16;
break;
case TIFF_LONG:
fld->set_field_type = TIFF_SETGET_C32_UINT32;
fld->get_field_type = TIFF_SETGET_C32_UINT32;
fld->set_get_field_type = TIFF_SETGET_C32_UINT32;
break;
case TIFF_RATIONAL:
case TIFF_SRATIONAL:
case TIFF_FLOAT:
fld->set_field_type = TIFF_SETGET_C32_FLOAT;
fld->get_field_type = TIFF_SETGET_C32_FLOAT;
fld->set_get_field_type = TIFF_SETGET_C32_FLOAT;
break;
case TIFF_SBYTE:
fld->set_field_type = TIFF_SETGET_C32_SINT8;
fld->get_field_type = TIFF_SETGET_C32_SINT8;
fld->set_get_field_type = TIFF_SETGET_C32_SINT8;
break;
case TIFF_SSHORT:
fld->set_field_type = TIFF_SETGET_C32_SINT16;
fld->get_field_type = TIFF_SETGET_C32_SINT16;
fld->set_get_field_type = TIFF_SETGET_C32_SINT16;
break;
case TIFF_SLONG:
fld->set_field_type = TIFF_SETGET_C32_SINT32;
fld->get_field_type = TIFF_SETGET_C32_SINT32;
fld->set_get_field_type = TIFF_SETGET_C32_SINT32;
break;
case TIFF_DOUBLE:
fld->set_field_type = TIFF_SETGET_C32_DOUBLE;
fld->get_field_type = TIFF_SETGET_C32_DOUBLE;
fld->set_get_field_type = TIFF_SETGET_C32_DOUBLE;
break;
case TIFF_IFD:
case TIFF_IFD8:
fld->set_field_type = TIFF_SETGET_C32_IFD8;
fld->get_field_type = TIFF_SETGET_C32_IFD8;
fld->set_get_field_type = TIFF_SETGET_C32_IFD8;
break;
case TIFF_LONG8:
fld->set_field_type = TIFF_SETGET_C32_UINT64;
fld->get_field_type = TIFF_SETGET_C32_UINT64;
fld->set_get_field_type = TIFF_SETGET_C32_UINT64;
break;
case TIFF_SLONG8:
fld->set_field_type = TIFF_SETGET_C32_SINT64;
fld->get_field_type = TIFF_SETGET_C32_SINT64;
fld->set_get_field_type = TIFF_SETGET_C32_SINT64;
break;
default:
fld->set_field_type = TIFF_SETGET_UNDEFINED;
fld->get_field_type = TIFF_SETGET_UNDEFINED;
fld->set_get_field_type = TIFF_SETGET_UNDEFINED;
break;
}
fld->field_bit = FIELD_CUSTOM;
@@ -1198,38 +1186,51 @@ int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n)
{
tp->field_tag = info[i].field_tag;
if (info[i].field_readcount < TIFF_VARIABLE2 ||
info[i].field_readcount == 0 ||
info[i].field_writecount < TIFF_VARIABLE2 ||
info[i].field_writecount == 0)
info[i].field_writecount < TIFF_VARIABLE2)
{
/* The fields (field_readcount) and (field_writecount) may use the
* values TIFF_VARIABLE (-1), TIFF_SPP (-2), TIFF_VARIABLE2 (-3). */
TIFFErrorExtR(tif, module,
"The value of field_readcount and field_writecount "
"must be greater than or equal to -3 and not zero.");
TIFFErrorExtR(
tif, module,
"The value of field_readcount %d and field_writecount %d "
"must be greater than or equal to -3.",
info[i].field_readcount, info[i].field_writecount);
return -1;
}
if ((info[i].field_readcount == 0 || info[i].field_writecount == 0) &&
info[i].field_bit != FIELD_IGNORE)
{
/* The fields (field_readcount) and (field_writecount) may only
be zero for pseudo_tags or ignored tags. */
TIFFErrorExtR(
tif, module,
"The value of field_readcount %d and field_writecount %d "
"may only be zero for field_bit = 0 (i.e. ignored tags).",
info[i].field_readcount, info[i].field_writecount);
return -1;
}
tp->field_readcount = info[i].field_readcount;
tp->field_writecount = info[i].field_writecount;
tp->field_type = info[i].field_type;
tp->field_anonymous = 0;
tp->set_field_type =
tp->set_get_field_type =
_TIFFSetGetType(info[i].field_type, info[i].field_writecount,
info[i].field_passcount);
tp->get_field_type =
_TIFFSetGetType(info[i].field_type, info[i].field_readcount,
info[i].field_passcount);
tp->field_bit = info[i].field_bit;
tp->field_oktochange = info[i].field_oktochange;
tp->field_passcount = info[i].field_passcount;
/* Define an empty static string to be passed as field_name where a NULL
* pointer is passed in. Otherwise, this will lead to buffer overflow
* furtheron. */
if (info[i].field_name == NULL)
{
TIFFErrorExtR(tif, module,
"Field_name of %d.th allocation tag %d is NULL", i,
info[i].field_tag);
return -1;
static const char *string_static_empty = "";
tp->field_name = (char *)string_static_empty;
}
else
{
tp->field_name = info[i].field_name;
}
tp->field_name = info[i].field_name;
tp->field_subfields = NULL;
tp++;
}
+31 -19
View File
@@ -47,6 +47,9 @@
#define TIFFCvtIEEEFloatToNative(tif, n, fp)
#define TIFFCvtIEEEDoubleToNative(tif, n, dp)
#else
/* If your machine does not support IEEE floating point then you will need to
* add support to tif_machdep.c to convert between the native format and
* IEEE format. */
extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *);
extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *);
#endif
@@ -2781,7 +2784,7 @@ TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value)
case TIFF_FLOAT:
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfLong((uint32_t *)origdata, count);
TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata);
TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata);
*value = (float *)origdata;
return (TIFFReadDirEntryErrOk);
}
@@ -4310,7 +4313,6 @@ int TIFFReadDirectory(TIFF *tif)
tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
/* free any old stuff and reinit */
(*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
TIFFFreeDirectory(tif);
TIFFDefaultDirectory(tif);
@@ -4403,10 +4405,13 @@ int TIFFReadDirectory(TIFF *tif)
TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
if (fii == FAILED_FII)
{
TIFFWarningExtR(tif, module,
"Unknown field with tag %" PRIu16 " (0x%" PRIx16
") encountered",
dp->tdir_tag, dp->tdir_tag);
if (tif->tif_warn_about_unknown_tags)
{
TIFFWarningExtR(tif, module,
"Unknown field with tag %" PRIu16
" (0x%" PRIx16 ") encountered",
dp->tdir_tag, dp->tdir_tag);
}
/* the following knowingly leaks the
anonymous field structure */
const TIFFField *fld = _TIFFCreateAnonField(
@@ -5281,6 +5286,7 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
const TIFFField *fip;
uint32_t fii;
assert(infoarray != NULL);
dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL);
if (!dircount)
{
@@ -5313,7 +5319,6 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
}
/* Free any old stuff and reinit. */
(*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
TIFFFreeDirectory(tif);
/* Even if custom directories do not need the default settings of a standard
* IFD, the pointer to the TIFFSetField() and TIFFGetField() (i.e.
@@ -5344,18 +5349,25 @@ int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff,
TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii);
if (fii == FAILED_FII)
{
TIFFWarningExtR(tif, module,
"Unknown field with tag %" PRIu16 " (0x%" PRIx16
") encountered",
dp->tdir_tag, dp->tdir_tag);
if (tif->tif_warn_about_unknown_tags)
{
TIFFWarningExtR(tif, module,
"Unknown field with tag %" PRIu16 " (0x%" PRIx16
") encountered",
dp->tdir_tag, dp->tdir_tag);
}
const TIFFField *fld = _TIFFCreateAnonField(
tif, dp->tdir_tag, (TIFFDataType)dp->tdir_type);
if (fld == NULL || !_TIFFMergeFields(tif, fld, 1))
{
TIFFWarningExtR(tif, module,
"Registering anonymous field with tag %" PRIu16
" (0x%" PRIx16 ") failed",
dp->tdir_tag, dp->tdir_tag);
if (tif->tif_warn_about_unknown_tags)
{
TIFFWarningExtR(
tif, module,
"Registering anonymous field with tag %" PRIu16
" (0x%" PRIx16 ") failed",
dp->tdir_tag, dp->tdir_tag);
}
dp->tdir_ignore = TRUE;
}
else
@@ -6273,19 +6285,19 @@ static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover)
}
fip = tif->tif_fields[fii];
assert(fip != NULL); /* should not happen */
assert(fip->set_field_type !=
assert(fip->set_get_field_type !=
TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with
this in specialized code */
assert(fip->set_field_type !=
assert(fip->set_get_field_type !=
TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only
the case for pseudo-tags */
err = TIFFReadDirEntryErrOk;
switch (fip->set_field_type)
switch (fip->set_get_field_type)
{
case TIFF_SETGET_UNDEFINED:
TIFFErrorExtR(
tif, "TIFFFetchNormalTag",
"Defined set_field_type of custom tag %u (%s) is "
"Defined set_get_field_type of custom tag %u (%s) is "
"TIFF_SETGET_UNDEFINED and thus tag is not read from file",
fip->field_tag, fip->field_name);
break;
+30 -17
View File
@@ -35,6 +35,9 @@
#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
#else
/* If your machine does not support IEEE floating point then you will need to
* add support to tif_machdep.c to convert between the native format and
* IEEE format. */
extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp);
extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp);
#endif
@@ -534,6 +537,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
{
_TIFFfreeExt(tif, tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawcp = NULL;
tif->tif_rawcc = 0;
tif->tif_rawdatasize = 0;
tif->tif_rawdataoff = 0;
@@ -562,6 +566,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
tif->tif_dir.td_dirdatasize_write = 0;
if (isimage)
{
/*-- Step 1: Process named tags for an image with FIELD bits
* associated. --*/
if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
{
if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir,
@@ -860,6 +866,10 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir))
goto bad;
}
/*-- Step 2: Process named tags for an image with FIELD bits
added by a codec.
Attention: There is only code for some field_types,
which are actually used by current codecs. --*/
{
uint32_t n;
for (n = 0; n < tif->tif_nfields; n++)
@@ -869,7 +879,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
if ((o->field_bit >= FIELD_CODEC) &&
(TIFFFieldSet(tif, o->field_bit)))
{
switch (o->set_field_type)
switch (o->set_get_field_type)
{
case TIFF_SETGET_ASCII:
{
@@ -879,7 +889,7 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
assert(o->field_readcount == TIFF_VARIABLE);
assert(o->field_passcount == 0);
TIFFGetField(tif, o->field_tag, &pb);
pa = (uint32_t)(strlen(pb));
pa = (uint32_t)(strlen(pb) + 1);
if (!TIFFWriteDirectoryTagAscii(
tif, &ndir, dir, (uint16_t)o->field_tag,
pa, pb))
@@ -938,6 +948,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
}
}
}
/*-- Step 3: Process custom tags without FIELD bit for an image
* or for custom IFDs (e.g. EXIF) with !isimage. --*/
for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
{
uint16_t tag =
@@ -1008,7 +1020,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
case TIFF_RATIONAL:
{
/*-- Rational2Double: For Rationals evaluate
* "set_field_type" to determine internal storage size. */
* "set_get_field_type" to determine internal storage size.
*/
int tv_size;
tv_size = TIFFFieldSetGetSize(
tif->tif_dir.td_customValues[m].info);
@@ -1030,11 +1043,11 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
* tv_size==4 should be set as default. */
if (tv_size != 4)
{
TIFFErrorExtR(tif,
"TIFFLib: _TIFFWriteDirectorySec()",
"Rational2Double: .set_field_type is "
"not 4 but %d",
tv_size);
TIFFErrorExtR(
tif, "TIFFLib: _TIFFWriteDirectorySec()",
"Rational2Double: .set_get_field_type is "
"not 4 but %d",
tv_size);
}
}
}
@@ -1042,7 +1055,8 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
case TIFF_SRATIONAL:
{
/*-- Rational2Double: For Rationals evaluate
* "set_field_type" to determine internal storage size. */
* "set_get_field_type" to determine internal storage size.
*/
int tv_size;
tv_size = TIFFFieldSetGetSize(
tif->tif_dir.td_customValues[m].info);
@@ -1064,11 +1078,11 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
* tv_size==4 should be set as default. */
if (tv_size != 4)
{
TIFFErrorExtR(tif,
"TIFFLib: _TIFFWriteDirectorySec()",
"Rational2Double: .set_field_type is "
"not 4 but %d",
tv_size);
TIFFErrorExtR(
tif, "TIFFLib: _TIFFWriteDirectorySec()",
"Rational2Double: .set_get_field_type is "
"not 4 but %d",
tv_size);
}
}
}
@@ -1369,7 +1383,6 @@ static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
TIFFFreeDirectory(tif);
tif->tif_flags &= ~TIFF_DIRTYDIRECT;
tif->tif_flags &= ~TIFF_DIRTYSTRIP;
(*tif->tif_cleanup)(tif);
/* Reset directory-related state for subsequent directories. */
TIFFCreateDirectory(tif);
}
@@ -2958,7 +2971,7 @@ static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
EvaluateIFDdatasizeWrite(tif, count, 4, ndir);
return 1;
}
TIFFCvtNativeToIEEEFloat(tif, count, &value);
TIFFCvtNativeToIEEEFloat(tif, count, value);
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfFloat(value, count);
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
@@ -2977,7 +2990,7 @@ static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
EvaluateIFDdatasizeWrite(tif, count, 8, ndir);
return 1;
}
TIFFCvtNativeToIEEEDouble(tif, count, &value);
TIFFCvtNativeToIEEEDouble(tif, count, value);
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabArrayOfDouble(value, count);
return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
+92 -35
View File
@@ -87,6 +87,10 @@ typedef struct
int EOLcnt; /* count of EOL codes recognized */
int eofReachedCount; /* number of times decode has been called with
EOF already reached */
int eolReachedCount; /* number of times decode has been called with
EOL already reached */
int unexpectedReachedCount; /* number of times decode has been called with
"unexpedted" already reached */
TIFFFaxFillFunc fill; /* fill routine */
uint32_t *runs; /* b&w runs for current/previous row */
uint32_t nruns; /* size of the refruns / curruns arrays */
@@ -174,6 +178,8 @@ static int Fax3PreDecode(TIFF *tif, uint16_t s)
sp->data = 0;
sp->EOLcnt = 0; /* force initial scan for EOL */
sp->eofReachedCount = 0;
sp->eolReachedCount = 0;
sp->unexpectedReachedCount = 0;
/*
* Decoder assumes lsb-to-msb bit order. Note that we select
* this here rather than in Fax3SetupState so that viewers can
@@ -209,7 +215,12 @@ static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line,
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
}
#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0)
#define unexpected(table, a0) \
do \
{ \
Fax3Unexpected(module, tif, sp->line, a0); \
++sp->unexpectedReachedCount; \
} while (0)
static void Fax3Extension(const char *module, TIFF *tif, uint32_t line,
uint32_t a0)
@@ -233,7 +244,12 @@ static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line,
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0,
lastx);
}
#define badlength(a0, lastx) Fax3BadLength(module, tif, sp->line, a0, lastx)
#define badlength(a0, lastx) \
do \
{ \
Fax3BadLength(module, tif, sp->line, a0, lastx); \
++sp->eolReachedCount; \
} while (0)
static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
uint32_t a0)
@@ -251,8 +267,55 @@ static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
++sp->eofReachedCount; \
} while (0)
static void Fax3TryG3WithoutEOL(const char *module, TIFF *tif, uint32_t line,
uint32_t a0)
{
TIFFWarningExtR(
tif, module,
"Try to decode (read) fax Group 3 data without EOL at line %" PRIu32
" of %s %" PRIu32 " (x %" PRIu32 "). Please check result",
line, isTiled(tif) ? "tile" : "strip",
(isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
}
#define tryG3WithoutEOL(a0) \
do \
{ \
Fax3TryG3WithoutEOL(module, tif, sp->line, a0); \
} while (0)
#define Nop
static int CheckReachedCounters(TIFF *tif, const char *module,
Fax3CodecState *sp)
{
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
{
TIFFErrorExtR(tif, module,
"End of file (EOF) has already been reached %d times "
"within that %s.",
sp->eofReachedCount, isTiled(tif) ? "tile" : "strip");
return (-1);
}
if (sp->eolReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
{
TIFFErrorExtR(tif, module,
"Bad line length (EOL) has already been reached %d times "
"within that %s",
sp->eolReachedCount, isTiled(tif) ? "tile" : "strip");
return (-1);
}
if (sp->unexpectedReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
{
TIFFErrorExtR(tif, module,
"Bad code word (unexpected) has already been reached %d "
"times within that %s",
sp->unexpectedReachedCount,
isTiled(tif) ? "tile" : "strip");
return (-1);
}
return (0);
}
/**
* Decode the requested amount of G3 1D-encoded data.
* @param buf destination buffer
@@ -269,14 +332,9 @@ static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return (-1);
}
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
{
TIFFErrorExtR(
tif, module,
"End of file has already been reached %d times within that strip",
sp->eofReachedCount);
if (CheckReachedCounters(tif, module, sp))
return (-1);
}
RETRY_WITHOUT_EOL_1D:
CACHE_STATE(tif, sp);
thisrun = sp->curruns;
while (occ > 0)
@@ -289,7 +347,7 @@ static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
printf("-------------------- %" PRIu32 "\n", tif->tif_row);
fflush(stdout);
#endif
SYNC_EOL(EOF1D);
SYNC_EOL(EOF1D, RETRY_WITHOUT_EOL_1D);
EXPAND1D(EOF1Da);
(*sp->fill)(buf, thisrun, pa, lastx);
buf += sp->b.rowbytes;
@@ -327,14 +385,9 @@ static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return (-1);
}
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
{
TIFFErrorExtR(
tif, module,
"End of file has already been reached %d times within that strip",
sp->eofReachedCount);
if (CheckReachedCounters(tif, module, sp))
return (-1);
}
RETRY_WITHOUT_EOL_2D:
CACHE_STATE(tif, sp);
while (occ > 0)
{
@@ -345,7 +398,7 @@ static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d EOLcnt = %d", BitAcc,
BitsAvail, EOLcnt);
#endif
SYNC_EOL(EOF2D);
SYNC_EOL(EOF2D, RETRY_WITHOUT_EOL_2D);
NeedBits8(1, EOF2D);
is1D = GetBits(1); /* 1D/2D-encoding tag bit */
ClrBits(1);
@@ -535,6 +588,15 @@ static int Fax3SetupState(TIFF *tif)
"Bits/sample must be 1 for Group 3/4 encoding/decoding");
return (0);
}
if (td->td_samplesperpixel != 1 &&
td->td_planarconfig != PLANARCONFIG_SEPARATE)
{
TIFFErrorExtR(
tif, module,
"Samples/pixel shall be 1 for Group 3/4 encoding/decoding, "
"or PlanarConfiguration must be set to Separate.");
return 0;
}
/*
* Calculate the scanline/tile widths.
*/
@@ -1275,24 +1337,23 @@ static void Fax3Cleanup(TIFF *tif)
#define FIELD_OPTIONS (FIELD_CODEC + 7)
static const TIFFField faxFields[] = {
{TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL},
{TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL},
{TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, FALSE,
FALSE, "FaxMode", NULL},
{TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, FIELD_PSEUDO,
FALSE, FALSE, "FaxFillFunc", NULL},
{TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL},
FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL},
{TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL},
FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL},
{TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines",
NULL}};
FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL}};
static const TIFFField fax3Fields[] = {
{TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL},
FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL},
};
static const TIFFField fax4Fields[] = {
{TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL},
FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL},
};
static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap)
@@ -1555,14 +1616,8 @@ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return (-1);
}
if (sp->eofReachedCount >= EOF_REACHED_COUNT_THRESHOLD)
{
TIFFErrorExtR(
tif, module,
"End of file has already been reached %d times within that strip",
sp->eofReachedCount);
if (CheckReachedCounters(tif, module, sp))
return (-1);
}
CACHE_STATE(tif, sp);
int start = sp->line;
while (occ > 0)
@@ -1707,6 +1762,8 @@ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
return (-1);
}
if (CheckReachedCounters(tif, module, sp))
return (-1);
CACHE_STATE(tif, sp);
thisrun = sp->curruns;
while (occ > 0)
+25 -16
View File
@@ -289,30 +289,39 @@ static const char *StateNames[] = {
* is non-zero then we still need to scan for the final flag
* bit that is part of the EOL code.
*/
#define SYNC_EOL(eoflab) \
#define SYNC_EOL(eoflab, retrywithouteol) \
do \
{ \
if (EOLcnt == 0) \
if (!(sp->b.mode & FAXMODE_NOEOL)) /* skip EOL, if not present */ \
{ \
if (EOLcnt == 0) \
{ \
for (;;) \
{ \
NeedBits16(11, eoflab); \
if (GetBits(11) == 0) \
break; /* EOL found */ \
ClrBits(1); \
} \
} \
/* Now move after EOL or detect missing EOL. */ \
for (;;) \
{ \
NeedBits16(11, eoflab); \
if (GetBits(11) == 0) \
NeedBits8(8, noEOLFound); \
if (GetBits(8)) \
break; \
ClrBits(1); \
ClrBits(8); \
} \
while (GetBits(1) == 0) \
ClrBits(1); \
ClrBits(1); /* EOL bit */ \
EOLcnt = 0; /* reset EOL counter/flag */ \
break; /* existing EOL skipped, leave macro */ \
noEOLFound: \
sp->b.mode |= FAXMODE_NOEOL; \
tryG3WithoutEOL(a0); \
goto retrywithouteol; \
} \
for (;;) \
{ \
NeedBits8(8, eoflab); \
if (GetBits(8)) \
break; \
ClrBits(8); \
} \
while (GetBits(1) == 0) \
ClrBits(1); \
ClrBits(1); /* EOL bit */ \
EOLcnt = 0; /* reset EOL counter/flag */ \
} while (0)
/*
+160 -37
View File
@@ -600,6 +600,27 @@ int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
"No \"put\" routine setupl; probably can not handle image format");
return (0);
}
/* Verify raster height against image height.
* Width is checked in img->get() function individually. */
if (0 <= img->row_offset && (uint32_t)img->row_offset < img->height)
{
uint32_t hx = img->height - img->row_offset;
if (h > hx)
{
/* Adapt parameters to read only available lines and put image
* at the bottom of the raster. */
raster += (size_t)(h - hx) * w;
h = hx;
}
}
else
{
TIFFErrorExtR(img->tif, TIFFFileName(img->tif),
"Error in TIFFRGBAImageGet: row offset %d exceeds "
"image height %d",
img->row_offset, img->height);
return 0;
}
return (*img->get)(img, raster, w, h);
}
@@ -614,12 +635,10 @@ int TIFFReadRGBAImageOriented(TIFF *tif, uint32_t rwidth, uint32_t rheight,
TIFFRGBAImage img;
int ok;
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg))
if (TIFFRGBAImageBegin(&img, tif, stop, emsg))
{
img.req_orientation = (uint16_t)orientation;
/* XXX verify rwidth and rheight against width and height */
ok = TIFFRGBAImageGet(&img, raster + (rheight - img.height) * rwidth,
rwidth, img.height);
ok = TIFFRGBAImageGet(&img, raster, rwidth, rheight);
TIFFRGBAImageEnd(&img);
}
else
@@ -726,6 +745,22 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
uint32_t leftmost_tw;
tmsize_t bufsize;
/* If the raster is smaller than the image,
* or if there is a col_offset, adapt the samples to be copied per row. */
uint32_t wmin;
if (0 <= img->col_offset && (uint32_t)img->col_offset < img->width)
{
wmin = TIFFmin(w, img->width - img->col_offset);
}
else
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Error in gtTileContig: column offset %d exceeds "
"image width %d",
img->col_offset, img->width);
return 0;
}
bufsize = TIFFTileSize(tif);
if (bufsize == 0)
{
@@ -739,7 +774,7 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
flip = setorientation(img);
if (flip & FLIP_VERTICALLY)
{
if ((tw + w) > INT_MAX)
if (((int64_t)tw + w) > INT_MAX)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
"unsupported tile size (too wide)");
@@ -750,7 +785,7 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
}
else
{
if (tw > (INT_MAX + w))
if (tw > ((int64_t)INT_MAX + w))
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
"unsupported tile size (too wide)");
@@ -771,7 +806,14 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
*/
leftmost_fromskew = img->col_offset % tw;
leftmost_tw = tw - leftmost_fromskew;
leftmost_toskew = toskew + leftmost_fromskew;
int64_t skew_i64 = (int64_t)toskew + leftmost_fromskew;
if (skew_i64 > INT_MAX || skew_i64 < INT_MIN)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s %" PRId64, "Invalid skew",
skew_i64);
return (0);
}
leftmost_toskew = (int32_t)skew_i64;
for (row = 0; ret != 0 && row < h; row += nrow)
{
rowstoread = th - (row + img->row_offset) % th;
@@ -781,7 +823,8 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
this_toskew = leftmost_toskew;
tocol = 0;
col = img->col_offset;
while (tocol < w)
/* wmin: only write imagewidth if raster is bigger. */
while (tocol < wmin)
{
if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col,
row + img->row_offset, 0,
@@ -793,12 +836,12 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
}
pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) +
((tmsize_t)fromskew * img->samplesperpixel);
if (tocol + this_tw > w)
if (tocol + this_tw > wmin)
{
/*
* Rightmost tile is clipped on right side.
*/
fromskew = tw - (w - tocol);
fromskew = tw - (wmin - tocol);
this_tw = tw - fromskew;
this_toskew = toskew + fromskew;
}
@@ -827,7 +870,9 @@ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
for (line = 0; line < h; line++)
{
uint32_t *left = raster + (line * w);
uint32_t *right = left + w - 1;
/* Use wmin to only flip horizontally data in place and not complete
* raster-row. */
uint32_t *right = left + wmin - 1;
while (left < right)
{
@@ -874,6 +919,22 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
int32_t leftmost_fromskew;
uint32_t leftmost_tw;
/* If the raster is smaller than the image,
* or if there is a col_offset, adapt the samples to be copied per row. */
uint32_t wmin;
if (0 <= img->col_offset && (uint32_t)img->col_offset < img->width)
{
wmin = TIFFmin(w, img->width - img->col_offset);
}
else
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Error in gtTileSeparate: column offset %d exceeds "
"image width %d",
img->col_offset, img->width);
return 0;
}
tilesize = TIFFTileSize(tif);
bufsize =
_TIFFMultiplySSize(tif, alpha ? 4 : 3, tilesize, "gtTileSeparate");
@@ -888,7 +949,7 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
flip = setorientation(img);
if (flip & FLIP_VERTICALLY)
{
if ((tw + w) > INT_MAX)
if (((int64_t)tw + w) > INT_MAX)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
"unsupported tile size (too wide)");
@@ -899,7 +960,7 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
}
else
{
if (tw > (INT_MAX + w))
if (tw > ((int64_t)INT_MAX + w))
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s",
"unsupported tile size (too wide)");
@@ -933,7 +994,14 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
*/
leftmost_fromskew = img->col_offset % tw;
leftmost_tw = tw - leftmost_fromskew;
leftmost_toskew = toskew + leftmost_fromskew;
int64_t skew_i64 = (int64_t)toskew + leftmost_fromskew;
if (skew_i64 > INT_MAX || skew_i64 < INT_MIN)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s %" PRId64, "Invalid skew",
skew_i64);
return (0);
}
leftmost_toskew = (int32_t)skew_i64;
for (row = 0; ret != 0 && row < h; row += nrow)
{
rowstoread = th - (row + img->row_offset) % th;
@@ -943,7 +1011,8 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
this_toskew = leftmost_toskew;
tocol = 0;
col = img->col_offset;
while (tocol < w)
/* wmin: only write imagewidth if raster is bigger. */
while (tocol < wmin)
{
if (buf == NULL)
{
@@ -1000,14 +1069,16 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
break;
}
/* For SEPARATE the pos-offset is per sample and should not be
* multiplied by img->samplesperpixel. */
pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) +
((tmsize_t)fromskew * img->samplesperpixel);
if (tocol + this_tw > w)
(tmsize_t)fromskew;
if (tocol + this_tw > wmin)
{
/*
* Rightmost tile is clipped on right side.
*/
fromskew = tw - (w - tocol);
fromskew = tw - (wmin - tocol);
this_tw = tw - fromskew;
this_toskew = toskew + fromskew;
}
@@ -1036,7 +1107,9 @@ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
for (line = 0; line < h; line++)
{
uint32_t *left = raster + (line * w);
uint32_t *right = left + w - 1;
/* Use wmin to only flip horizontally data in place and not complete
* raster-row. */
uint32_t *right = left + wmin - 1;
while (left < right)
{
@@ -1071,10 +1144,28 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
uint16_t subsamplinghor, subsamplingver;
uint32_t imagewidth = img->width;
tmsize_t scanline;
/* fromskew, toskew are the increments within the input image or the raster
* from the end of a line to the start of the next line to read or write. */
int32_t fromskew, toskew;
int ret = 1, flip;
tmsize_t maxstripsize;
/* If the raster is smaller than the image,
* or if there is a col_offset, adapt the samples to be copied per row. */
uint32_t wmin;
if (0 <= img->col_offset && (uint32_t)img->col_offset < imagewidth)
{
wmin = TIFFmin(w, imagewidth - img->col_offset);
}
else
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Error in gtStripContig: column offset %d exceeds "
"image width %d",
img->col_offset, imagewidth);
return 0;
}
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor,
&subsamplingver);
if (subsamplingver == 0)
@@ -1089,18 +1180,22 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
flip = setorientation(img);
if (flip & FLIP_VERTICALLY)
{
if (w > INT_MAX)
if (w > INT_MAX / 2)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow");
return (0);
}
y = h - 1;
toskew = -(int32_t)(w + w);
/* Skew back to the raster row before the currently written row
* -> one raster width plus copied image pixels. */
toskew = -(int32_t)(w + wmin);
}
else
{
y = 0;
toskew = -(int32_t)(w - w);
/* Skew forward to the end of the raster width of the row currently
* copied. */
toskew = w - wmin;
}
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
@@ -1140,19 +1235,25 @@ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
pos = ((row + img->row_offset) % rowsperstrip) * scanline +
((tmsize_t)img->col_offset * img->samplesperpixel);
tmsize_t roffset = (tmsize_t)y * w;
(*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew,
(*put)(img, raster + roffset, 0, y, wmin, nrow, fromskew, toskew,
buf + pos);
y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow);
}
if (flip & FLIP_HORIZONTALLY)
{
/* Flips the complete raster matrix horizontally. If raster width is
* larger than image width, data are moved horizontally to the right
* side.
* Use wmin to only flip data in place. */
uint32_t line;
for (line = 0; line < h; line++)
{
uint32_t *left = raster + (line * w);
uint32_t *right = left + w - 1;
/* Use wmin to only flip horizontally data in place and not complete
* raster-row. */
uint32_t *right = left + wmin - 1;
while (left < right)
{
@@ -1194,6 +1295,22 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
int ret = 1, flip;
uint16_t colorchannels;
/* If the raster is smaller than the image,
* or if there is a col_offset, adapt the samples to be copied per row. */
uint32_t wmin;
if (0 <= img->col_offset && (uint32_t)img->col_offset < imagewidth)
{
wmin = TIFFmin(w, imagewidth - img->col_offset);
}
else
{
TIFFErrorExtR(tif, TIFFFileName(tif),
"Error in gtStripSeparate: column offset %d exceeds "
"image width %d",
img->col_offset, imagewidth);
return 0;
}
stripsize = TIFFStripSize(tif);
bufsize =
_TIFFMultiplySSize(tif, alpha ? 4 : 3, stripsize, "gtStripSeparate");
@@ -1205,18 +1322,22 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
flip = setorientation(img);
if (flip & FLIP_VERTICALLY)
{
if (w > INT_MAX)
if (w > INT_MAX / 2)
{
TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow");
return (0);
}
y = h - 1;
toskew = -(int32_t)(w + w);
/* Skew back to the raster row before the currently written row
* -> one raster width plus one image width. */
toskew = -(int32_t)(w + wmin);
}
else
{
y = 0;
toskew = -(int32_t)(w - w);
/* Skew forward to the end of the raster width of the row currently
* written. */
toskew = w - wmin;
}
switch (img->photometric)
@@ -1312,11 +1433,13 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
}
}
/* For SEPARATE the pos-offset is per sample and should not be
* multiplied by img->samplesperpixel. */
pos = ((row + img->row_offset) % rowsperstrip) * scanline +
((tmsize_t)img->col_offset * img->samplesperpixel);
(tmsize_t)img->col_offset;
tmsize_t roffset = (tmsize_t)y * w;
(*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, p0 + pos,
p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL));
(*put)(img, raster + roffset, 0, y, wmin, nrow, fromskew, toskew,
p0 + pos, p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL));
y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow);
}
@@ -1327,7 +1450,9 @@ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w,
for (line = 0; line < h; line++)
{
uint32_t *left = raster + (line * w);
uint32_t *right = left + w - 1;
/* Use wmin to only flip horizontally data in place and not complete
* raster-row. */
uint32_t *right = left + wmin - 1;
while (left < right)
{
@@ -3140,8 +3265,8 @@ static int PickSeparateCase(TIFFRGBAImage *img)
case PHOTOMETRIC_SEPARATED:
if (img->bitspersample == 8 && img->samplesperpixel == 4)
{
img->alpha =
1; // Not alpha, but seems like the only way to get 4th band
/* Not alpha, but seems like the only way to get 4th band */
img->alpha = 1;
img->put.separate = putCMYKseparate8bittile;
}
break;
@@ -3251,8 +3376,7 @@ int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster,
return (0);
}
if (TIFFRGBAImageOK(tif, emsg) &&
TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
if (TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
{
if (row >= img.height)
{
@@ -3338,8 +3462,7 @@ int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster,
* Setup the RGBA reader.
*/
if (!TIFFRGBAImageOK(tif, emsg) ||
!TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
if (!TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg))
{
TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg);
return (0);
+28 -10
View File
@@ -90,6 +90,7 @@ int TIFFJPEGIsFullStripRequired_12(TIFF *tif);
/* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 3.0 which
* adds a dual-mode 8/12 bit API in the same library.
* (note: libjpeg-turbo 2.2 was actually released as 3.0)
*/
#if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
@@ -205,6 +206,8 @@ typedef struct
int samplesperclump;
JPEGOtherSettings otherSettings;
int encode_raw_error;
} JPEGState;
#define JState(tif) ((JPEGState *)(tif)->tif_data)
@@ -220,13 +223,13 @@ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
static const TIFFField jpegFields[] = {
{TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8,
TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL},
{TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
{TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
{TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}};
FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL},
{TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "", NULL},
{TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
FALSE, FALSE, "", NULL},
{TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
FALSE, FALSE, "", NULL}};
/*
* libjpeg interface layer.
@@ -1769,7 +1772,8 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
unsigned char *out_ptr =
((unsigned char *)buf) + iPair * 3;
JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2);
TIFF_JSAMPLE *in_ptr =
(TIFF_JSAMPLE *)(tmpbuf + iPair * 2);
out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
out_ptr[1] =
(unsigned char)(((in_ptr[0] & 0xf) << 4) |
@@ -2191,9 +2195,12 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
}
if (segment_width > 65535 || segment_height > 65535)
if (segment_width > (uint32_t)JPEG_MAX_DIMENSION ||
segment_height > (uint32_t)JPEG_MAX_DIMENSION)
{
TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG");
TIFFErrorExtR(tif, module,
"Strip/tile too large for JPEG. Maximum dimension is %d",
(int)JPEG_MAX_DIMENSION);
return (0);
}
sp->cinfo.c.image_width = segment_width;
@@ -2300,6 +2307,7 @@ static int JPEGPreEncode(TIFF *tif, uint16_t s)
return (0);
}
sp->scancount = 0;
sp->encode_raw_error = FALSE;
return (1);
}
@@ -2396,6 +2404,13 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
(void)s;
assert(sp != NULL);
if (sp->encode_raw_error)
{
TIFFErrorExtR(tif, tif->tif_name, "JPEGEncodeRaw() already failed");
return 0;
}
/* data is expected to be supplied in multiples of a clumpline */
/* a clumpline is equivalent to v_sampling desubsampled scanlines */
/* TODO: the following calculation of bytesperclumpline, should substitute
@@ -2467,7 +2482,10 @@ static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
{
int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
{
sp->encode_raw_error = TRUE;
return (0);
}
sp->scancount = 0;
}
tif->tif_row += sp->v_sampling;
+33 -29
View File
@@ -93,7 +93,6 @@ typedef struct
#define LERCDecoderState(tif) GetLERCState(tif)
#define LERCEncoderState(tif) GetLERCState(tif)
static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
static int LERCFixupTags(TIFF *tif)
@@ -222,7 +221,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
{
TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile");
_TIFFfreeExt(tif, sp->uncompressed_buffer);
sp->uncompressed_buffer = 0;
sp->uncompressed_buffer = NULL;
sp->uncompressed_alloc = 0;
return 0;
}
@@ -230,12 +229,12 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
if (sp->uncompressed_alloc < new_alloc)
{
_TIFFfreeExt(tif, sp->uncompressed_buffer);
sp->uncompressed_buffer = _TIFFmallocExt(tif, new_alloc);
sp->uncompressed_buffer = (uint8_t *)_TIFFmallocExt(tif, new_alloc);
if (!sp->uncompressed_buffer)
{
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
_TIFFfreeExt(tif, sp->uncompressed_buffer);
sp->uncompressed_buffer = 0;
sp->uncompressed_buffer = NULL;
sp->uncompressed_alloc = 0;
return 0;
}
@@ -267,7 +266,7 @@ static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
TIFFErrorExtR(tif, module, "Cannot allocate buffer");
sp->mask_size = 0;
_TIFFfreeExt(tif, sp->uncompressed_buffer);
sp->uncompressed_buffer = 0;
sp->uncompressed_buffer = NULL;
sp->uncompressed_alloc = 0;
return 0;
}
@@ -348,7 +347,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
return 0;
}
assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
lerc_data = sp->compressed_buffer;
lerc_data = (uint8_t *)sp->compressed_buffer;
lerc_data_size = (unsigned int)lerc_data_sizet;
#else
z_stream strm;
@@ -369,7 +368,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
strm.avail_in = (uInt)tif->tif_rawcc;
strm.next_in = tif->tif_rawcp;
strm.avail_out = sp->compressed_size;
strm.next_out = sp->compressed_buffer;
strm.next_out = (Bytef *)sp->compressed_buffer;
zlib_ret = inflate(&strm, Z_FINISH);
if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK)
{
@@ -377,7 +376,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
inflateEnd(&strm);
return 0;
}
lerc_data = sp->compressed_buffer;
lerc_data = (uint8_t *)sp->compressed_buffer;
lerc_data_size = sp->compressed_size - strm.avail_out;
inflateEnd(&strm);
#endif
@@ -396,7 +395,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
return 0;
}
lerc_data = sp->compressed_buffer;
lerc_data = (uint8_t *)sp->compressed_buffer;
lerc_data_size = (unsigned int)zstd_ret;
#else
TIFFErrorExtR(tif, module, "ZSTD support missing");
@@ -568,7 +567,7 @@ static int LERCPreDecode(TIFF *tif, uint16_t s)
{
_TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
sp->uncompressed_buffer_multiband =
_TIFFmallocExt(tif, num_bytes_needed);
(uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
if (!sp->uncompressed_buffer_multiband)
{
sp->uncompressed_buffer_multiband_alloc = 0;
@@ -752,7 +751,7 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
assert(sp != NULL);
assert(sp->state == LSTATE_INIT_DECODE);
if (sp->uncompressed_buffer == 0)
if (sp->uncompressed_buffer == NULL)
{
memset(op, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
@@ -773,6 +772,8 @@ static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
return 1;
}
#ifndef LERC_READ_ONLY
static int LERCSetupEncode(TIFF *tif)
{
LERCState *sp = LERCEncoderState(tif);
@@ -1005,7 +1006,7 @@ static int LERCPostEncode(TIFF *tif)
{
_TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
sp->uncompressed_buffer_multiband =
_TIFFmallocExt(tif, num_bytes_needed);
(uint8_t *)_TIFFmallocExt(tif, num_bytes_needed);
if (!sp->uncompressed_buffer_multiband)
{
sp->uncompressed_buffer_multiband_alloc = 0;
@@ -1126,7 +1127,8 @@ static int LERCPostEncode(TIFF *tif)
sp->uncompressed_buffer_multiband, sp->lerc_version,
GetLercDataType(tif), 1, sp->segment_width, sp->segment_height,
dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror,
sp->compressed_buffer, sp->compressed_size, &numBytesWritten);
(unsigned char *)sp->compressed_buffer, sp->compressed_size,
&numBytesWritten);
}
else
#endif
@@ -1139,7 +1141,8 @@ static int LERCPostEncode(TIFF *tif)
use_mask ? 1 : 0,
#endif
use_mask ? sp->mask_buffer : NULL, sp->maxzerror,
sp->compressed_buffer, sp->compressed_size, &numBytesWritten);
(unsigned char *)sp->compressed_buffer, sp->compressed_size,
&numBytesWritten);
}
if (lerc_ret != 0)
{
@@ -1271,7 +1274,7 @@ static int LERCPostEncode(TIFF *tif)
{
int ret;
uint8_t *tif_rawdata_backup = tif->tif_rawdata;
tif->tif_rawdata = sp->compressed_buffer;
tif->tif_rawdata = (uint8_t *)sp->compressed_buffer;
tif->tif_rawcc = numBytesWritten;
ret = TIFFFlushData1(tif);
tif->tif_rawdata = tif_rawdata_backup;
@@ -1282,11 +1285,13 @@ static int LERCPostEncode(TIFF *tif)
return 1;
}
#endif /* LERC_READ_ONLY */
static void LERCCleanup(TIFF *tif)
{
LERCState *sp = GetLERCState(tif);
assert(sp != 0);
assert(sp != NULL);
tif->tif_tagmethods.vgetfield = sp->vgetparent;
tif->tif_tagmethods.vsetfield = sp->vsetparent;
@@ -1311,21 +1316,18 @@ static void LERCCleanup(TIFF *tif)
static const TIFFField LERCFields[] = {
{TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0,
TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, FALSE, TRUE,
"LercParameters", NULL},
TIFF_SETGET_C32_UINT32, FIELD_CUSTOM, FALSE, TRUE,
(char *)"LercParameters", NULL},
{TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError",
NULL},
{TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL},
FIELD_PSEUDO, TRUE, FALSE, (char *)"LercMaximumError", NULL},
{TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, FIELD_PSEUDO,
FALSE, FALSE, (char *)"LercVersion", NULL},
{TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE,
"LercAdditionalCompression", NULL},
{TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE,
"ZSTD zstd_compress_level", NULL},
{TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
FIELD_PSEUDO, FALSE, FALSE, (char *)"LercAdditionalCompression", NULL},
{TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, (char *)"ZSTD zstd_compress_level", NULL},
{TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, (char *)"", NULL},
};
static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
@@ -1517,12 +1519,14 @@ int TIFFInitLERC(TIFF *tif, int scheme)
tif->tif_decoderow = LERCDecode;
tif->tif_decodestrip = LERCDecode;
tif->tif_decodetile = LERCDecode;
#ifndef LERC_READ_ONLY
tif->tif_setupencode = LERCSetupEncode;
tif->tif_preencode = LERCPreEncode;
tif->tif_postencode = LERCPostEncode;
tif->tif_encoderow = LERCEncode;
tif->tif_encodestrip = LERCEncode;
tif->tif_encodetile = LERCEncode;
#endif
tif->tif_cleanup = LERCCleanup;
/* Default values for codec-specific fields */
+22 -7
View File
@@ -145,9 +145,11 @@
* quantization errors into noise.
*/
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
* State block for each open TIFF
@@ -770,13 +772,26 @@ static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
#undef exp2 /* Conflict with C'99 function */
#define exp2(x) exp(M_LN2 *(x))
#define TIFF_RAND_MAX 32767
// From POSIX.1-2001 as an example of an implementation of rand()
static uint32_t _TIFFRand()
{
static uint32_t nCounter = 0;
if (!nCounter)
nCounter = (uint32_t)(time(NULL) & UINT32_MAX);
++nCounter;
uint32_t nCounterLocal =
(uint32_t)(((uint64_t)(nCounter)*1103515245U + 12345U) & UINT32_MAX);
nCounter = nCounterLocal;
return (nCounterLocal / 65536U) % (TIFF_RAND_MAX + 1);
};
static int tiff_itrunc(double x, int m)
{
if (m == SGILOGENCODE_NODITHER)
return (int)x;
/* Silence CoverityScan warning about bad crypto function */
/* coverity[dont_call] */
return (int)(x + rand() * (1. / RAND_MAX) - .5);
return (int)(x + _TIFFRand() * (1. / TIFF_RAND_MAX) - .5);
}
#if !LOGLUV_PUBLIC
@@ -1774,10 +1789,10 @@ static int LogLuvVGetField(TIFF *tif, uint32_t tag, va_list ap)
}
static const TIFFField LogLuvFields[] = {
{TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL},
{TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}};
{TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "SGILogDataFmt", NULL},
{TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "SGILogEncode", NULL}};
int TIFFInitSGILog(TIFF *tif, int scheme)
{
+2 -3
View File
@@ -450,9 +450,8 @@ static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap)
}
static const TIFFField lzmaFields[] = {
{TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE,
"LZMA2 Compression Preset", NULL},
{TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "LZMA2 Compression Preset", NULL},
};
int TIFFInitLZMA(TIFF *tif, int scheme)
+10 -2
View File
@@ -168,7 +168,6 @@ static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s);
#ifdef LZW_COMPAT
static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s);
#endif
static void cl_hash(LZWCodecState *);
/*
* LZW Decoder.
@@ -733,6 +732,7 @@ after_loop:
if (occ > 0)
{
memset(op, 0, (size_t)occ);
sp->read_error = 1;
TIFFErrorExtR(tif, module,
"Not enough data at scanline %" PRIu32 " (short %" PRIu64
" bytes)",
@@ -1017,6 +1017,10 @@ static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s)
}
#endif /* LZW_COMPAT */
#ifndef LZW_READ_ONLY
static void cl_hash(LZWCodecState *);
/*
* LZW Encoding.
*/
@@ -1373,11 +1377,13 @@ static void cl_hash(LZWCodecState *sp)
hp->hash = -1;
}
#endif
static void LZWCleanup(TIFF *tif)
{
(void)TIFFPredictorCleanup(tif);
assert(tif->tif_data != 0);
assert(tif->tif_data != NULL);
if (LZWDecoderState(tif)->dec_codetab)
_TIFFfreeExt(tif, LZWDecoderState(tif)->dec_codetab);
@@ -1416,12 +1422,14 @@ int TIFFInitLZW(TIFF *tif, int scheme)
tif->tif_decoderow = LZWDecode;
tif->tif_decodestrip = LZWDecode;
tif->tif_decodetile = LZWDecode;
#ifndef LZW_READ_ONLY
tif->tif_setupencode = LZWSetupEncode;
tif->tif_preencode = LZWPreEncode;
tif->tif_postencode = LZWPostEncode;
tif->tif_encoderow = LZWEncode;
tif->tif_encodestrip = LZWEncode;
tif->tif_encodetile = LZWEncode;
#endif
tif->tif_cleanup = LZWCleanup;
/*
* Setup predictor setup.
+17 -18
View File
@@ -181,26 +181,25 @@
static const TIFFField ojpegFields[] = {
{TIFFTAG_JPEGIFOFFSET, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64,
TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMAT, TRUE, FALSE,
"JpegInterchangeFormat", NULL},
{TIFFTAG_JPEGIFBYTECOUNT, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64,
TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH, TRUE,
FALSE, "JpegInterchangeFormatLength", NULL},
{TIFFTAG_JPEGQTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGQTABLES,
FALSE, TRUE, "JpegQTables", NULL},
{TIFFTAG_JPEGDCTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGDCTABLES,
FALSE, TRUE, "JpegDcTables", NULL},
{TIFFTAG_JPEGACTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGACTABLES,
FALSE, TRUE, "JpegAcTables", NULL},
{TIFFTAG_JPEGPROC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGPROC, FALSE, FALSE, "JpegProc",
FIELD_OJPEG_JPEGINTERCHANGEFORMAT, TRUE, FALSE, "JpegInterchangeFormat",
NULL},
{TIFFTAG_JPEGIFBYTECOUNT, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64,
FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH, TRUE, FALSE,
"JpegInterchangeFormatLength", NULL},
{TIFFTAG_JPEGQTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
TIFF_SETGET_C32_UINT64, FIELD_OJPEG_JPEGQTABLES, FALSE, TRUE,
"JpegQTables", NULL},
{TIFFTAG_JPEGDCTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
TIFF_SETGET_C32_UINT64, FIELD_OJPEG_JPEGDCTABLES, FALSE, TRUE,
"JpegDcTables", NULL},
{TIFFTAG_JPEGACTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0,
TIFF_SETGET_C32_UINT64, FIELD_OJPEG_JPEGACTABLES, FALSE, TRUE,
"JpegAcTables", NULL},
{TIFFTAG_JPEGPROC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
FIELD_OJPEG_JPEGPROC, FALSE, FALSE, "JpegProc", NULL},
{TIFFTAG_JPEGRESTARTINTERVAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGRESTARTINTERVAL, FALSE, FALSE,
"JpegRestartInterval", NULL},
FIELD_OJPEG_JPEGRESTARTINTERVAL, FALSE, FALSE, "JpegRestartInterval",
NULL},
};
#ifndef LIBJPEG_ENCAP_EXTERNAL
+12 -2
View File
@@ -37,7 +37,7 @@
/*
* Dummy functions to fill the omitted client procedures.
*/
static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
(void)fd;
(void)pbase;
@@ -45,7 +45,7 @@ static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
return (0);
}
static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)base;
@@ -109,6 +109,15 @@ void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
}
/** Whether a warning should be emitted when encountering a unknown tag.
* Default is FALSE since libtiff 4.7.1
*/
void TIFFOpenOptionsSetWarnAboutUnknownTags(TIFFOpenOptions *opts,
int warn_about_unknown_tags)
{
opts->warn_about_unknown_tags = warn_about_unknown_tags;
}
void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
TIFFErrorHandlerExtR handler,
void *errorhandler_user_data)
@@ -386,6 +395,7 @@ TIFF *TIFFClientOpenExt(const char *name, const char *mode,
tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags;
}
if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
+7 -1
View File
@@ -31,6 +31,8 @@
*/
#include <stdio.h>
#ifndef PACKBITS_READ_ONLY
static int PackBitsPreEncode(TIFF *tif, uint16_t s)
{
(void)s;
@@ -78,7 +80,7 @@ static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
op = tif->tif_rawcp;
ep = tif->tif_rawdata + tif->tif_rawdatasize;
state = BASE;
lastliteral = 0;
lastliteral = NULL;
while (cc > 0)
{
/*
@@ -231,6 +233,8 @@ static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
return (1);
}
#endif
static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
{
static const char module[] = "PackBitsDecode";
@@ -314,11 +318,13 @@ int TIFFInitPackBits(TIFF *tif, int scheme)
tif->tif_decoderow = PackBitsDecode;
tif->tif_decodestrip = PackBitsDecode;
tif->tif_decodetile = PackBitsDecode;
#ifndef PACKBITS_READ_ONLY
tif->tif_preencode = PackBitsPreEncode;
tif->tif_postencode = PackBitsPostEncode;
tif->tif_encoderow = PackBitsEncode;
tif->tif_encodestrip = PackBitsEncodeChunk;
tif->tif_encodetile = PackBitsEncodeChunk;
#endif
return (1);
}
#endif /* PACKBITS_SUPPORT */
+4 -4
View File
@@ -1596,10 +1596,10 @@ static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap)
}
static const TIFFField pixarlogFields[] = {
{TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
{TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}};
{TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
FALSE, FALSE, "", NULL},
{TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
FALSE, FALSE, "", NULL}};
int TIFFInitPixarLog(TIFF *tif, int scheme)
{
+148 -33
View File
@@ -30,6 +30,10 @@
#include "tif_predict.h"
#include "tiffiop.h"
#if defined(__x86_64__) || defined(_M_X64)
#include <emmintrin.h>
#endif
#define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data)
static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc);
@@ -208,16 +212,12 @@ static int PredictorSetupDecode(TIFF *tif)
/*
* The data should not be swapped outside of the floating
* point predictor, the accumulation routine should return
* byres in the native order.
* bytes in the native order.
*/
if (tif->tif_flags & TIFF_SWAB)
{
tif->tif_postdecode = _TIFFNoPostDecode;
}
/*
* Allocate buffer to keep the decoded bytes before
* rearranging in the right order
*/
}
return 1;
@@ -305,6 +305,15 @@ static int PredictorSetupEncode(TIFF *tif)
sp->encodetile = tif->tif_encodetile;
tif->tif_encodetile = PredictorEncodeTile;
}
/*
* The data should not be swapped outside of the floating
* point predictor, the differentiation routine should return
* bytes in the native order.
*/
if (tif->tif_flags & TIFF_SWAB)
{
tif->tif_postdecode = _TIFFNoPostDecode;
}
}
return 1;
@@ -343,7 +352,7 @@ static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
{
tmsize_t stride = PredictorState(tif)->stride;
unsigned char *cp = (unsigned char *)cp0;
uint8_t *cp = cp0;
if ((cc % stride) != 0)
{
TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0");
@@ -355,32 +364,48 @@ static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
/*
* Pipeline the most common cases.
*/
if (stride == 3)
if (stride == 1)
{
unsigned int cr = cp[0];
unsigned int cg = cp[1];
unsigned int cb = cp[2];
uint32_t acc = cp[0];
tmsize_t i = stride;
for (; i < cc - 3; i += 4)
{
cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
cp[i + 1] = (uint8_t)((acc += cp[i + 1]) & 0xff);
cp[i + 2] = (uint8_t)((acc += cp[i + 2]) & 0xff);
cp[i + 3] = (uint8_t)((acc += cp[i + 3]) & 0xff);
}
for (; i < cc; i++)
{
cp[i + 0] = (uint8_t)((acc += cp[i + 0]) & 0xff);
}
}
else if (stride == 3)
{
uint32_t cr = cp[0];
uint32_t cg = cp[1];
uint32_t cb = cp[2];
tmsize_t i = stride;
for (; i < cc; i += stride)
{
cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff);
cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff);
cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff);
cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
}
}
else if (stride == 4)
{
unsigned int cr = cp[0];
unsigned int cg = cp[1];
unsigned int cb = cp[2];
unsigned int ca = cp[3];
uint32_t cr = cp[0];
uint32_t cg = cp[1];
uint32_t cb = cp[2];
uint32_t ca = cp[3];
tmsize_t i = stride;
for (; i < cc; i += stride)
{
cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff);
cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff);
cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff);
cp[i + 3] = (unsigned char)((ca += cp[i + 3]) & 0xff);
cp[i + 0] = (uint8_t)((cr += cp[i + 0]) & 0xff);
cp[i + 1] = (uint8_t)((cg += cp[i + 1]) & 0xff);
cp[i + 2] = (uint8_t)((cb += cp[i + 2]) & 0xff);
cp[i + 3] = (uint8_t)((ca += cp[i + 3]) & 0xff);
}
}
else
@@ -389,7 +414,7 @@ static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc)
do
{
REPEAT4(stride,
cp[stride] = (unsigned char)((cp[stride] + *cp) & 0xff);
cp[stride] = (uint8_t)((cp[stride] + *cp) & 0xff);
cp++)
cc -= stride;
} while (cc > 0);
@@ -512,7 +537,7 @@ static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
uint32_t bps = tif->tif_dir.td_bitspersample / 8;
tmsize_t wc = cc / bps;
tmsize_t count = cc;
uint8_t *cp = (uint8_t *)cp0;
uint8_t *cp = cp0;
uint8_t *tmp;
if (cc % (bps * stride) != 0)
@@ -525,17 +550,85 @@ static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc)
if (!tmp)
return 0;
while (count > stride)
if (stride == 1)
{
REPEAT4(stride,
cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff);
cp++)
count -= stride;
/* Optimization of general case */
#define OP \
do \
{ \
cp[1] = (uint8_t)((cp[1] + cp[0]) & 0xff); \
++cp; \
} while (0)
for (; count > 8; count -= 8)
{
OP;
OP;
OP;
OP;
OP;
OP;
OP;
OP;
}
for (; count > 1; count -= 1)
{
OP;
}
#undef OP
}
else
{
while (count > stride)
{
REPEAT4(stride, cp[stride] = (uint8_t)((cp[stride] + cp[0]) & 0xff);
cp++)
count -= stride;
}
}
_TIFFmemcpy(tmp, cp0, cc);
cp = (uint8_t *)cp0;
for (count = 0; count < wc; count++)
count = 0;
#if defined(__x86_64__) || defined(_M_X64)
if (bps == 4)
{
/* Optimization of general case */
for (; count + 15 < wc; count += 16)
{
/* Interlace 4*16 byte values */
__m128i xmm0 =
_mm_loadu_si128((const __m128i *)(tmp + count + 3 * wc));
__m128i xmm1 =
_mm_loadu_si128((const __m128i *)(tmp + count + 2 * wc));
__m128i xmm2 =
_mm_loadu_si128((const __m128i *)(tmp + count + 1 * wc));
__m128i xmm3 =
_mm_loadu_si128((const __m128i *)(tmp + count + 0 * wc));
/* (xmm0_0, xmm1_0, xmm0_1, xmm1_1, xmm0_2, xmm1_2, ...) */
__m128i tmp0 = _mm_unpacklo_epi8(xmm0, xmm1);
/* (xmm0_8, xmm1_8, xmm0_9, xmm1_9, xmm0_10, xmm1_10, ...) */
__m128i tmp1 = _mm_unpackhi_epi8(xmm0, xmm1);
/* (xmm2_0, xmm3_0, xmm2_1, xmm3_1, xmm2_2, xmm3_2, ...) */
__m128i tmp2 = _mm_unpacklo_epi8(xmm2, xmm3);
/* (xmm2_8, xmm3_8, xmm2_9, xmm3_9, xmm2_10, xmm3_10, ...) */
__m128i tmp3 = _mm_unpackhi_epi8(xmm2, xmm3);
/* (xmm0_0, xmm1_0, xmm2_0, xmm3_0, xmm0_1, xmm1_1, xmm2_1, xmm3_1,
* ...) */
__m128i tmp2_0 = _mm_unpacklo_epi16(tmp0, tmp2);
__m128i tmp2_1 = _mm_unpackhi_epi16(tmp0, tmp2);
__m128i tmp2_2 = _mm_unpacklo_epi16(tmp1, tmp3);
__m128i tmp2_3 = _mm_unpackhi_epi16(tmp1, tmp3);
_mm_storeu_si128((__m128i *)(cp + 4 * count + 0 * 16), tmp2_0);
_mm_storeu_si128((__m128i *)(cp + 4 * count + 1 * 16), tmp2_1);
_mm_storeu_si128((__m128i *)(cp + 4 * count + 2 * 16), tmp2_2);
_mm_storeu_si128((__m128i *)(cp + 4 * count + 3 * 16), tmp2_3);
}
}
#endif
for (; count < wc; count++)
{
uint32_t byte;
for (byte = 0; byte < bps; byte++)
@@ -857,16 +950,38 @@ static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc)
static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
{
static const char module[] = "PredictorEncodeRow";
TIFFPredictorState *sp = PredictorState(tif);
uint8_t *working_copy;
int result_code;
assert(sp != NULL);
assert(sp->encodepfunc != NULL);
assert(sp->encoderow != NULL);
/* XXX horizontal differencing alters user's data XXX */
if (!(*sp->encodepfunc)(tif, bp, cc))
/*
* Do predictor manipulation in a working buffer to avoid altering
* the callers buffer, like for PredictorEncodeTile().
* https://gitlab.com/libtiff/libtiff/-/issues/5
*/
working_copy = (uint8_t *)_TIFFmallocExt(tif, cc);
if (working_copy == NULL)
{
TIFFErrorExtR(tif, module,
"Out of memory allocating %" PRId64 " byte temp buffer.",
(int64_t)cc);
return 0;
return (*sp->encoderow)(tif, bp, cc, s);
}
memcpy(working_copy, bp, cc);
if (!(*sp->encodepfunc)(tif, working_copy, cc))
{
_TIFFfreeExt(tif, working_copy);
return 0;
}
result_code = (*sp->encoderow)(tif, working_copy, cc, s);
_TIFFfreeExt(tif, working_copy);
return result_code;
}
static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
@@ -923,7 +1038,7 @@ static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0,
static const TIFFField predictFields[] = {
{TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL},
};
static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap)
+2 -1
View File
@@ -677,7 +677,8 @@ void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags)
else
{
/*--: Rational2Double: For Rationals evaluate
* "set_field_type" to determine internal storage size. */
* "set_get_field_type" to determine internal storage size.
*/
int tv_size = TIFFFieldSetGetSize(fip);
raw_data = _TIFFmallocExt(tif, tv_size * value_count);
mem_alloc = 1;
+26 -8
View File
@@ -351,15 +351,14 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
* chunk strip */
whole_strip = 1;
}
#else
whole_strip = 1;
#endif
if (!whole_strip)
{
/* 16 is for YCbCr mode where we may need to read 16 */
/* lines at a time to get a decompressed line, and 5000 */
/* is some constant value, for example for JPEG tables */
/* coverity[dead_error_line:SUPPRESS] */
if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
{
@@ -370,6 +369,9 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
read_ahead = tif->tif_scanlinesize;
}
}
#else
whole_strip = 1;
#endif
/*
* If we haven't loaded this strip, do so now, possibly
@@ -383,18 +385,22 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
if (!TIFFFillStrip(tif, strip))
return (0);
}
#if defined(CHUNKY_STRIP_READ_SUPPORT)
else
{
if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
return 0;
}
#endif
}
#if defined(CHUNKY_STRIP_READ_SUPPORT)
/*
** If we already have some data loaded, do we need to read some more?
*/
else if (!whole_strip)
{
/* coverity[dead_error_line:SUPPRESS] */
if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) <
read_ahead &&
(uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded <
@@ -404,6 +410,7 @@ static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
return 0;
}
}
#endif
if (row < tif->tif_row)
{
@@ -466,7 +473,9 @@ int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
}
else
{
memset(buf, 0, (size_t)tif->tif_scanlinesize);
/* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
if (buf)
memset(buf, 0, (size_t)tif->tif_scanlinesize);
}
return (e > 0 ? 1 : -1);
}
@@ -554,7 +563,10 @@ tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
stripsize = size;
if (!TIFFFillStrip(tif, strip))
{
memset(buf, 0, (size_t)stripsize);
/* The output buf may be NULL, in particular if TIFFTAG_FAXFILLFUNC
is being used. Thus, memset must be conditional on buf not NULL. */
if (buf)
memset(buf, 0, (size_t)stripsize);
return ((tmsize_t)(-1));
}
if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
@@ -976,7 +988,9 @@ tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
size = tilesize;
if (!TIFFFillTile(tif, tile))
{
memset(buf, 0, (size_t)size);
/* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
if (buf)
memset(buf, 0, (size_t)size);
return ((tmsize_t)(-1));
}
else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
@@ -1569,7 +1583,9 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
if (!TIFFStartTile(tif, strile))
{
ret = 0;
memset(outbuf, 0, (size_t)outsize);
/* See related TIFFReadEncodedStrip comment. */
if (outbuf)
memset(outbuf, 0, (size_t)outsize);
}
else if (!(*tif->tif_decodetile)(
tif, (uint8_t *)outbuf, outsize,
@@ -1596,7 +1612,9 @@ int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
if (!TIFFStartStrip(tif, strile))
{
ret = 0;
memset(outbuf, 0, (size_t)outsize);
/* See related TIFFReadEncodedStrip comment. */
if (outbuf)
memset(outbuf, 0, (size_t)outsize);
}
else if (!(*tif->tif_decodestrip)(
tif, (uint8_t *)outbuf, outsize,
+6 -6
View File
@@ -87,8 +87,8 @@ extern "C"
static uint64_t _tiffisSizeProc(thandle_t fd);
static int _tiffosCloseProc(thandle_t fd);
static int _tiffisCloseProc(thandle_t fd);
static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size);
static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size);
static int _tiffDummyMapProcCxx(thandle_t, void **base, toff_t *size);
static void _tiffDummyUnmapProcCxx(thandle_t, void *base, toff_t size);
static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd);
struct tiffis_data
@@ -324,14 +324,14 @@ extern "C"
return 0;
}
static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size)
static int _tiffDummyMapProcCxx(thandle_t, void **base, toff_t *size)
{
(void)base;
(void)size;
return (0);
}
static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size)
static void _tiffDummyUnmapProcCxx(thandle_t, void *base, toff_t size)
{
(void)base;
(void)size;
@@ -354,7 +354,7 @@ extern "C"
tif = TIFFClientOpen(
name, mode, reinterpret_cast<thandle_t>(data), _tiffosReadProc,
_tiffosWriteProc, _tiffosSeekProc, _tiffosCloseProc,
_tiffosSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc);
_tiffosSizeProc, _tiffDummyMapProcCxx, _tiffDummyUnmapProcCxx);
if (!tif)
{
delete data;
@@ -369,7 +369,7 @@ extern "C"
tif = TIFFClientOpen(
name, mode, reinterpret_cast<thandle_t>(data), _tiffisReadProc,
_tiffisWriteProc, _tiffisSeekProc, _tiffisCloseProc,
_tiffisSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc);
_tiffisSizeProc, _tiffDummyMapProcCxx, _tiffDummyUnmapProcCxx);
if (!tif)
{
delete data;
+2 -1
View File
@@ -40,7 +40,8 @@ uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample)
if (td->td_rowsperstrip == 0)
{
TIFFErrorExtR(tif, module, "Cannot compute strip: RowsPerStrip is zero");
TIFFErrorExtR(tif, module,
"Cannot compute strip: RowsPerStrip is zero");
return 0;
}
strip = row / td->td_rowsperstrip;
+4
View File
@@ -91,6 +91,8 @@ static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
}
if (count < 0)
return (tmsize_t)-1;
/* Silence Coverity Scan warning about unsigned to signed underflow. */
/* coverity[return_overflow:SUPPRESS] */
return (tmsize_t)bytes_read;
}
@@ -120,6 +122,8 @@ static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
}
if (count < 0)
return (tmsize_t)-1;
/* Silence Coverity Scan warning about unsigned to signed underflow. */
/* coverity[return_overflow:SUPPRESS] */
return (tmsize_t)bytes_written;
/* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */
}
+5 -7
View File
@@ -836,14 +836,12 @@ static int TWebPVGetField(TIFF *tif, uint32_t tag, va_list ap)
}
static const TIFFField TWebPFields[] = {
{TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL},
{TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy",
NULL},
{TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "WEBP quality", NULL},
{TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "WEBP lossless/lossy", NULL},
{TIFFTAG_WEBP_LOSSLESS_EXACT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless",
NULL},
FIELD_PSEUDO, TRUE, FALSE, "WEBP exact lossless", NULL},
};
int TIFFInitWebP(TIFF *tif, int scheme)
-15
View File
@@ -158,14 +158,6 @@ static uint64_t _tiffSizeProc(thandle_t fd)
return (0);
}
static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
(void)fd;
(void)pbase;
(void)psize;
return (0);
}
/*
* From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
*
@@ -201,13 +193,6 @@ static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
return (1);
}
static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)base;
(void)size;
}
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
+5
View File
@@ -573,8 +573,13 @@ int TIFFSetupStrips(TIFF *tif)
}
if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
td->td_stripsperimage /= td->td_samplesperpixel;
if (td->td_stripoffset_p != NULL)
_TIFFfreeExt(tif, td->td_stripoffset_p);
td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
if (td->td_stripbytecount_p != NULL)
_TIFFfreeExt(tif, td->td_stripbytecount_p);
td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
+45 -25
View File
@@ -128,6 +128,16 @@ static int ZIPSetupDecode(TIFF *tif)
}
}
static inline uint64_t TIFF_MIN_UINT64(uint64_t a, uint64_t b)
{
return a < b ? a : b;
}
static inline uInt TIFF_CLAMP_UINT64_TO_INT32_MAX(uint64_t v)
{
return (uInt)TIFF_MIN_UINT64(v, INT32_MAX);
}
/*
* Setup state for decoding a strip.
*/
@@ -149,9 +159,7 @@ static int ZIPPreDecode(TIFF *tif, uint16_t s)
we need to simplify this code to reflect a ZLib that is likely updated
to deal with 8byte memory sizes, though this code will respond
appropriately even before we simplify it */
sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
? (uInt)tif->tif_rawcc
: 0xFFFFFFFFU;
sp->stream.avail_in = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
if (inflateReset(&sp->stream) == Z_OK)
{
sp->read_error = 0;
@@ -267,14 +275,10 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
do
{
int state;
uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU
? (uInt)tif->tif_rawcc
: 0xFFFFFFFFU;
uInt avail_out_before =
(uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU;
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawcc);
uInt avail_out_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(occ);
sp->stream.avail_in = avail_in_before;
sp->stream.avail_out = avail_out_before;
/* coverity[overrun-buffer-arg] */
state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
occ -= (avail_out_before - sp->stream.avail_out);
@@ -282,7 +286,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
break;
if (state == Z_DATA_ERROR)
{
memset(sp->stream.next_out, 0, sp->stream.avail_out);
memset(sp->stream.next_out, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
(unsigned long)tif->tif_row, SAFE_MSG(sp));
sp->read_error = 1;
@@ -290,7 +294,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
}
if (state != Z_OK)
{
memset(sp->stream.next_out, 0, sp->stream.avail_out);
memset(sp->stream.next_out, 0, (size_t)occ);
TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
sp->read_error = 1;
return (0);
@@ -302,7 +306,7 @@ static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
"Not enough data at scanline %lu (short %" PRIu64
" bytes)",
(unsigned long)tif->tif_row, (uint64_t)occ);
memset(sp->stream.next_out, 0, sp->stream.avail_out);
memset(sp->stream.next_out, 0, (size_t)occ);
sp->read_error = 1;
return (0);
}
@@ -481,10 +485,8 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
appropriately even before we simplify it */
do
{
uInt avail_in_before =
(uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
uInt avail_in_before = TIFF_CLAMP_UINT64_TO_INT32_MAX(cc);
sp->stream.avail_in = avail_in_before;
/* coverity[overrun-buffer-arg] */
if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
{
TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp));
@@ -496,9 +498,8 @@ static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
if (!TIFFFlushData1(tif))
return 0;
sp->stream.next_out = tif->tif_rawdata;
sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
? (uInt)tif->tif_rawdatasize
: 0xFFFFFFFFU;
sp->stream.avail_out =
TIFF_CLAMP_UINT64_TO_INT32_MAX(tif->tif_rawdatasize);
}
cc -= (avail_in_before - sp->stream.avail_in);
} while (cc > 0);
@@ -672,12 +673,31 @@ static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
}
static const TIFFField zipFields[] = {
{TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
{TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
{TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "", NULL},
{TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO,
TRUE, FALSE, "", NULL},
};
static void *TIFF_zalloc(void *opaque, unsigned int items, unsigned int size)
{
static const char module[] = "TIFF_zalloc";
TIFF *tif = opaque;
if (items > ~(size_t)0 / size)
{
TIFFErrorExtR(tif, module, "Overflow");
return NULL;
}
return _TIFFmallocExt(tif, items * size);
}
static void TIFF_zfree(void *opaque, void *ptr)
{
_TIFFfreeExt((TIFF *)opaque, ptr);
}
int TIFFInitZIP(TIFF *tif, int scheme)
{
static const char module[] = "TIFFInitZIP";
@@ -706,9 +726,9 @@ int TIFFInitZIP(TIFF *tif, int scheme)
if (tif->tif_data == NULL)
goto bad;
sp = GetZIPState(tif);
sp->stream.zalloc = NULL;
sp->stream.zfree = NULL;
sp->stream.opaque = NULL;
sp->stream.zalloc = TIFF_zalloc;
sp->stream.zfree = TIFF_zfree;
sp->stream.opaque = tif;
sp->stream.data_type = Z_BINARY;
/*
+2 -3
View File
@@ -363,9 +363,8 @@ static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap)
}
static const TIFFField ZSTDFields[] = {
{TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level",
NULL},
{TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, FIELD_PSEUDO, TRUE,
FALSE, "ZSTD compression_level", NULL},
};
int TIFFInitZSTD(TIFF *tif, int scheme)
+1
View File
@@ -216,6 +216,7 @@ typedef enum
#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */
#define COMPRESSION_JXL_DNG_1_7 52546 /* JPEGXL from DNG 1.7 specification */
#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
+1 -1
View File
@@ -89,7 +89,7 @@
/* Support NeXT 2-bit RLE algorithm */
#cmakedefine NEXT_SUPPORT 1
/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
/* Support Old JPEG compression (read contrib/ojpeg/README first! Compilation
fails with unpatched IJG JPEG library) */
#cmakedefine OJPEG_SUPPORT 1
+23 -5
View File
@@ -45,12 +45,14 @@ typedef struct tiff TIFF;
* to pass tag types and values uses the types defined in
* tiff.h directly.
*
* NB: ttag_t is unsigned int and not unsigned short because
* NB: ttag_t -> deprecated and replaced by uint32_t
* is unsigned int and not unsigned short because
* ANSI C requires that the type before the ellipsis be a
* promoted type (i.e. one of int, unsigned int, pointer,
* or double) and because we defined pseudo-tags that are
* outside the range of legal Aldus-assigned tags.
* NB: tsize_t is signed and not unsigned because some functions
* NB: tsize_t -> deprecated and replaced by tmsize_t
* is signed and not unsigned because some functions
* return -1.
* NB: toff_t is not off_t for many reasons; TIFFs max out at
* 32-bit file offsets, and BigTIFF maxes out at 64-bit
@@ -66,10 +68,11 @@ typedef TIFF_SSIZE_T tmsize_t;
#define TIFF_TMSIZE_T_MAX (tmsize_t)(SIZE_MAX >> 1)
typedef uint64_t toff_t; /* file offset */
typedef uint32_t tdir_t; /* directory index */
/* the following are deprecated and should be replaced by their defining
counterparts */
typedef uint32_t ttag_t; /* directory tag */
typedef uint32_t tdir_t; /* directory index */
typedef uint16_t tsample_t; /* sample number */
typedef uint32_t tstrile_t; /* strip or tile number */
typedef tstrile_t tstrip_t; /* strip number */
@@ -151,6 +154,18 @@ typedef struct
float d_gammaB;
} TIFFDisplay;
/* YCbCr->RGB support for TIFFYCbCrToRGBInit() and TIFFYCbCrToRGB()
* Attention:
* Functions TIFFYCbCrToRGBInit() and TIFFYCbCrToRGB() require a user provided
* large memory buffer, where several tables can be setup.
* The pointers to these tables are stored in the structure TIFFYCbCrToRGB,
* which is located at the beginning of the buffer. Thus, this memory has to be
* allocated as follows:
* TIFFYCbCrToRGB *ycbcr = (TIFFYCbCrToRGB *)_TIFFmalloc(
* TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)) +
* 4 * 256 * sizeof(TIFFRGBValue) + 2 * 256 * sizeof(int) +
* 3 * 256 * sizeof(int32_t));
*/
typedef struct
{ /* YCbCr->RGB support */
TIFFRGBValue *clamptab; /* range clamping table */
@@ -508,6 +523,9 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
tmsize_t max_cumulated_mem_alloc);
extern void
TIFFOpenOptionsSetWarnAboutUnknownTags(TIFFOpenOptions *opts,
int warn_about_unknown_tags);
extern void
TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
TIFFErrorHandlerExtR handler,
void *errorhandler_user_data);
@@ -590,7 +608,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile,
int *pbErr);
#ifdef LOGLUV_PUBLIC
#if LOGLUV_PUBLIC
#define U_NEU 0.210526316
#define V_NEU 0.473684211
#define UVSCALE 410.
@@ -634,7 +652,7 @@ extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *,
****************************************************************************/
typedef struct
{
ttag_t field_tag; /* field's tag */
uint32_t field_tag; /* field's tag */
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */
+4
View File
@@ -258,6 +258,7 @@ struct tiff
tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */
tmsize_t tif_max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
tmsize_t tif_cur_cumulated_mem_alloc; /* in bytes */
int tif_warn_about_unknown_tags;
};
struct TIFFOpenOptions
@@ -268,6 +269,7 @@ struct TIFFOpenOptions
void *warnhandler_user_data; /* may be NULL */
tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */
tmsize_t max_cumulated_mem_alloc; /* in bytes. 0 for unlimited */
int warn_about_unknown_tags;
};
#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */
@@ -398,6 +400,8 @@ typedef size_t TIFFIOSize_t;
extern "C"
{
#endif
extern int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize);
extern void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size);
extern int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata,
const char *mode, const char *module);
extern int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc,
+1 -1
View File
@@ -41,7 +41,7 @@ if(MSVC)
ocv_add_defense_compiler_flag("/guard:cf")
ocv_add_defense_compiler_flag("/w34018 /w34146 /w34244 /w34267 /w34302 /w34308 /w34509 /w34532 /w34533 /w34700 /w34789 /w34995 /w34996")
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "${OPENCV_LINKER_DEFENSES_FLAGS_COMMON} /guard:cf /dynamicbase" )
if(NOT X86_64)
if(X86)
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "${OPENCV_LINKER_DEFENSES_FLAGS_COMMON} /safeseh")
endif()
elseif(CV_CLANG)
+1 -1
View File
@@ -200,7 +200,7 @@ if(WITH_LAPACK)
CBLAS_H "cblas.h"
LAPACKE_H "lapacke.h"
INCLUDE_DIR "${OpenBLAS_INCLUDE_DIRS}"
LIBRARIES "${OpenBLAS_LIBRARIES}")
LIBRARIES "${OpenBLAS_LIBRARY};${OpenBLAS_LIBRARIES}")
endif()
endif()
if(NOT LAPACK_LIBRARIES AND UNIX)
+9
View File
@@ -1616,3 +1616,12 @@
volume = {8},
url = {https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=1fbd43f3827fffeb76641a9c5ab5b625eb5a75ba}
}
@article{Aggarwal1985,
author = {Aggarwal, A. and Chang, J. and Yap, Chee K.},
title = {Minimum area circumscribing Polygons},
year = {1985},
pages = {112--117},
journal = {The Visual Computer},
volume = {7},
url = {https://doi.org/10.1007/BF01898354}
}
+8 -3
View File
@@ -16,6 +16,7 @@ python gen_pattern.py -o out.svg -r 11 -c 8 -T circles -s 20.0 -R 5.0 -u mm -w 2
-m, --markers - list of cells with markers for the radon checkerboard
-p, --aruco_marker_size - aruco markers size for ChAruco pattern (default 10.0)
-f, --dict_file - file name of custom aruco dictionary for ChAruco pattern
-do, --dict_offset - index of the first ArUco index used
-H, --help - show help
"""
@@ -27,7 +28,7 @@ from svgfig import *
class PatternMaker:
def __init__(self, cols, rows, output, units, square_size, radius_rate, page_width, page_height, markers, aruco_marker_size, dict_file):
def __init__(self, cols, rows, output, units, square_size, radius_rate, page_width, page_height, markers, aruco_marker_size, dict_file, dict_offset):
self.cols = cols
self.rows = rows
self.output = output
@@ -39,6 +40,7 @@ class PatternMaker:
self.markers = markers
self.aruco_marker_size = aruco_marker_size #for charuco boards only
self.dict_file = dict_file
self.dict_offset = dict_offset
self.g = SVG("g") # the svg group container
@@ -188,7 +190,7 @@ class PatternMaker:
ch_ar_border = (self.square_size - self.aruco_marker_size)/2
if ch_ar_border < side*0.7:
print("Marker border {} is less than 70% of ArUco pin size {}. Please increase --square_size or decrease --marker_size for stable board detection".format(ch_ar_border, int(side)))
marker_id = 0
marker_id = self.dict_offset
for y in range(0, self.rows):
for x in range(0, self.cols):
@@ -248,6 +250,8 @@ def main():
action="store", dest="aruco_marker_size", type=float)
parser.add_argument("-f", "--dict_file", help="file name of custom aruco dictionary for ChAruco pattern", default="DICT_ARUCO_ORIGINAL.json",
action="store", dest="dict_file", type=str)
parser.add_argument("-do", "--dict_offset", help="index of the first ArUco index used", default=0,
action="store", dest="dict_offset", type=int)
args = parser.parse_args()
show_help = args.show_help
@@ -263,6 +267,7 @@ def main():
radius_rate = args.radius_rate
aruco_marker_size = args.aruco_marker_size
dict_file = args.dict_file
dict_offset = args.dict_offset
if 'page_width' and 'page_height' in args:
page_width = args.page_width
@@ -288,7 +293,7 @@ def main():
if p_type == "charuco_board" and aruco_marker_size >= square_size:
raise ValueError("ArUco markers size must be smaller than square size")
pm = PatternMaker(columns, rows, output, units, square_size, radius_rate, page_width, page_height, markers, aruco_marker_size, dict_file)
pm = PatternMaker(columns, rows, output, units, square_size, radius_rate, page_width, page_height, markers, aruco_marker_size, dict_file, dict_offset)
# dict for easy lookup of pattern type
mp = {"circles": pm.make_circles_pattern, "acircles": pm.make_acircles_pattern,
"checkerboard": pm.make_checkerboard_pattern, "radon_checkerboard": pm.make_radon_checkerboard_pattern,
+2 -2
View File
@@ -44,7 +44,7 @@ class aruco_objdetect_test(NewOpenCVTests):
basedir = os.path.abspath(os.path.dirname(__file__))
pm = gen_pattern.PatternMaker(cols, rows, filesvg, "px", square_size, 0, board_width,
board_height, "charuco_checkboard", marker_size,
os.path.join(basedir, aruco_type_str[aruco_type_i]+'.json.gz'))
os.path.join(basedir, aruco_type_str[aruco_type_i]+'.json.gz'), 0)
pm.make_charuco_board()
pm.save()
drawing = svg2rlg(filesvg)
@@ -101,7 +101,7 @@ class aruco_objdetect_test(NewOpenCVTests):
try:
basedir = os.path.abspath(os.path.dirname(__file__))
pm = gen_pattern.PatternMaker(cols, rows, filesvg, "px", square_size, 0, board_width,
board_height, "charuco_checkboard", marker_size, os.path.join(basedir, aruco_type_str+'.json.gz'))
board_height, "charuco_checkboard", marker_size, os.path.join(basedir, aruco_type_str+'.json.gz'), 0)
pm.make_charuco_board()
pm.save()
drawing = svg2rlg(filesvg)
@@ -335,23 +335,6 @@ namespace fs {
//! @} // core_utils
} // namespace cv::utils
//! @cond IGNORED
CV_WRAP static inline
int setLogLevel(int level)
{
// NB: Binding generators doesn't work with enums properly yet, so we define separate overload here
return cv::utils::logging::setLogLevel((cv::utils::logging::LogLevel)level);
}
CV_WRAP static inline
int getLogLevel()
{
return cv::utils::logging::getLogLevel();
}
//! @endcond IGNORED
} // namespaces cv / utils
#endif // OPENCV_CORE_BINDINGS_UTILS_HPP
@@ -170,7 +170,10 @@ inline _InputArray::_InputArray(const std::vector<UMat>& vec) { init(+STD_VECTOR
template<typename _Tp> inline
_InputArray::_InputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); }
{
CV_CheckLE(vec.size(), static_cast<size_t>(std::numeric_limits<int>::max()), "Must not be larger than INT_MAX");
init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec);
}
template<typename _Tp, std::size_t _Nm> inline
_InputArray::_InputArray(const std::array<_Tp, _Nm>& arr)
@@ -22,9 +22,9 @@ namespace logging {
/** Set global logging level
@return previous logging level
*/
CV_EXPORTS LogLevel setLogLevel(LogLevel logLevel);
CV_EXPORTS_W LogLevel setLogLevel(LogLevel logLevel);
/** Get global logging level */
CV_EXPORTS LogLevel getLogLevel();
CV_EXPORTS_W LogLevel getLogLevel();
CV_EXPORTS void registerLogTag(cv::utils::logging::LogTag* plogtag);
+9 -1
View File
@@ -131,7 +131,15 @@ static void generateCentersPP(const Mat& data, Mat& _out_centers,
KMeansPPDistanceComputer(tdist2, data, dist, ci),
(double)divUp((size_t)(dims * N), CV_KMEANS_PARALLEL_GRANULARITY));
double s = 0;
for (int i = 0; i < N; i++)
int i = 0;
#if CV_ENABLE_UNROLLED
for (; i + 7 < N; i += 8)
{
s += tdist2[i + 0] + tdist2[i + 1] + tdist2[i + 2] + tdist2[i + 3] +
tdist2[i + 4] + tdist2[i + 5] + tdist2[i + 6] + tdist2[i + 7];
}
#endif
for (; i < N; i++)
{
s += tdist2[i];
}
+28 -4
View File
@@ -71,7 +71,7 @@ std::shared_ptr<ParallelForAPI> createParallelForAPI()
std::shared_ptr<ParallelForAPI> backend = info.backendFactory->create();
if (!backend)
{
CV_LOG_VERBOSE(NULL, 0, "core(parallel): not available: " << info.name);
CV_LOG_DEBUG(NULL, "core(parallel): not available: " << info.name);
continue;
}
CV_LOG_INFO(NULL, "core(parallel): using backend: " << info.name << " (priority=" << info.priority << ")");
@@ -95,9 +95,16 @@ std::shared_ptr<ParallelForAPI> createParallelForAPI()
else
{
if (!isKnown)
CV_LOG_INFO(NULL, "core(parallel): unknown backend: " << name);
{
CV_LOG_INFO(NULL, "core(parallel): unknown backend: " << name << ", fallback on builtin code");
}
else
{
CV_LOG_INFO(NULL, "core(parallel): backend=" << name << " is not available, fallback on builtin code");
}
}
g_initializedParallelForAPI = true;
getParallelBackendName() = std::string();
return std::shared_ptr<ParallelForAPI>();
}
@@ -127,6 +134,10 @@ bool setParallelForBackend(const std::string& backendName, bool propagateNumThre
{
CV_TRACE_FUNCTION();
bool saved_initialized = g_initializedParallelForAPI;
std::string saved_backendName = getParallelBackendName();
std::shared_ptr<ParallelForAPI> saved_backend; // don't call getCurrentParallelForAPI() if g_initializedParallelForAPI = false to avoid unnecessary "default" initialization
std::string backendName_u = toUpperCase(backendName);
if (g_initializedParallelForAPI)
{
@@ -138,8 +149,9 @@ bool setParallelForBackend(const std::string& backendName, bool propagateNumThre
}
else
{
saved_backend = getCurrentParallelForAPI();
// ... re-create new
CV_LOG_DEBUG(NULL, "core(parallel): replacing parallel backend...");
CV_LOG_DEBUG(NULL, "core(parallel): replacing parallel backend (old=" << saved_backendName << " new=" << backendName << ")...");
getParallelBackendName() = backendName_u;
getCurrentParallelForAPI() = createParallelForAPI();
}
@@ -154,7 +166,19 @@ bool setParallelForBackend(const std::string& backendName, bool propagateNumThre
{
if (!backendName.empty())
{
CV_LOG_WARNING(NULL, "core(parallel): backend is not available: " << backendName << " (using builtin legacy code)");
// restore previous backend or build default
getParallelBackendName() = saved_backendName;
if (saved_initialized)
{
CV_LOG_WARNING(NULL, "core(parallel): backend is not available: " << backendName << " (keep previous)");
getCurrentParallelForAPI() = saved_backend;
}
else
{
CV_LOG_WARNING(NULL, "core(parallel): backend is not available: " << backendName << " (use default)");
g_initializedParallelForAPI = false;
getCurrentParallelForAPI() = createDefaultParallelForAPI();
}
return false;
}
else
+8
View File
@@ -1376,6 +1376,14 @@ TEST(Core_InputArray, empty)
ASSERT_TRUE( _InputArray(data).empty() );
}
TEST(Core_InputArray, convert_from_vector_over2GB)
{
applyTestTag(CV_TEST_TAG_MEMORY_6GB);
// empty buffer more than 2GB size
std::vector<uint8_t> buf(size_t(INT_MAX) + 4096);
EXPECT_ANY_THROW(auto work = _InputArray(buf));
}
TEST(Core_CopyMask, bug1918)
{
Mat_<unsigned char> tmpSrc(100,100);
@@ -1852,6 +1852,7 @@ void convBlockMR1_F32(int np, const float* a, const float* b, float *c, const fl
}
#if CV_SIMD128
#if CONV_NR_FP32 > 8
static inline void convBlock4x24(int np, const float* a, const float* b, float* c, int ldc, bool init_c, const int convMR, const int convNR)
{
v_float32x4 c0 = v_setzero_f32(), c1 = c0, c2 = c0, c3 = c0, c4 = c0, c5 = c0;
@@ -1956,6 +1957,7 @@ static inline void convBlock4x24(int np, const float* a, const float* b, float*
v_store(c + ldc * 3 + 16, c22);
v_store(c + ldc * 3 + 20, c23);
}
#endif
static inline void convBlock4x8(int np, const float* a, const float* b, float* c, int ldc, bool init_c, const int convMR, const int convNR)
{
@@ -2084,11 +2086,13 @@ void convBlock_F32(int np, const float* a, const float* b, float* c, int ldc, bo
// The possible outLen range is [24, 8~1].
#if CV_SIMD128
CV_Assert(convMR == 4);
#if CONV_NR_FP32 > 8
if (outLen > 8 && convNR == 24)
{
convBlock4x24(np, a, b, c, ldc, init_c, convMR, convNR);
return;
}
#endif
if (outLen <= 8 && outLen > 4)
{
@@ -28,6 +28,9 @@
#elif CV_NEON // 16 registers.
#define CONV_MR_FP32 4
#define CONV_NR_FP32 12
#elif CV_WASM_SIMD
#define CONV_MR_FP32 4
#define CONV_NR_FP32 8
#else // SIMD 128, AVX or AVX2
#define CONV_MR_FP32 4
#define CONV_NR_FP32 24
+20 -2
View File
@@ -48,7 +48,16 @@ void softmax(Mat &dst, const Mat &src, int axis, int axisBias, int axisStep){
size_t innerDim = i % innerSize;
size_t srcOffset = outerDim * outerStep + innerDim;
// copy data from src to buf along axis, since the data may not be continuous
for (size_t _cnDim = 0; _cnDim < axisStep; _cnDim++)
size_t _cnDim = 0;
#if CV_ENABLE_UNROLLED && defined(_M_ARM64)
for (; _cnDim + 3 < axisStep; _cnDim += 4) {
axisBuf[_cnDim + 0] = srcPtr[srcOffset + (_cnDim + 0 + axisBias) * cnStep];
axisBuf[_cnDim + 1] = srcPtr[srcOffset + (_cnDim + 1 + axisBias) * cnStep];
axisBuf[_cnDim + 2] = srcPtr[srcOffset + (_cnDim + 2 + axisBias) * cnStep];
axisBuf[_cnDim + 3] = srcPtr[srcOffset + (_cnDim + 3 + axisBias) * cnStep];
}
#endif
for (; _cnDim < axisStep; _cnDim++)
axisBuf[_cnDim] = srcPtr[srcOffset + (_cnDim + axisBias) * cnStep];
float maxVal = -FLT_MAX;
@@ -95,7 +104,16 @@ void softmax(Mat &dst, const Mat &src, int axis, int axisBias, int axisStep){
s = 1.f / s;
// copy back the result to src
for (size_t _cnDim = 0; _cnDim < axisStep; _cnDim++)
_cnDim = 0;
#if CV_ENABLE_UNROLLED && defined(_M_ARM64)
for (; _cnDim + 3 < axisStep; _cnDim += 4) {
dstPtr[srcOffset + (_cnDim + 0 + axisBias) * cnStep] = axisBuf[_cnDim + 0] * s;
dstPtr[srcOffset + (_cnDim + 1 + axisBias) * cnStep] = axisBuf[_cnDim + 1] * s;
dstPtr[srcOffset + (_cnDim + 2 + axisBias) * cnStep] = axisBuf[_cnDim + 2] * s;
dstPtr[srcOffset + (_cnDim + 3 + axisBias) * cnStep] = axisBuf[_cnDim + 3] * s;
}
#endif
for (; _cnDim < axisStep; _cnDim++)
dstPtr[srcOffset + (_cnDim + axisBias) * cnStep] = axisBuf[_cnDim] * s;
}
}, nstripes);
+13 -1
View File
@@ -174,8 +174,20 @@ void FAST_t(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bo
if(nonmax_suppression)
{
short d[25];
for (int _k = 0; _k < 25; _k++)
int _k = 0;
#if CV_ENABLE_UNROLLED
for (; _k + 4 < 25; _k += 5)
{
d[_k] = (short)(ptr[k] - ptr[k + pixel[_k]]);
d[_k + 1] = (short)(ptr[k] - ptr[k + pixel[_k + 1]]);
d[_k + 2] = (short)(ptr[k] - ptr[k + pixel[_k + 2]]);
d[_k + 3] = (short)(ptr[k] - ptr[k + pixel[_k + 3]]);
d[_k + 4] = (short)(ptr[k] - ptr[k + pixel[_k + 4]]);
}
#else
for ( ; _k < 25; _k++)
d[_k] = (short)(ptr[k] - ptr[k + pixel[_k]]);
#endif
v_int16x8 a0, b0, a1, b1;
a0 = b0 = a1 = b1 = v_load(d + 8);
@@ -95,9 +95,9 @@ enum ImwriteFlags {
IMWRITE_JPEG_SAMPLING_FACTOR = 7, //!< For JPEG, set sampling factor. See cv::ImwriteJPEGSamplingFactorParams.
IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. If specified, strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY). Default value is 1 (best speed setting).
IMWRITE_PNG_STRATEGY = 17, //!< For PNG, One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE.
IMWRITE_PNG_BILEVEL = 18, //!< For PNG, Binary level PNG, 0 or 1, default is 0.
IMWRITE_PNG_FILTER = 19, //!< For PNG, One of cv::ImwritePNGFilterFlags, default is IMWRITE_PNG_FILTER_SUB.
IMWRITE_PNG_ZLIBBUFFER_SIZE = 20, //!< For PNG with libpng, sets the size of the internal zlib compression buffer in bytes, from 6 to 1048576(1024 KiB). Default is 8192(8 KiB). For normal use, 131072(128 KiB) or 262144(256 KiB) may be sufficient. If WITH_SPNG=ON, it is not supported.
IMWRITE_PNG_BILEVEL = 18, //!< For PNG, Binary level PNG, 0 or 1, default is 0. For APNG, it is not supported.
IMWRITE_PNG_FILTER = 19, //!< For PNG, One of cv::ImwritePNGFilterFlags, default is IMWRITE_PNG_FILTER_SUB. For APNG, it is not supported.
IMWRITE_PNG_ZLIBBUFFER_SIZE = 20, //!< For PNG with libpng, sets the size of the internal zlib compression buffer in bytes, from 6 to 1048576(1024 KiB). Default is 8192(8 KiB). For normal use, 131072(128 KiB) or 262144(256 KiB) may be sufficient. If WITH_SPNG=ON, it is not supported. For APNG, it is not supported.
IMWRITE_PXM_BINARY = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1.
IMWRITE_EXR_TYPE = (3 << 4) + 0 /* 48 */, //!< override EXR storage type (FLOAT (FP32) is default)
IMWRITE_EXR_COMPRESSION = (3 << 4) + 1 /* 49 */, //!< override EXR compression type (ZIP_COMPRESSION = 3 is default)
+15 -5
View File
@@ -59,7 +59,17 @@ void RBaseStream::readBlock()
throw RBS_THROW_EOS;
}
#ifdef _WIN32
// See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fseek-fseeki64?view=msvc-170
// See https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
// - Windows uses LLP64 data model, sizeof long int = 32.
// - Linux uses LP64 data model, sizeof long int = 64.
// So for Windows, we have to use _fseeki64() instead of fseek().
_fseeki64( m_file, m_block_pos, SEEK_SET );
#else
fseek( m_file, m_block_pos, SEEK_SET );
#endif
size_t readed = fread( m_start, 1, m_block_size, m_file );
m_end = m_start + readed;
@@ -120,7 +130,7 @@ void RBaseStream::release()
}
void RBaseStream::setPos( int pos )
void RBaseStream::setPos( int64_t pos )
{
CV_Assert(isOpened() && pos >= 0);
@@ -132,7 +142,7 @@ void RBaseStream::setPos( int pos )
}
int offset = pos % m_block_size;
int old_block_pos = m_block_pos;
int64_t old_block_pos = m_block_pos;
m_block_pos = pos - offset;
m_current = m_start + offset;
if (old_block_pos != m_block_pos)
@@ -140,16 +150,16 @@ void RBaseStream::setPos( int pos )
}
int RBaseStream::getPos()
int64_t RBaseStream::getPos()
{
CV_Assert(isOpened());
int pos = validateToInt((m_current - m_start) + m_block_pos);
int64_t pos = validateToInt64((m_current - m_start) + m_block_pos);
CV_Assert(pos >= m_block_pos); // overflow check
CV_Assert(pos >= 0); // overflow check
return pos;
}
void RBaseStream::skip( int bytes )
void RBaseStream::skip( int64_t bytes )
{
CV_Assert(bytes >= 0);
uchar* old = m_current;
+4 -4
View File
@@ -45,9 +45,9 @@ public:
virtual bool open( const Mat& buf );
virtual void close();
bool isOpened();
void setPos( int pos );
int getPos();
void skip( int bytes );
void setPos( int64_t pos );
int64_t getPos();
void skip( int64_t bytes );
protected:
@@ -57,7 +57,7 @@ protected:
uchar* m_current;
FILE* m_file;
int m_block_size;
int m_block_pos;
int64_t m_block_pos;
bool m_is_opened;
virtual void readBlock();
-3
View File
@@ -237,9 +237,6 @@ bool BmpDecoder::readData( Mat& img )
int nch = color ? 3 : 1;
int y, width3 = m_width*nch;
// FIXIT: use safe pointer arithmetic (avoid 'int'), use size_t, intptr_t, etc
CV_Assert(((uint64)m_height * m_width * nch < (CV_BIG_UINT(1) << 30)) && "BMP reader implementation doesn't support large images >= 1Gb");
if( m_offset < 0 || !m_strm.isOpened())
return false;
+1 -1
View File
@@ -87,7 +87,7 @@ protected:
PaletteEntry m_palette[256];
Origin m_origin;
int m_bpp;
int m_offset;
int64_t m_offset;
BmpCompression m_rle_code;
uint m_rgba_mask[4];
int m_rgba_bit_offset[4];
+2 -2
View File
@@ -78,8 +78,8 @@ public:
protected:
RLByteStream m_strm;
int m_maxval, m_channels, m_sampledepth, m_offset,
selected_fmt;
int64_t m_offset;
int m_maxval, m_channels, m_sampledepth, selected_fmt;
bool bit_mode;
};
+163 -122
View File
@@ -434,138 +434,147 @@ bool PngDecoder::readData( Mat& img )
if (!processing_start((void*)&frameRaw, mat_cur))
return false;
while (true)
// See https://github.com/opencv/opencv/issues/27744
if( setjmp( png_jmpbuf ( m_png_ptr ) ) == 0 )
{
id = read_chunk(chunk);
if (!id)
return false;
if (id == id_fcTL && m_is_IDAT_loaded)
while (true)
{
if (!m_is_fcTL_loaded)
id = read_chunk(chunk);
if (!id)
return false;
if (id == id_fcTL && m_is_IDAT_loaded)
{
m_mat_raw.copyTo(m_animation.still_image);
}
else
{
if (processing_finish())
if (!m_is_fcTL_loaded)
{
if (dop == 2)
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (x0 + w0 > frameCur.getWidth() || y0 + h0 > frameCur.getHeight())
return false;
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000. * delay_num / delay_den));
if (mat_cur.channels() == img.channels())
m_mat_raw.copyTo(m_animation.still_image);
}
else
{
if (processing_finish())
{
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(img, CV_8U, 1. / 255);
if (dop == 2)
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (x0 + w0 > frameCur.getWidth() || y0 + h0 > frameCur.getHeight())
return false;
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000. * delay_num / delay_den));
if (mat_cur.channels() == img.channels())
{
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(img, CV_8U, 1. / 255);
else
mat_cur.copyTo(img);
}
else
mat_cur.copyTo(img);
{
Mat mat_cur_scaled;
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur_scaled, CV_8U, 1. / 255);
else
mat_cur_scaled = mat_cur;
if (img.channels() == 1)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2BGR);
}
if (dop != 2)
{
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (dop == 1)
for (j = 0; j < h0; j++)
memset(frameNext.getRows()[y0 + j] + x0 * img.channels(), 0, w0 * img.channels());
}
}
else
{
Mat mat_cur_scaled;
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur_scaled, CV_8U, 1. / 255);
else
mat_cur_scaled = mat_cur;
if (img.channels() == 1)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2BGR);
return false;
}
}
if (dop != 2)
w0 = png_get_uint_32(&chunk.p[12]);
h0 = png_get_uint_32(&chunk.p[16]);
x0 = png_get_uint_32(&chunk.p[20]);
y0 = png_get_uint_32(&chunk.p[24]);
delay_num = png_get_uint_16(&chunk.p[28]);
delay_den = png_get_uint_16(&chunk.p[30]);
dop = chunk.p[32];
bop = chunk.p[33];
if (int(x0 + w0) > img.cols || int(y0 + h0) > img.rows || dop > 2 || bop > 1)
{
return false;
}
memcpy(&m_chunkIHDR.p[8], &chunk.p[12], 8);
if (m_is_fcTL_loaded)
return true;
else
{
m_is_fcTL_loaded = true;
ClearPngPtr();
if (!processing_start((void*)&frameRaw, mat_cur))
return false;
}
}
else if (id == id_IDAT)
{
m_is_IDAT_loaded = true;
png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
}
else if (id == id_fdAT && m_is_fcTL_loaded)
{
m_is_IDAT_loaded = true;
png_save_uint_32(&chunk.p[4], static_cast<uint32_t>(chunk.p.size() - 16));
memcpy(&chunk.p[8], "IDAT", 4);
png_process_data(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4);
}
else if (id == id_IEND)
{
if (processing_finish())
{
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den));
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U && mat_cur.channels() == img.channels())
mat_cur.convertTo(img, CV_8U, 1. / 255);
else
{
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (dop == 1)
for (j = 0; j < h0; j++)
memset(frameNext.getRows()[y0 + j] + x0 * img.channels(), 0, w0 * img.channels());
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur, CV_8U, 1. / 255);
if (mat_cur.channels() == img.channels())
mat_cur.copyTo(img);
else if (img.channels() == 1)
cvtColor(mat_cur, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur, img, COLOR_BGRA2BGR);
}
}
else
{
return false;
}
}
w0 = png_get_uint_32(&chunk.p[12]);
h0 = png_get_uint_32(&chunk.p[16]);
x0 = png_get_uint_32(&chunk.p[20]);
y0 = png_get_uint_32(&chunk.p[24]);
delay_num = png_get_uint_16(&chunk.p[28]);
delay_den = png_get_uint_16(&chunk.p[30]);
dop = chunk.p[32];
bop = chunk.p[33];
if (int(x0 + w0) > img.cols || int(y0 + h0) > img.rows || dop > 2 || bop > 1)
{
return false;
}
memcpy(&m_chunkIHDR.p[8], &chunk.p[12], 8);
if (m_is_fcTL_loaded)
return true;
else
{
m_is_fcTL_loaded = true;
ClearPngPtr();
if (!processing_start((void*)&frameRaw, mat_cur))
return false;
}
}
else if (id == id_IDAT)
{
m_is_IDAT_loaded = true;
png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
}
else if (id == id_fdAT && m_is_fcTL_loaded)
{
m_is_IDAT_loaded = true;
png_save_uint_32(&chunk.p[4], static_cast<uint32_t>(chunk.p.size() - 16));
memcpy(&chunk.p[8], "IDAT", 4);
png_process_data(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4);
}
else if (id == id_IEND)
{
if (processing_finish())
{
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den));
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U && mat_cur.channels() == img.channels())
mat_cur.convertTo(img, CV_8U, 1. / 255);
else
{
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur, CV_8U, 1. / 255);
if (mat_cur.channels() == img.channels())
mat_cur.copyTo(img);
else if (img.channels() == 1)
cvtColor(mat_cur, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur, img, COLOR_BGRA2BGR);
}
}
else
return false;
return true;
png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
}
else
png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
return false;
}
else
{
// libpng internal error is detected.
return false;
}
return false;
}
volatile bool result = false;
@@ -1621,20 +1630,52 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vector<in
for (size_t i = 0; i < params.size(); i += 2)
{
if (params[i] == IMWRITE_PNG_COMPRESSION)
const int value = params[i+1];
switch (params[i])
{
case IMWRITE_PNG_COMPRESSION:
m_compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy
m_compression_level = params[i + 1];
m_compression_level = MIN(MAX(m_compression_level, 0), Z_BEST_COMPRESSION);
}
if (params[i] == IMWRITE_PNG_STRATEGY)
{
m_compression_strategy = params[i + 1];
m_compression_strategy = MIN(MAX(m_compression_strategy, 0), Z_FIXED);
}
if (params[i] == IMWRITE_PNG_BILEVEL)
{
m_isBilevel = params[i + 1] != 0;
m_compression_level = MIN(MAX(value, 0), Z_BEST_COMPRESSION);
if(value != m_compression_level) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, m_compression_level));
}
break;
case IMWRITE_PNG_STRATEGY:
{
switch(value) {
case IMWRITE_PNG_STRATEGY_DEFAULT:
case IMWRITE_PNG_STRATEGY_FILTERED:
case IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY:
case IMWRITE_PNG_STRATEGY_RLE:
case IMWRITE_PNG_STRATEGY_FIXED:
m_compression_strategy = value;
break;
default:
m_compression_strategy = IMWRITE_PNG_STRATEGY_RLE;
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_STRATEGY must be one of ImwritePNGFlags. It is fallbacked to IMWRITE_PNG_STRATEGY_RLE", value));
break;
}
}
break;
case IMWRITE_PNG_BILEVEL:
m_isBilevel = value != 0;
if((value != 0) && (value != 1)) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_BILEVEL must be 0 or 1. It is fallbacked to 1", value ));
}
break;
case IMWRITE_PNG_FILTER:
CV_LOG_WARNING(nullptr, "IMWRITE_PNG_BILEVEL parameter is not supported for APNG");
break;
case IMWRITE_PNG_ZLIBBUFFER_SIZE:
CV_LOG_WARNING(nullptr, "IMWRITE_PNG_ZLIBBUFFER_SIZE parameter is not supported for APNG");
break;
default:
break;
}
}
+1 -1
View File
@@ -79,7 +79,7 @@ protected:
RLByteStream m_strm;
PaletteEntry m_palette[256];
int m_bpp;
int m_offset;
int64_t m_offset;
bool m_binary;
int m_maxval;
};
+3 -3
View File
@@ -540,8 +540,8 @@ bool SPngEncoder::write(const Mat &img, const std::vector<int> &params)
{
compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy
compression_level = MIN(MAX(value, 0), Z_BEST_COMPRESSION);
if(value != m_compression_level) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, m_compression_level));
if(value != compression_level) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, compression_level));
}
set_compression_level = true;
}
@@ -556,7 +556,7 @@ bool SPngEncoder::write(const Mat &img, const std::vector<int> &params)
compression_strategy = value;
break;
default:
compression_strategy = IMWRITE_PNG_STRATEGY_RLE:
compression_strategy = IMWRITE_PNG_STRATEGY_RLE;
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_STRATEGY must be one of ImwritePNGFlags. It is fallbacked to IMWRITE_PNG_STRATEGY_RLE", value));
break;
}
+2 -2
View File
@@ -94,7 +94,7 @@ bool SunRasterDecoder::readHeader()
m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1;
m_offset = m_strm.getPos();
CV_Assert(m_offset == 32 + m_maplength);
CV_Assert(m_offset == static_cast<int64_t>(32 + m_maplength));
result = true;
}
}
@@ -107,7 +107,7 @@ bool SunRasterDecoder::readHeader()
m_offset = m_strm.getPos();
CV_Assert(m_offset == 32 + m_maplength);
CV_Assert(m_offset == static_cast<int64_t>(32 + m_maplength));
result = true;
}
}
+1 -1
View File
@@ -84,7 +84,7 @@ protected:
RMByteStream m_strm;
PaletteEntry m_palette[256];
int m_bpp;
int m_offset;
int64_t m_offset;
SunRasType m_encoding;
SunRasMapType m_maptype;
int m_maplength;
+10 -7
View File
@@ -511,23 +511,26 @@ bool WebPEncoder::writeanimation(const Animation& animation, const std::vector<i
anim_config.anim_params.bgcolor = bgvalue;
anim_config.anim_params.loop_count = animation.loop_count;
anim_config.minimize_size = 0;
if (params.size() > 1)
for(size_t i = 0; i < params.size(); i += 2)
{
if (params[0] == IMWRITE_WEBP_QUALITY)
const int value = params[i+1];
if (params[i] == IMWRITE_WEBP_QUALITY)
{
config.lossless = 0;
config.quality = static_cast<float>(params[1]);
config.lossless = 0; // false
config.quality = static_cast<float>(value);
if (config.quality < 1.0f)
{
config.quality = 1.0f;
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_WEBP_QUALITY must be between 1 to 100(lossy) or more(lossless). It is fallbacked to 1", value));
}
if (config.quality >= 100.0f)
if (config.quality > 100.0f)
{
config.lossless = 1;
config.quality = 100.0f;
config.lossless = 1; // true
}
}
anim_config.minimize_size = 0;
}
std::unique_ptr<WebPAnimEncoder, void (*)(WebPAnimEncoder*)> anim_encoder(
+7
View File
@@ -51,6 +51,13 @@ int validateToInt(size_t sz)
return valueInt;
}
int64_t validateToInt64(size_t sz)
{
int64_t valueInt = static_cast<int64_t>(sz);
CV_Assert((size_t)valueInt == sz);
return valueInt;
}
#define SCALE 14
#define cR (int)(0.299*(1 << SCALE) + 0.5)
#define cG (int)(0.587*(1 << SCALE) + 0.5)
+1
View File
@@ -45,6 +45,7 @@
namespace cv {
int validateToInt(size_t step);
int64_t validateToInt64(size_t step);
template <typename _Tp> static inline
size_t safeCastToSizeT(const _Tp v_origin, const char* msg)
+61
View File
@@ -0,0 +1,61 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "test_precomp.hpp"
#include "test_common.hpp"
#include <vector>
namespace opencv_test { namespace {
// See https://github.com/opencv/opencv/issues/27789
// See https://github.com/opencv/opencv/issues/23233
TEST(Imgcodecs_BMP, encode_decode_over1GB_regression27789)
{
applyTestTag( CV_TEST_TAG_MEMORY_2GB, CV_TEST_TAG_LONG );
// Create large Mat over 1GB
// 20000 px * 18000 px * 24 bpp(3ch) = 1,080,000,000 bytes
// 1 GiB = 1,073,741,824 bytes
cv::Mat src(20000, 18000, CV_8UC3, cv::Scalar(0,0,0));
// Encode large BMP file.
std::vector<uint8_t> buf;
bool ret = false;
ASSERT_NO_THROW(ret = cv::imencode(".bmp", src, buf, {}));
ASSERT_TRUE(ret);
src.release(); // To reduce usage memory, it is needed.
// Decode large BMP file.
cv::Mat dst;
ASSERT_NO_THROW(dst = cv::imdecode(buf, cv::IMREAD_COLOR));
ASSERT_FALSE(dst.empty());
}
TEST(Imgcodecs_BMP, write_read_over1GB_regression27789)
{
// tag CV_TEST_TAG_VERYLONG applied to skip on CI. The test writes ~1GB file.
applyTestTag( CV_TEST_TAG_MEMORY_2GB, CV_TEST_TAG_VERYLONG );
string bmpFilename = cv::tempfile(".bmp"); // To remove it, test must use EXPECT_* instead of ASSERT_*.
// Create large Mat over 1GB
// 20000 px * 18000 px * 24 bpp(3ch) = 1,080,000,000 bytes
// 1 GiB = 1,073,741,824 bytes
cv::Mat src(20000, 18000, CV_8UC3, cv::Scalar(0,0,0));
// Write large BMP file.
bool ret = false;
EXPECT_NO_THROW(ret = cv::imwrite(bmpFilename, src, {}));
EXPECT_TRUE(ret);
// Read large BMP file.
cv::Mat dst;
EXPECT_NO_THROW(dst = cv::imread(bmpFilename, cv::IMREAD_COLOR));
EXPECT_FALSE(dst.empty());
remove(bmpFilename.c_str());
}
}} // namespace
+45
View File
@@ -157,6 +157,51 @@ TEST(Imgcodecs_Png, decode_regression27295)
EXPECT_TRUE(img.empty());
}
// The program must not crash even when decoding a corrupted APNG image.
// See https://github.com/opencv/opencv/issues/27744
#if defined(HAVE_PNG) // APNG is supported only with using libpng
TEST(Imgcodecs_Png, decode_regression27744)
{
// Create APNG stream
Animation anim;
for(size_t i = 0 ; i < 3 ; i++) {
Mat frame(120, 120, CV_8UC3, Scalar(0,0,0));
putText(frame, cv::format("%d", static_cast<int>(i)), Point(5, 28), FONT_HERSHEY_SIMPLEX, .5, Scalar(100, 255, 0, 255), 2);
anim.frames.push_back(frame);
anim.durations.push_back(30);
}
bool ret = false;
vector<uchar> buff;
EXPECT_NO_THROW(ret = imencodeanimation(".png", anim, buff));
ASSERT_TRUE(ret) << "imencodeanimation() returns false";
// Find IDAT chunk
const vector<uchar> IDAT = {'I', 'D', 'A', 'T' };
std::vector<uchar>::iterator it = std::search(buff.begin(), buff.end(), IDAT.begin(), IDAT.end());
ASSERT_FALSE(it == buff.end()) << "IDAT chunk not found";
// Determine the range to test
// APNG stream contains as { len0, len1, len2, len3, 'I', 'D', 'A' 'T', ... }
size_t idx = std::distance(buff.begin(), it); // 'I' position
size_t len = (buff[idx-4] << 24) + (buff[idx-3] << 16) +
(buff[idx-2] << 8) + (buff[idx-1]); // IDAT chunk length
idx = idx + 4; // Move to IDAT body
// Test
for(size_t i = 0; i < len; i++, idx++) {
vector<uint8_t> work = buff;
work[idx] = static_cast<uint8_t>((static_cast<uint32_t>(work[idx]) + 1) & 0xff);
Mat dst;
EXPECT_NO_THROW(dst = imdecode(work, cv::IMREAD_COLOR));
if(dst.empty()) {
// libpng detects some error, but the program is not crashed. Test is passed.
break;
}
}
}
#endif
typedef testing::TestWithParam<string> Imgcodecs_Png_PngSuite;
// Parameterized test for decoding PNG files from the PNGSuite test set
@@ -619,4 +619,13 @@ TEST(Imgcodecs_Params, imencode_regression_22752)
EXPECT_ANY_THROW(cv::imencode("test.jpg", img, buf, params)); // parameters size or missing JPEG codec
}
TEST(Imgcodecs, decode_over2GB)
{
applyTestTag(CV_TEST_TAG_MEMORY_6GB);
// empty buffer more than 2GB size
std::vector<uint8_t> buf(size_t(INT_MAX) + 4096);
cv::Mat dst;
EXPECT_THROW(dst = cv::imdecode(buf, cv::IMREAD_COLOR), cv::Exception);
}
}} // namespace
+1 -1
View File
@@ -8,7 +8,7 @@ ocv_add_dispatched_file(color_rgb SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(color_yuv SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(median_blur SSE2 SSE4_1 AVX2 AVX512_SKX)
ocv_add_dispatched_file(morph SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2 AVX512_ICL)
ocv_add_dispatched_file(sumpixels SSE2 AVX2 AVX512_SKX)
ocv_add_dispatched_file(warp_kernels SSE2 SSE4_1 AVX2 NEON NEON_FP16 RVV LASX)
ocv_define_module(imgproc opencv_core WRAP java objc python js)
+27 -2
View File
@@ -4079,7 +4079,7 @@ The algorithm based on the paper @cite LowIlie2003 .
@param approxCurve Result of the approximation. The type is vector of a 2D point (Point2f or Point) in std::vector or Mat.
@param nsides The parameter defines the number of sides of the result polygon.
@param epsilon_percentage defines the percentage of the maximum of additional area.
If it equals -1, it is not used. Otherwise algorighm stops if additional area is greater than contourArea(_curve) * percentage.
If it equals -1, it is not used. Otherwise algorithm stops if additional area is greater than contourArea(_curve) * percentage.
If additional area exceeds the limit, algorithm returns as many vertices as there were at the moment the limit was exceeded.
@param ensure_convex If it is true, algorithm creates a convex hull of input contour. Otherwise input vector should be convex.
*/
@@ -4157,7 +4157,8 @@ The function finds the four vertices of a rotated rectangle. The four vertices a
in clockwise order starting from the point with greatest \f$y\f$. If two points have the
same \f$y\f$ coordinate the rightmost is the starting point. This function is useful to draw the
rectangle. In C++, instead of using this function, you can directly use RotatedRect::points method. Please
visit the @ref tutorial_bounding_rotated_ellipses "tutorial on Creating Bounding rotated boxes and ellipses for contours" for more information.
visit the @ref tutorial_bounding_rotated_ellipses "tutorial on Creating Bounding rotated boxes and ellipses
for contours" for more information.
@param box The input rotated rectangle. It may be the output of @ref minAreaRect.
@param points The output array of four vertices of rectangles.
@@ -4197,6 +4198,30 @@ of the OutputArray must be CV_32F.
*/
CV_EXPORTS_W double minEnclosingTriangle( InputArray points, CV_OUT OutputArray triangle );
/**
@brief Finds a convex polygon of minimum area enclosing a 2D point set and returns its area.
This function takes a given set of 2D points and finds the enclosing polygon with k vertices and minimal
area. It takes the set of points and the parameter k as input and returns the area of the minimal
enclosing polygon.
The Implementation is based on a paper by Aggarwal, Chang and Yap @cite Aggarwal1985. They
provide a \f$\theta(n²log(n)log(k))\f$ algorighm for finding the minimal convex polygon with k
vertices enclosing a 2D convex polygon with n vertices (k < n). Since the #minEnclosingConvexPolygon
function takes a 2D point set as input, an additional preprocessing step of computing the convex hull
of the 2D point set is required. The complexity of the #convexHull function is \f$O(n log(n))\f$ which
is lower than \f$\theta(n²log(n)log(k))\f$. Thus the overall complexity of the function is
\f$O(n²log(n)log(k))\f$.
@param points Input vector of 2D points, stored in std::vector\<\> or Mat
@param polygon Output vector of 2D points defining the vertices of the enclosing polygon
@param k Number of vertices of the output polygon
*/
CV_EXPORTS_W double minEnclosingConvexPolygon ( InputArray points, OutputArray polygon, int k );
/** @brief Compares two shapes.
The function compares two shapes. All three implemented methods use the Hu invariants (see #HuMoments)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+101
View File
@@ -1069,5 +1069,106 @@ TEST(minEnclosingCircle, three_points)
EXPECT_LE(delta, 1.f);
}
//============================ minEnclosingPolygon tests ============================
TEST(minEnclosingPolygon, input_errors)
{
std::vector<cv::Point2f> kgon;
std::vector<cv::Point2f> ngon {{0.0, 0.0}, {1.0, 1.0}};
EXPECT_THROW(minEnclosingConvexPolygon(ngon, kgon, 3), cv::Exception);
ngon = {{0.0, 0.0}, {0.0, 1.0}, {1.0, 0.0}, {1.0, 1.0}};
EXPECT_THROW(minEnclosingConvexPolygon(ngon, kgon, 2), cv::Exception);
EXPECT_THROW(minEnclosingConvexPolygon(ngon, kgon, 5), cv::Exception);
}
TEST(minEnclosingPolygon, input_corner_cases)
{
double area = -1.0;
std::vector<cv::Point2f> kgon;
std::vector<cv::Point2f> ngon = {{0.0, 0.0}, {0.0, 0.0}, {1.0, 1.0}, {1.0, 1.0}};
EXPECT_NO_THROW(area = minEnclosingConvexPolygon(ngon, kgon, 3))
<< "unexpected exception: not enough different points in input ngon (double points)";
EXPECT_LE(area, 0.);
EXPECT_TRUE(kgon.empty());
ngon = {{0.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}};
EXPECT_NO_THROW(area = minEnclosingConvexPolygon(ngon, kgon, 3))
<< "unexpected exception: all points on line";
EXPECT_LE(area, 0.);
EXPECT_TRUE(kgon.empty());
}
TEST(minEnclosingPolygon, unit_circle)
{
const int n = 64;
const int k = 7;
double area = -1.0;
std::vector<cv::Point2f> kgon;
std::vector<cv::Point2f> ngon(n);
for(int i = 0; i < n; i++)
{
ngon[i] = { cosf(float(i * 2.f * M_PI / n)), sinf(float(i * 2.f * M_PI / n)) };
}
EXPECT_NO_THROW(area = minEnclosingConvexPolygon(ngon, kgon, k));
EXPECT_GT(area, cv::contourArea(ngon));
EXPECT_EQ((int)kgon.size(), k);
}
TEST(minEnclosingPolygon, random_points)
{
const int n = 100;
const int k = 7;
double area = -1.0;
std::vector<cv::Point2f> kgon;
std::vector<cv::Point2f> ngon(n);
std::vector<cv::Point2f> ngonHull;
cv::randu(ngon, 1, 101);
cv::convexHull(ngon, ngonHull, true);
EXPECT_NO_THROW(area = minEnclosingConvexPolygon(ngon, kgon, k));
EXPECT_GT(area, cv::contourArea(ngonHull));
EXPECT_EQ(kgon.size(), (size_t)k);
}
TEST(minEnclosingPolygon, pentagon)
{
double area;
std::vector<cv::Point2f> kgon;
std::vector<cv::Point2f> expectedKgon;
std::vector<cv::Point2f> ngon;
ngon = {{1, 0}, {0, 8}, {4, 12}, {8, 8}, {7, 0}};
EXPECT_NO_THROW({
area = minEnclosingConvexPolygon(ngon, kgon, 4);
});
expectedKgon = {{1, 0}, {-0.5, 12}, {8.5, 12}, {7, 0}};
EXPECT_EQ(area, cv::contourArea(expectedKgon));
ASSERT_EQ((int)kgon.size(), 4);
for (size_t i = 0; i < 4; i++)
{
bool match = false;
for (size_t j = 0; j < 4; j++)
{
if(expectedKgon[i].x == kgon[j].x && expectedKgon[i].y == kgon[j].y)
{
match = true;
break;
}
}
EXPECT_EQ(match, true);
}
}
}} // namespace
/* End of file. */
+34 -6
View File
@@ -320,7 +320,6 @@ class Namespace(object):
class JSWrapperGenerator(object):
def __init__(self, preprocessor_definitions=None):
self.bindings = []
self.wrapper_funcs = []
@@ -333,6 +332,29 @@ class JSWrapperGenerator(object):
)
self.class_idx = 0
def _is_string_type(self, tp: str) -> bool:
"""Check if a type should be treated as string in bindings."""
string_types = {
"std::string",
"char",
"signed char",
"unsigned char",
}
return tp in string_types
def _generate_class_properties(self, class_info, class_bindings):
# Generate bindings for properties
for prop in class_info.props:
if prop.tp in type_dict and not self._is_string_type(prop.tp):
_class_property = class_property_enum_template
else:
_class_property = class_property_template
class_bindings.append(_class_property.substitute(
js_name=prop.name,
cpp_name='::'.join([class_info.cname, prop.name])
))
def add_class(self, stype, name, decl):
class_info = ClassInfo(name, decl)
class_info.decl_idx = self.class_idx
@@ -893,11 +915,17 @@ class JSWrapperGenerator(object):
# Generate bindings for properties
for property in class_info.props:
_class_property = class_property_enum_template if property.tp in type_dict else class_property_template
class_bindings.append(_class_property.substitute(js_name=property.name, cpp_name='::'.join(
[class_info.cname, property.name])))
# Generate bindings for properties(prop)
for prop in class_info.props:
if prop.tp in type_dict and not self._is_string_type(prop.tp):
_class_property = class_property_enum_template
else:
_class_property = class_property_template
class_bindings.append(_class_property.substitute(
js_name=prop.name,
cpp_name='::'.join([class_info.cname, prop.name])
))
dv = ''
base = Template("""base<$base>""")
+4
View File
@@ -107,6 +107,10 @@ typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
typedef TrackerMIL::Params TrackerMIL_Params;
#endif
#ifdef HAVE_OPENCV_XIMGPROC
typedef ximgproc::EdgeDrawing::Params EdgeDrawing_Params;
#endif
// HACK: JS generator ommits namespace for parameter types for some reason. Added typedef to handle std::string correctly
typedef std::string string;
@@ -32,8 +32,10 @@ struct CharucoDetector::CharucoDetectorImpl {
const Mat chIds = charucoIds.getMat();
const vector<int>& boardIds = board.getIds();
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx();
vector<Point2f> distance(board.getNearestMarkerIdx().size(), Point2f(0.f, std::numeric_limits<float>::max()));
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
const vector<vector<int> > nearestMarkerCorners = board.getNearestMarkerCorners();
vector<Point2f> distance(nearestMarkerIdx.size(), Point2f(0.f, std::numeric_limits<float>::max()));
// distance[i].x: max distance from the i-th charuco corner to charuco corner-forming markers.
// The two charuco corner-forming markers of i-th charuco corner are defined in getNearestMarkerIdx()[i]
// distance[i].y: min distance from the charuco corner to other markers.
@@ -52,7 +54,7 @@ struct CharucoDetector::CharucoDetectorImpl {
const int nearestMarkerId1 = boardIds[nearestMarkerIdx[chId][0]];
const int nearestMarkerId2 = boardIds[nearestMarkerIdx[chId][1]];
if (nearestMarkerId1 == idMaker || nearestMarkerId2 == idMaker) {
int nearestCornerId = nearestMarkerId1 == idMaker ? board.getNearestMarkerCorners()[chId][0] : board.getNearestMarkerCorners()[chId][1];
int nearestCornerId = nearestMarkerId1 == idMaker ? nearestMarkerCorners[chId][0] : nearestMarkerCorners[chId][1];
Point2f nearestCorner = mCorners[j].ptr<Point2f>(0)[nearestCornerId];
// distToNearest: distance from the charuco corner to charuco corner-forming markers
float distToNearest = sqrt(normL2Sqr<float>(nearestCorner - charucoCorner));
@@ -84,18 +86,21 @@ struct CharucoDetector::CharucoDetectorImpl {
InputArray charucoCorners) {
size_t nCharucoCorners = charucoCorners.getMat().total();
CV_Assert(board.getNearestMarkerIdx().size() == nCharucoCorners);
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
const vector<vector<int> > nearestMarkerCorners = board.getNearestMarkerCorners();
CV_Assert(nearestMarkerIdx.size() == nCharucoCorners);
vector<Size> winSizes(nCharucoCorners, Size(-1, -1));
for(size_t i = 0ull; i < nCharucoCorners; i++) {
if(charucoCorners.getMat().at<Point2f>((int)i) == Point2f(-1.f, -1.f)) continue;
if(board.getNearestMarkerIdx()[i].empty()) continue;
if(nearestMarkerIdx[i].empty()) continue;
double minDist = -1;
int counter = 0;
// calculate the distance to each of the closest corner of each closest marker
for(size_t j = 0; j < board.getNearestMarkerIdx()[i].size(); j++) {
for(size_t j = 0; j < nearestMarkerIdx[i].size(); j++) {
// find marker
int markerId = board.getIds()[board.getNearestMarkerIdx()[i][j]];
int markerId = board.getIds()[nearestMarkerIdx[i][j]];
int markerIdx = -1;
for(size_t k = 0; k < markerIds.getMat().total(); k++) {
if(markerIds.getMat().at<int>((int)k) == markerId) {
@@ -105,7 +110,7 @@ struct CharucoDetector::CharucoDetectorImpl {
}
if(markerIdx == -1) continue;
Point2f markerCorner =
markerCorners.getMat(markerIdx).at<Point2f>(board.getNearestMarkerCorners()[i][j]);
markerCorners.getMat(markerIdx).at<Point2f>(nearestMarkerCorners[i][j]);
Point2f charucoCorner = charucoCorners.getMat().at<Point2f>((int)i);
double dist = norm(markerCorner - charucoCorner);
if(minDist == -1) minDist = dist; // if first distance, just assign it
@@ -212,6 +217,8 @@ struct CharucoDetector::CharucoDetectorImpl {
vector<Mat> transformations(nMarkers);
vector<bool> validTransform(nMarkers, false);
const auto& ids = board.getIds();
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
for(size_t i = 0ull; i < nMarkers; i++) {
vector<Point2f> markerObjPoints2D;
int markerId = markerIds.getMat().at<int>((int)i);
@@ -227,15 +234,16 @@ struct CharucoDetector::CharucoDetectorImpl {
double det = determinant(transformations[i]);
validTransform[i] = std::abs(det) > 1e-6;
}
size_t nCharucoCorners = (size_t)board.getChessboardCorners().size();
const vector<Point3f> chessboardCorners = board.getChessboardCorners();
size_t nCharucoCorners = (size_t)chessboardCorners.size();
vector<Point2f> allChessboardImgPoints(nCharucoCorners, Point2f(-1, -1));
// for each charuco corner, calculate its interpolation position based on the closest markers
// homographies
for(size_t i = 0ull; i < nCharucoCorners; i++) {
Point2f objPoint2D = Point2f(board.getChessboardCorners()[i].x, board.getChessboardCorners()[i].y);
Point2f objPoint2D = Point2f(chessboardCorners[i].x, chessboardCorners[i].y);
vector<Point2f> interpolatedPositions;
for(size_t j = 0ull; j < board.getNearestMarkerIdx()[i].size(); j++) {
int markerId = board.getIds()[board.getNearestMarkerIdx()[i][j]];
for(size_t j = 0ull; j < nearestMarkerIdx[i].size(); j++) {
int markerId = board.getIds()[nearestMarkerIdx[i][j]];
int markerIdx = -1;
for(size_t k = 0ull; k < markerIds.getMat().total(); k++) {
if(markerIds.getMat().at<int>((int)k) == markerId) {
@@ -274,13 +282,14 @@ struct CharucoDetector::CharucoDetectorImpl {
CV_Assert(charucoParameters.minMarkers >= 0 && charucoParameters.minMarkers <= 2);
vector<Point2f> filteredCharucoCorners;
vector<int> filteredCharucoIds;
const vector<vector<int> > nearestMarkerIdx = board.getNearestMarkerIdx(); // only copy the vectors once
// for each charuco corner
for(unsigned int i = 0; i < allCharucoIds.getMat().total(); i++) {
int currentCharucoId = allCharucoIds.getMat().at<int>(i);
int totalMarkers = 0; // nomber of closest marker detected
// look for closest markers
for(unsigned int m = 0; m < board.getNearestMarkerIdx()[currentCharucoId].size(); m++) {
int markerId = board.getIds()[board.getNearestMarkerIdx()[currentCharucoId][m]];
for(unsigned int m = 0; m < nearestMarkerIdx[currentCharucoId].size(); m++) {
int markerId = board.getIds()[nearestMarkerIdx[currentCharucoId][m]];
bool found = false;
for(unsigned int k = 0; k < allArucoIds.getMat().total(); k++) {
if(allArucoIds.getMat().at<int>(k) == markerId) {
+6 -4
View File
@@ -3417,8 +3417,10 @@ int QRDetectMulti::findNumberLocalizationPoints(vector<Point2f>& tmp_localizatio
Mat tmp_shrinking = bin_barcode;
int tmp_num_points = 0;
int num_points = -1;
for (eps_horizontal = 0.1; eps_horizontal < 0.4; eps_horizontal += 0.1)
double eps = 0.0;
for (int epsCoeff = 1; epsCoeff <= 3; epsCoeff++)
{
eps = eps_horizontal * static_cast<double>(epsCoeff);
tmp_num_points = 0;
num_points = -1;
if (purpose == SHRINKING)
@@ -3443,7 +3445,7 @@ int QRDetectMulti::findNumberLocalizationPoints(vector<Point2f>& tmp_localizatio
else
break;
}
vector<Point2f> list_lines_y = extractVerticalLines(list_lines_x, eps_horizontal);
vector<Point2f> list_lines_y = extractVerticalLines(list_lines_x, eps);
if (list_lines_y.size() < 3)
{
if (k == 0)
@@ -3453,7 +3455,7 @@ int QRDetectMulti::findNumberLocalizationPoints(vector<Point2f>& tmp_localizatio
list_lines_x = searchHorizontalLines();
if (list_lines_x.empty())
break;
list_lines_y = extractVerticalLines(list_lines_x, eps_horizontal);
list_lines_y = extractVerticalLines(list_lines_x, eps);
if (list_lines_y.size() < 3)
break;
}
@@ -3531,7 +3533,7 @@ int QRDetectMulti::findNumberLocalizationPoints(vector<Point2f>& tmp_localizatio
vector<Vec3d> list_lines_x = searchHorizontalLines();
if (list_lines_x.empty())
return num_points;
vector<Point2f> list_lines_y = extractVerticalLines(list_lines_x, eps_horizontal);
vector<Point2f> list_lines_y = extractVerticalLines(list_lines_x, eps);
if (list_lines_y.size() < 3)
return num_points;
if (num_points < 3)
+36
View File
@@ -679,4 +679,40 @@ TEST(Objdetect_QRCode_detect, detect_regression_22892)
EXPECT_EQ(corners.size(), 4U);
}
// See https://github.com/opencv/opencv/issues/27783
TEST(Objdetect_QRCode_detect, detect_regression_27783)
{
const std::string name_current_image = "9_qrcodes.jpg";
const std::string root = "qrcode/multiple/";
std::string image_path = findDataFile(root + name_current_image);
Mat src = imread(image_path);
ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path;
std::vector<std::string> info;
std::vector<Point> corners;
{
// If default, we can decode 9 QRs.
QRCodeDetector qrcode;
EXPECT_TRUE(qrcode.detectAndDecodeMulti(src, info, corners));
ASSERT_EQ(info.size(), 9UL);
ASSERT_EQ(corners.size(), 36UL);
}
{
// If setEpsX is too small, we can decode no QRs.
QRCodeDetector qrcode;
qrcode.setEpsX(0.01);
EXPECT_FALSE(qrcode.detectAndDecodeMulti(src, info, corners));
}
{
// If setEpsY is too small, we can decode no QRs.
QRCodeDetector qrcode;
qrcode.setEpsY(0.01);
EXPECT_FALSE(qrcode.detectAndDecodeMulti(src, info, corners));
}
}
}} // namespace
+1 -1
View File
@@ -51,7 +51,7 @@ ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/fast_math.hpp"
ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda/")
ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/")
ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl/")
ocv_list_filterout(opencv_hdrs "modules/.+/utils/.*")
ocv_list_filterout(opencv_hdrs "modules/.+/utils/trace.hpp")
ocv_list_filterout(opencv_hdrs "modules/.*\\\\.inl\\\\.h*")
ocv_list_filterout(opencv_hdrs "modules/.*_inl\\\\.h*")
ocv_list_filterout(opencv_hdrs "modules/.*\\\\.details\\\\.h*")
@@ -12,6 +12,7 @@ from .nodes import (
SequenceTypeNode,
AnyTypeNode,
AggregatedTypeNode,
PathLikeTypeNode,
)
from .types_conversion import (
@@ -28,6 +28,8 @@ def apply_manual_api_refinement(root: NamespaceNode) -> None:
version_constant = root.add_constant("__version__", "<unused>")
version_constant._value_type = "str"
convert_returned_scalar_to_tuple(root)
"""
def redirectError(
onError: Callable[[int, str, str, str, int], None] | None
@@ -126,6 +128,30 @@ def make_optional_arg(*arg_names: str) -> Callable[[NamespaceNode, SymbolName],
return _make_optional_arg
def convert_returned_scalar_to_tuple(root: NamespaceNode) -> None:
"""Force `tuple[float, float, float, float]` usage instead of Scalar alias
for return types due to `pyopencv_from` specialization for Scalar type.
"""
float_4_tuple_node = TupleTypeNode(
"ScalarOutput",
items=(PrimitiveTypeNode.float_(),) * 4
)
def fix_scalar_return_type(fn: FunctionNode.Overload):
if fn.return_type is None:
return
if fn.return_type.type_node.typename == "Scalar":
fn.return_type.type_node = float_4_tuple_node
for overload in for_each_function_overload(root):
fix_scalar_return_type(overload)
for ns in root.namespaces.values():
for overload in for_each_function_overload(ns):
fix_scalar_return_type(overload)
def refine_cuda_module(root: NamespaceNode) -> None:
def fix_cudaoptflow_enums_names() -> None:
for class_name in ("NvidiaOpticalFlow_1_0", "NvidiaOpticalFlow_2_0"):
@@ -4,7 +4,7 @@ import keyword
from .nodes import (ASTNode, NamespaceNode, ClassNode, FunctionNode,
EnumerationNode, ClassProperty, OptionalTypeNode,
TupleTypeNode)
TupleTypeNode, PathLikeTypeNode)
from .types_conversion import create_type_node
@@ -167,12 +167,16 @@ def create_function_node_in_scope(scope: Union[NamespaceNode, ClassNode],
func_info) -> FunctionNode:
def prepare_overload_arguments_and_return_type(variant):
arguments = [] # type: list[FunctionNode.Arg]
# Enumerate is requried, because `argno` in `variant.py_arglist`
# Enumerate is required, because `argno` in `variant.py_arglist`
# refers to position of argument in C++ function interface,
# but `variant.py_noptargs` refers to position in `py_arglist`
for i, (_, argno) in enumerate(variant.py_arglist):
arg_info = variant.args[argno]
type_node = create_type_node(arg_info.tp)
# Special handling for string representation of the file system path
if arg_info.pathlike and type_node.typename == "str":
type_node = PathLikeTypeNode.string_or_pathlike_()
default_value = None
if len(arg_info.defval):
default_value = arg_info.defval
@@ -8,5 +8,5 @@ from .type_node import (
TypeNode, OptionalTypeNode, UnionTypeNode, NoneTypeNode, TupleTypeNode,
ASTNodeTypeNode, AliasTypeNode, SequenceTypeNode, AnyTypeNode,
AggregatedTypeNode, NDArrayTypeNode, AliasRefTypeNode, PrimitiveTypeNode,
CallableTypeNode, DictTypeNode, ClassTypeNode
CallableTypeNode, DictTypeNode, ClassTypeNode, PathLikeTypeNode
)
@@ -43,7 +43,7 @@ class TypeNode(abc.ABC):
Returns:
str: short name of the type node.
"""
pass
return ""
@property
def full_typename(self) -> str:
@@ -123,12 +123,11 @@ class TypeNode(abc.ABC):
def is_resolved(self) -> bool:
return True
def relative_typename(self, module_full_export_name: str) -> str:
def relative_typename(self, module: str) -> str:
"""Type name relative to the provided module.
Args:
module_full_export_name (str): Full export name of the module to
get relative name to.
module (str): Full export name of the module to get relative name to.
Returns:
str: If module name of the type node doesn't match `module`, then
@@ -715,11 +714,11 @@ class ContainerTypeNode(AggregatedTypeNode):
@abc.abstractproperty
def type_format(self) -> str:
pass
return ""
@abc.abstractproperty
def types_separator(self) -> str:
pass
return ""
class SequenceTypeNode(ContainerTypeNode):
@@ -895,6 +894,31 @@ class ClassTypeNode(ContainerTypeNode):
return ", "
class PathLikeTypeNode(TypeNode):
"""Type node representing a PathLike object.
"""
def __init__(self, ctype_name: str) -> None:
super().__init__(ctype_name)
@property
def typename(self) -> str:
return "os.PathLike[str]"
@property
def required_usage_imports(self) -> Generator[str, None, None]:
yield "import os"
@staticmethod
def string_or_pathlike_(ctype_name: str = "string") -> UnionTypeNode:
return UnionTypeNode(
ctype_name,
items=(
PrimitiveTypeNode.str_(ctype_name),
PathLikeTypeNode(ctype_name)
)
)
def _resolve_symbol(root: Optional[ASTNode], full_symbol_name: str) -> Optional[ASTNode]:
"""Searches for a symbol with the given full export name in the AST
starting from the `root`.
+6
View File
@@ -172,6 +172,10 @@ class Builder:
if flags:
cmd += ["-DCMAKE_C_FLAGS='%s'" % flags,
"-DCMAKE_CXX_FLAGS='%s'" % flags]
if self.options.extra_modules:
cmd.append("-DOPENCV_EXTRA_MODULES_PATH='%s'" % self.options.extra_modules)
return cmd
def get_build_flags(self):
@@ -257,6 +261,8 @@ if __name__ == "__main__":
# Write a path to modify file like argument of this flag
parser.add_argument('--config', help="Specify configuration file with own list of exported into JS functions")
parser.add_argument('--webnn', action="store_true", help="Enable WebNN Backend")
parser.add_argument("--extra_modules", required=False, help="Path extra modules location (OPENCV_EXTRA_MODULES_PATH)")
transformed_args = ["--cmake_option={}".format(arg) if arg[:2] == "-D" else arg for arg in sys.argv[1:]]
args = parser.parse_args(transformed_args)
+7 -7
View File
@@ -1015,19 +1015,19 @@ if __name__ == '__main__':
print("params.board_dict_path:", params.board_dict_path)
if params.log_level == "verbose":
cv.setLogLevel(6)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_VERBOSE)
elif params.log_level == "debug":
cv.setLogLevel(5)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_DEBUG)
elif params.log_level == "info":
cv.setLogLevel(4)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_INFO)
elif params.log_level == "warning":
cv.setLogLevel(3)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_WARNING)
elif params.log_level == "error":
cv.setLogLevel(2)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_ERROR)
elif params.log_level == "fatal":
cv.setLogLevel(1)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_FATAL)
elif params.log_level == "silent":
cv.setLogLevel(0)
cv.utils.logging.setLogLevel(cv.utils.logging.LOG_LEVEL_SILENT)
if params.visualize:
assert os.path.exists(params.path_to_visualize), f'Path to result file does not exist: {params.path_to_visualize}'