2009.11.29 17:02 "[Tiff] Reentrancy patches", by Adam Goode

2009.11.29 17:02 "[Tiff] [PATCH 3/3] Eliminate static buffer for default YCbCrCoefficients", by Adam Goode

When custom fields were introduced in 2005, many internal fields
were converted to use custom fields, and TIFFGetFieldDefaulted got
a bit more complicated each time (with TIFFDefaultDirectory

getting

simpler). Unfortunately for TIFFTAG_YCBCRCOEFFICIENTS, the default result

is returned in a static buffer. If a program altered the data stored

in this buffer, it would change the defaults for all other users of

the entire library (in the current address space). The buffer cannot

be const because of the ABI.

This fix returns YCbCrCoefficients to a non-custom field, which may not be

perfect, but it does remove the static buffer.
---

 libtiff/tif_aux.c     |    8 ++------
 libtiff/tif_dir.c     |   16 ++++++++++++++++
 libtiff/tif_dir.h     |    2 ++
 libtiff/tif_dirinfo.c |    2 +-
 4 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c

index e8d89f4..61cab87 100644

--- a/libtiff/tif_aux.c
+++ b/libtiff/tif_aux.c

@@ -216,12 +216,8 @@ TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)

                *va_arg(ap, uint32 *) = td->td_imagedepth;

               return (1);

case TIFFTAG_YCBCRCOEFFICIENTS:

  • return 1;
  • }

+               *va_arg(ap, float **) = td->td_ycbcrcoeffs;
+               return (1);
        case TIFFTAG_YCBCRSUBSAMPLING:
                *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
                *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];

diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c

index 56863df..0a50f8d 100644

--- a/libtiff/tif_dir.c
+++ b/libtiff/tif_dir.c

@@ -365,6 +365,9 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
                        status = 0;
                }
                break;
+ case TIFFTAG_YCBCRCOEFFICIENTS:

+               _TIFFsetFloatArray(&td->td_ycbcrcoeffs, va_arg(ap, float*), 3);
+               break;

        case TIFFTAG_YCBCRPOSITIONING:
                td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
                break;
@@ -880,6 +883,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)

                        *va_arg(ap, uint16*) = td->td_nsubifd;
                        *va_arg(ap, uint64**) = td->td_subifd;
                        break;
+               case TIFFTAG_YCBCRCOEFFICIENTS:
+                       *va_arg(ap, float**) = td->td_ycbcrcoeffs;
+                       break;
                case TIFFTAG_YCBCRPOSITIONING:
                        *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
                        break;

@@ -1087,6 +1093,7 @@ TIFFFreeDirectory(TIFF* tif)
        CleanupField(td_colormap[2]);
        CleanupField(td_sampleinfo);

        CleanupField(td_subifd);

+ CleanupField(td_ycbcrcoeffs);

        CleanupField(td_inknames);

CleanupField(td_whitepoint);

CleanupField(td_refblackwhite);

@@ -1168,6 +1175,15 @@ TIFFDefaultDirectory(TIFF* tif)
        td->td_resolutionunit = RESUNIT_INCH;
        td->td_sampleformat = SAMPLEFORMAT_UINT;
        td->td_imagedepth = 1;
+

+       /* YCbCrCoefficients defaults are from CCIR Recommendation 601-1 */
+       td->td_ycbcrcoeffs = (float *) _TIFFmalloc(3 * sizeof (float));
+       if (!td->td_ycbcrcoeffs)
+               return (0);
+       td->td_ycbcrcoeffs[0] = 0.299f;
+       td->td_ycbcrcoeffs[1] = 0.587f;
+       td->td_ycbcrcoeffs[2] = 0.114f;
+
        td->td_ycbcrsubsampling[0] = 2;
        td->td_ycbcrsubsampling[1] = 2;
        td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;

diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h

index 70b68f2..1b7d035 100644

--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h

@@ -78,6 +78,7 @@ typedef struct {

        uint16  td_nsubifd;
        uint64* td_subifd;
        /* YCbCr parameters */
+       float*  td_ycbcrcoeffs;
        uint16  td_ycbcrsubsampling[2];

        uint16  td_ycbcrpositioning;
        /* Colorimetry parameters */

@@ -136,6 +137,7 @@ typedef struct {
 #define FIELD_IMAGEDEPTH 35
 #define FIELD_TILEDEPTH 36

 #define FIELD_HALFTONEHINTS            37

+#define FIELD_YCBCRCOEFFICIENTS 38

 #define FIELD_YCBCRSUBSAMPLING         39
 #define FIELD_YCBCRPOSITIONING         40

index 4a927aa..ac4f47c 100644

--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c

@@ -109,7 +109,7 @@ tiffFields[] = {
        { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
        { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
        { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL },

+ { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_YCBCRCOEFFICIENTS, 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 },

--
1.6.5.2