- update to 1.6.19:

Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
  Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
  Fixed the recently reported 1's complement security issue.
  Fixed png_save_int_32 when int is not 2's complement by replacing
    the value that is illegal in the PNG spec, in both signed and 
    unsigned values, with 0.
 etc., see ANNOUNCE and CHANGES for details
- removed: libpng-rgb_to_gray-checks.patch (upstreamed)

OBS-URL: https://build.opensuse.org/package/show/graphics/libpng16?expand=0&rev=73
This commit is contained in:
Petr Gajdos 2015-11-13 07:46:48 +00:00 committed by Git OBS Bridge
parent 2d78fea3f9
commit 35368c612d
7 changed files with 34 additions and 878 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:98507b55fbe5cd43c51981f2924e4671fd81fe35d52dc53357e20f2c77fa5dfd
size 919828

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJVFAdkAAoJEPVJhL+hbGQPhsUP/3rfXn1/5nEdAST5Ag2VDb+o
2U4ReFycUDoTzUBj0mVzvd83fG/lu2xuOySsePjEyp7UMGk/wKoD3QLIo2EcvzDZ
F0o3RHyfwCh7ftJJEvcl27xLkPCkjo4014XZadwSLDDrGWsEf1/XqQV27wxj7uoZ
VQ5Yyt0mK5SvA5SRI8DaZyY7v/PGdHcqe/BPklbONdQNHQ37YemdHlozranD80tY
LxITDytRTt4jeOIMA2FZT2i6sSgMXBa2sFhkcGUNzABEPU1aHsntebQKUq5/THK2
qD1i8CG0Ui4piB/zfNUU8Lb2fP4iaLNNX1bXmOlZYIGyd50a3vTILdYI8ZJFruBn
S2LveJwvmsepuslFZC0kFuJwe4DvyfJlHb5N2Eij9NxZGDvVs/Pkqs3IbXvtSzDq
fNmzi5Rzih+zIyzCfdhP4SfpgY3URAabtmVgC+5N6h4tuUvYXQ4X8Ayvrl38aO9h
yBdCejYQpLFgG5fOMSnZ5G/t3btwWy/vmeKpLDjET0kOXxe8xP/+iqJU9OTd8KIL
uHHl4SRBZWiRW9ZdxxZamURY1VR5pZpHhdmScUPD8pLnKpdrKQ96P9jZI+9qGp4b
aynXlTiSkhsEOt6HiJdC4GELefhNlce82G/9oUxnOjx1cz+hP+BUXkRX6HfK490U
eHtCd19UOHNIyta7pxBU
=+ptB
-----END PGP SIGNATURE-----

3
libpng-1.6.19.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:311c5657f53516986c67713c946f616483e3cdb52b8b2ee26711be74e8ac35e8
size 941280

17
libpng-1.6.19.tar.xz.asc Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQIcBAABAgAGBQJWRJdjAAoJEPVJhL+hbGQPfQgQAKr/BrU1ZGbvJjyQ6dxGDKjN
bshmoTp+u+B24qUmjM0mYFGiv2WeHIvSvaao0YEfL/u7S9+NINT1sL1+0K5PT+ZF
DgEy4R3OqvEUlnix3nTJ7UgIf9iPBniq747Xv+N3NMc2dzUMATbqyma1MNiGQpvE
pDuYQhIGauydimXlhqzYMm7/sE54j7uf1ecYxIsKHHLyIKy7Pwog+c5Rjb5BTjVS
tGx+TCSGsWbMy+hw74/h8ESkjjd6Bk4+S+aEzCoUoAdUCu3ziOSqVAdWN3z++w8S
1vM9lhguYvatz2hgLeHgngc3NvAeJLV5sOCUUqsxA+pilIlV6Tcmr/tmNsAWnWe5
nO5iJ4YnU+7CZYrX5V47AijaLtRDzXh07sdwefpooyEB+OUYKprNVi+jH9PFAFId
GLIiize/PevkeOheMMkafOyESEzD9zS9lPFgCIfRl+qZSKGLjA8Cq0QA56I1E60F
i6w2j9U3VAHUi+PcrBO3BTsUkVc8H2OWsClCwMlyYxkb4exgDAxV3XbnUdTXuF9A
ABQn1H/dLFmJcyLKRY+pQ7+XCWz/nnDQhIIFlwnlZH/lMzR4e6gtnjOBXDOZUS3W
vlTjx2OcxVEXFiafhKvHFk0fsnJscXinB88HpSrb/83aEOc++eMq6wmwySK1zf0T
TuCarcJ0DZkGmLBg2bRC
=XCSM
-----END PGP SIGNATURE-----

View File

@ -1,855 +0,0 @@
http://sourceforge.net/p/libpng/code/ci/a21a5b22c10b900d44d40fe30a203302b2a67f8b/
--- contrib/libtests/pngvalid.c
+++ contrib/libtests/pngvalid.c
@@ -258,7 +258,7 @@
make_random_bytes(seed, bytes, 4);
}
-#ifdef PNG_READ_SUPPORTED
+#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED
static void
randomize(void *pv, size_t size)
{
@@ -267,7 +267,9 @@
}
#define RANDOMIZE(this) randomize(&(this), sizeof (this))
-
+#endif /* READ || WRITE_tRNS */
+
+#ifdef PNG_READ_SUPPORTED
static unsigned int
random_mod(unsigned int max)
{
@@ -295,7 +297,8 @@
/* A numeric ID based on PNG file characteristics. The 'do_interlace' field
* simply records whether pngvalid did the interlace itself or whether it
* was done by libpng. Width and height must be less than 256. 'palette' is an
- * index of the palette to use for formats with a palette (0 otherwise.)
+ * index of the palette to use for formats with a palette otherwise a boolean
+ * indicating if a tRNS chunk was generated.
*/
#define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
@@ -316,12 +319,16 @@
png_uint_32 w, png_uint_32 h, int do_interlace)
{
pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
- if (npalette > 0)
+ if (colour_type == 3) /* must have a palette */
{
pos = safecat(buffer, bufsize, pos, "[");
pos = safecatn(buffer, bufsize, pos, npalette);
pos = safecat(buffer, bufsize, pos, "]");
}
+
+ else if (npalette != 0)
+ pos = safecat(buffer, bufsize, pos, "+tRNS");
+
pos = safecat(buffer, bufsize, pos, " ");
pos = safecatn(buffer, bufsize, pos, bit_depth);
pos = safecat(buffer, bufsize, pos, " bit");
@@ -378,25 +385,32 @@
static int
next_format(png_bytep colour_type, png_bytep bit_depth,
- unsigned int* palette_number, int no_low_depth_gray)
+ unsigned int* palette_number, int low_depth_gray, int tRNS)
{
if (*bit_depth == 0)
{
*colour_type = 0;
- if (no_low_depth_gray)
+ if (low_depth_gray)
+ *bit_depth = 1;
+ else
*bit_depth = 8;
- else
- *bit_depth = 1;
*palette_number = 0;
return 1;
}
- if (*colour_type == 3)
- {
- /* Add multiple palettes for colour type 3. */
- if (++*palette_number < PALETTE_COUNT(*bit_depth))
+ if (*colour_type < 4/*no alpha channel*/)
+ {
+ /* Add multiple palettes for colour type 3, one image with tRNS
+ * and one without for other non-alpha formats:
+ */
+ unsigned int pn = ++*palette_number;
+ png_byte ct = *colour_type;
+
+ if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) ||
+ (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth)))
return 1;
+ /* No: next bit depth */
*palette_number = 0;
}
@@ -1959,6 +1973,7 @@
/* Run tests on reading with a combination of transforms, */
unsigned int test_transform :1;
+ unsigned int test_tRNS :1; /* Includes tRNS images */
/* When to use the use_input_precision option, this controls the gamma
* validation code checks. If set any value that is within the transformed
@@ -1989,6 +2004,16 @@
unsigned int test_gamma_alpha_mode :1;
unsigned int test_gamma_expand16 :1;
unsigned int test_exhaustive :1;
+
+ /* Whether or not to run the low-bit-depth grayscale tests. This fail on
+ * gamma images in some cases because of gross inaccuracies in the grayscale
+ * gamma handling for low bit depth.
+ */
+ unsigned int test_lbg :1;
+ unsigned int test_lbg_gamma_threshold :1;
+ unsigned int test_lbg_gamma_transform :1;
+ unsigned int test_lbg_gamma_sbit :1;
+ unsigned int test_lbg_gamma_composition :1;
unsigned int log :1; /* Log max error */
@@ -2042,6 +2067,11 @@
pm->test_standard = 0;
pm->test_size = 0;
pm->test_transform = 0;
+# ifdef PNG_WRITE_tRNS_SUPPORTED
+ pm->test_tRNS = 1;
+# else
+ pm->test_tRNS = 0;
+# endif
pm->use_input_precision = 0;
pm->use_input_precision_sbit = 0;
pm->use_input_precision_16to8 = 0;
@@ -2054,6 +2084,11 @@
pm->test_gamma_background = 0;
pm->test_gamma_alpha_mode = 0;
pm->test_gamma_expand16 = 0;
+ pm->test_lbg = 1;
+ pm->test_lbg_gamma_threshold = 1;
+ pm->test_lbg_gamma_transform = 1;
+ pm->test_lbg_gamma_sbit = 1;
+ pm->test_lbg_gamma_composition = 1;
pm->test_exhaustive = 0;
pm->log = 0;
@@ -3192,6 +3227,45 @@
}
}
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+static void
+set_random_tRNS(png_structp pp, png_infop pi, PNG_CONST png_byte colour_type,
+ PNG_CONST int bit_depth)
+{
+ /* To make this useful the tRNS color needs to match at least one pixel.
+ * Random values are fine for gray, including the 16-bit case where we know
+ * that the test image contains all the gray values. For RGB we need more
+ * method as only 65536 different RGB values are generated.
+ */
+ png_color_16 tRNS;
+ const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
+
+ RANDOMIZE(tRNS);
+
+ if (colour_type & 2/*RGB*/)
+ {
+ if (bit_depth == 8)
+ {
+ tRNS.blue = tRNS.red ^ tRNS.green;
+ tRNS.red &= mask;
+ tRNS.green &= mask;
+ tRNS.blue &= mask;
+ }
+
+ else /* bit_depth == 16 */
+ {
+ tRNS.green = (png_uint_16)(tRNS.red * 257);
+ tRNS.blue = (png_uint_16)(tRNS.green * 17);
+ }
+ }
+
+ else
+ tRNS.gray &= mask;
+
+ png_set_tRNS(pp, pi, NULL, 0, &tRNS);
+}
+#endif
+
/* The number of passes is related to the interlace type. There was no libpng
* API to determine this prior to 1.5, so we need an inquiry function:
*/
@@ -3525,6 +3599,11 @@
if (colour_type == 3) /* palette */
init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);
+# ifdef PNG_WRITE_tRNS_SUPPORTED
+ else if (palette_number)
+ set_random_tRNS(pp, pi, colour_type, bit_depth);
+# endif
+
png_write_info(pp, pi);
if (png_get_rowbytes(pp, pi) !=
@@ -3598,19 +3677,20 @@
}
static void
-make_transform_images(png_store *ps)
+make_transform_images(png_modifier *pm)
{
png_byte colour_type = 0;
png_byte bit_depth = 0;
unsigned int palette_number = 0;
/* This is in case of errors. */
- safecat(ps->test, sizeof ps->test, 0, "make standard images");
+ safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images");
/* Use next_format to enumerate all the combinations we test, including
- * generating multiple low bit depth palette images.
- */
- while (next_format(&colour_type, &bit_depth, &palette_number, 0))
+ * generating multiple low bit depth palette images. Non-A images (palette
+ * and direct) are created with and without tRNS chunks.
+ */
+ while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1))
{
int interlace_type;
@@ -3621,7 +3701,7 @@
standard_name(name, sizeof name, 0, colour_type, bit_depth,
palette_number, interlace_type, 0, 0, 0);
- make_transform_image(ps, colour_type, bit_depth, palette_number,
+ make_transform_image(&pm->this, colour_type, bit_depth, palette_number,
interlace_type, name);
}
}
@@ -4287,6 +4367,7 @@
size_t cbRow; /* Bytes in a row of the output image */
int do_interlace; /* Do interlacing internally */
int is_transparent; /* Transparency information was present. */
+ int has_tRNS; /* color type GRAY or RGB with a tRNS chunk. */
int speed; /* Doing a speed test */
int use_update_info;/* Call update_info, not start_image */
struct
@@ -4619,14 +4700,14 @@
case 0:
dp->transparent.red = dp->transparent.green = dp->transparent.blue =
trans_color->gray;
- dp->is_transparent = 1;
+ dp->has_tRNS = 1;
break;
case 2:
dp->transparent.red = trans_color->red;
dp->transparent.green = trans_color->green;
dp->transparent.blue = trans_color->blue;
- dp->is_transparent = 1;
+ dp->has_tRNS = 1;
break;
case 3:
@@ -5518,7 +5599,7 @@
if (this->colour_type == PNG_COLOR_TYPE_GRAY)
{
if (this->bit_depth < 8)
- this->bit_depth = 8;
+ this->bit_depth = this->sample_depth = 8;
if (this->have_tRNS)
{
@@ -5553,9 +5634,11 @@
this->alphaf = 0;
else
this->alphaf = 1;
-
- this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
}
+ else
+ this->alphaf = 1;
+
+ this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
}
/* The error in the alpha is zero and the sBIT value comes from the
@@ -5848,8 +5931,9 @@
/* If png_set_filler is in action then fake the output color type to include
* an alpha channel where appropriate.
*/
- if (dp->output_bit_depth >= 8 && (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
- dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
+ if (dp->output_bit_depth >= 8 &&
+ (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
+ dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
dp->output_colour_type |= 4;
/* Validate the combination of colour type and bit depth that we are getting
@@ -6372,6 +6456,13 @@
transform_display *that, png_structp pp, png_infop pi)
{
png_set_tRNS_to_alpha(pp);
+
+ /* If there was a tRNS chunk that would get expanded and add an alpha
+ * channel is_transparent must be updated:
+ */
+ if (that->this.has_tRNS)
+ that->this.is_transparent = 1;
+
this->next->set(this->next, that, pp, pi);
}
@@ -6430,6 +6521,7 @@
transform_display *that, png_structp pp, png_infop pi)
{
png_set_gray_to_rgb(pp);
+ /* NOTE: this doesn't result in tRNS expansion. */
this->next->set(this->next, that, pp, pi);
}
@@ -6489,6 +6581,10 @@
transform_display *that, png_structp pp, png_infop pi)
{
png_set_expand(pp);
+
+ if (that->this.has_tRNS)
+ that->this.is_transparent = 1;
+
this->next->set(this->next, that, pp, pi);
}
@@ -6539,6 +6635,7 @@
png_infop pi)
{
png_set_expand_gray_1_2_4_to_8(pp);
+ /* NOTE: don't expect this to expand tRNS */
this->next->set(this->next, that, pp, pi);
}
@@ -6570,6 +6667,11 @@
transform_display *that, png_structp pp, png_infop pi)
{
png_set_expand_16(pp);
+
+ /* NOTE: at present libpng does SET_EXPAND as well, so tRNS is expanded. */
+ if (that->this.has_tRNS)
+ that->this.is_transparent = 1;
+
this->next->set(this->next, that, pp, pi);
}
@@ -6940,14 +7042,14 @@
* When DIGITIZE is set because a pre-1.7 version of libpng is being
* tested allow a bigger slack.
*
- * NOTE: this magic number was determined by experiment to be 1.25.
- * There's no great merit to the value below, however it only affects
- * the limit used for checking for internal calculation errors, not
- * the actual limit imposed by pngvalid on the output errors.
+ * NOTE: this magic number was determined by experiment to be about
+ * 1.263. There's no great merit to the value below, however it only
+ * affects the limit used for checking for internal calculation errors,
+ * not the actual limit imposed by pngvalid on the output errors.
*/
that->pm->limit += pow(
# if DIGITIZE
- 1.25
+ 1.3
# else
1.0
# endif
@@ -7111,7 +7213,8 @@
const unsigned int sample_depth = that->sample_depth;
const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
sample_depth);
- const unsigned int gamma_depth = (sample_depth == 16 ? 16 :
+ const unsigned int gamma_depth = (sample_depth == 16 ?
+ PNG_MAX_GAMMA_8 :
(pm->assume_16_bit_calculations ? PNG_MAX_GAMMA_8 : sample_depth));
int isgray;
double r, g, b;
@@ -7125,56 +7228,73 @@
* will be identical after this operation if there is only one
* transform, feel free to delete the png_error checks on this below in
* the future (this is just me trying to ensure it works!)
+ *
+ * Interval arithmetic is exact, but to implement it it must be
+ * possible to control the floating point implementation rounding mode.
+ * This cannot be done in ANSI-C, so instead I reduce the 'lo' values
+ * by DBL_EPSILON and increase the 'hi' values by the same.
*/
+# define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON))
+# define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON))
+
r = rlo = rhi = that->redf;
rlo -= that->rede;
- rlo = digitize(rlo, calc_depth, 1/*round*/);
+ rlo = DD(rlo, calc_depth, 1/*round*/);
rhi += that->rede;
- rhi = digitize(rhi, calc_depth, 1/*round*/);
+ rhi = DU(rhi, calc_depth, 1/*round*/);
g = glo = ghi = that->greenf;
glo -= that->greene;
- glo = digitize(glo, calc_depth, 1/*round*/);
+ glo = DD(glo, calc_depth, 1/*round*/);
ghi += that->greene;
- ghi = digitize(ghi, calc_depth, 1/*round*/);
+ ghi = DU(ghi, calc_depth, 1/*round*/);
b = blo = bhi = that->bluef;
blo -= that->bluee;
- blo = digitize(blo, calc_depth, 1/*round*/);
+ blo = DD(blo, calc_depth, 1/*round*/);
bhi += that->greene;
- bhi = digitize(bhi, calc_depth, 1/*round*/);
+ bhi = DU(bhi, calc_depth, 1/*round*/);
isgray = r==g && g==b;
if (data.gamma != 1)
{
PNG_CONST double power = 1/data.gamma;
- PNG_CONST double abse = calc_depth == 16 ? .5/65535 : .5/255;
-
- /* 'abse' is the absolute error permitted in linear calculations. It
- * is used here to capture the error permitted in the handling
- * (undoing) of the gamma encoding. Once again digitization occurs
- * to handle the upper and lower bounds of the values. This is
- * where the real errors are introduced.
+ PNG_CONST double abse = .5/(sample_depth == 16 ? 65535 : 255);
+
+ /* If a gamma calculation is done it is done using lookup tables of
+ * precision gamma_depth, so the already digitized value above may
+ * need to be further digitized here.
*/
+ if (gamma_depth != calc_depth)
+ {
+ rlo = DD(rlo, gamma_depth, 0/*truncate*/);
+ rhi = DU(rhi, gamma_depth, 0/*truncate*/);
+ glo = DD(glo, gamma_depth, 0/*truncate*/);
+ ghi = DU(ghi, gamma_depth, 0/*truncate*/);
+ blo = DD(blo, gamma_depth, 0/*truncate*/);
+ bhi = DU(bhi, gamma_depth, 0/*truncate*/);
+ }
+
+ /* 'abse' is the error in the gamma table calculation itself. */
r = pow(r, power);
- rlo = digitize(pow(rlo, power)-abse, calc_depth, 1);
- rhi = digitize(pow(rhi, power)+abse, calc_depth, 1);
+ rlo = DD(pow(rlo, power)-abse, calc_depth, 1);
+ rhi = DU(pow(rhi, power)+abse, calc_depth, 1);
g = pow(g, power);
- glo = digitize(pow(glo, power)-abse, calc_depth, 1);
- ghi = digitize(pow(ghi, power)+abse, calc_depth, 1);
+ glo = DD(pow(glo, power)-abse, calc_depth, 1);
+ ghi = DU(pow(ghi, power)+abse, calc_depth, 1);
b = pow(b, power);
- blo = digitize(pow(blo, power)-abse, calc_depth, 1);
- bhi = digitize(pow(bhi, power)+abse, calc_depth, 1);
+ blo = DD(pow(blo, power)-abse, calc_depth, 1);
+ bhi = DU(pow(bhi, power)+abse, calc_depth, 1);
}
/* Now calculate the actual gray values. Although the error in the
* coefficients depends on whether they were specified on the command
* line (in which case truncation to 15 bits happened) or not (rounding
* was used) the maxium error in an individual coefficient is always
- * 1/32768, because even in the rounding case the requirement that
+ * 2/32768, because even in the rounding case the requirement that
* coefficients add up to 32768 can cause a larger rounding error.
*
* The only time when rounding doesn't occur in 1.5.5 and later is when
@@ -7185,19 +7305,19 @@
{
PNG_CONST int do_round = data.gamma != 1 || calc_depth == 16;
- PNG_CONST double ce = 1. / 32768;
-
- graylo = digitize(rlo * (data.red_coefficient-ce) +
+ PNG_CONST double ce = 2. / 32768;
+
+ graylo = DD(rlo * (data.red_coefficient-ce) +
glo * (data.green_coefficient-ce) +
- blo * (data.blue_coefficient-ce), gamma_depth, do_round);
- if (graylo <= 0)
- graylo = 0;
-
- grayhi = digitize(rhi * (data.red_coefficient+ce) +
+ blo * (data.blue_coefficient-ce), calc_depth, do_round);
+ if (graylo > gray) /* always accept the right answer */
+ graylo = gray;
+
+ grayhi = DU(rhi * (data.red_coefficient+ce) +
ghi * (data.green_coefficient+ce) +
- bhi * (data.blue_coefficient+ce), gamma_depth, do_round);
- if (grayhi >= 1)
- grayhi = 1;
+ bhi * (data.blue_coefficient+ce), calc_depth, do_round);
+ if (grayhi < gray)
+ grayhi = gray;
}
/* And invert the gamma. */
@@ -7205,10 +7325,24 @@
{
PNG_CONST double power = data.gamma;
+ /* And this happens yet again, shifting the values once more. */
+ if (gamma_depth != sample_depth)
+ {
+ rlo = DD(rlo, gamma_depth, 0/*truncate*/);
+ rhi = DU(rhi, gamma_depth, 0/*truncate*/);
+ glo = DD(glo, gamma_depth, 0/*truncate*/);
+ ghi = DU(ghi, gamma_depth, 0/*truncate*/);
+ blo = DD(blo, gamma_depth, 0/*truncate*/);
+ bhi = DU(bhi, gamma_depth, 0/*truncate*/);
+ }
+
gray = pow(gray, power);
- graylo = digitize(pow(graylo, power), sample_depth, 1);
- grayhi = digitize(pow(grayhi, power), sample_depth, 1);
+ graylo = DD(pow(graylo, power), sample_depth, 1);
+ grayhi = DU(pow(grayhi, power), sample_depth, 1);
}
+
+# undef DD
+# undef DU
/* Now the error can be calculated.
*
@@ -7260,16 +7394,28 @@
{
/* There is no need to do the conversions to and from linear space,
* so the calculation should be a lot more accurate. There is a
- * built in 1/32768 error in the coefficients because they only have
- * 15 bits and are adjusted to make sure they add up to 32768, so
- * the result may have an additional error up to 1/32768. (Note
- * that adding the 1/32768 here avoids needing to increase the
- * global error limits to take this into account.)
+ * built in error in the coefficients because they only have 15 bits
+ * and are adjusted to make sure they add up to 32768. This
+ * involves a integer calculation with truncation of the form:
+ *
+ * ((int)(coefficient * 100000) * 32768)/100000
+ *
+ * This is done to the red and green coefficients (the ones
+ * provided to the API) then blue is calculated from them so the
+ * result adds up to 32768. In the worst case this can result in
+ * a -1 error in red and green and a +2 error in blue. Consequently
+ * the worst case in the calculation below is 2/32768 error.
+ *
+ * TODO: consider fixing this in libpng by rounding the calculation
+ * limiting the error to 1/32768.
+ *
+ * Handling this by adding 2/32768 here avoids needing to increase
+ * the global error limits to take this into account.)
*/
gray = r * data.red_coefficient + g * data.green_coefficient +
b * data.blue_coefficient;
err = re * data.red_coefficient + ge * data.green_coefficient +
- be * data.blue_coefficient + 1./32768 + gray * 5 * DBL_EPSILON;
+ be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON;
}
else
@@ -7304,7 +7450,7 @@
* previously added input quantization error at this point.
*/
gray = r * data.red_coefficient + g * data.green_coefficient +
- b * data.blue_coefficient - 1./32768 - out_qe;
+ b * data.blue_coefficient - 2./32768 - out_qe;
if (gray <= 0)
gray = 0;
else
@@ -7314,7 +7460,7 @@
}
grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +
- bhi * data.blue_coefficient + 1./32768 + out_qe;
+ bhi * data.blue_coefficient + 2./32768 + out_qe;
grayhi *= (1 + 6 * DBL_EPSILON);
if (grayhi >= 1)
grayhi = 1;
@@ -7429,6 +7575,9 @@
else
{
+ if (that->this.has_tRNS)
+ that->this.is_transparent = 1;
+
bit_depth = that->this.bit_depth;
expand = 1;
}
@@ -7506,13 +7655,13 @@
/* Remove the alpha type and set the alpha (not in that order.) */
that->alphaf = 1;
that->alphae = 0;
-
- if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_RGB;
- else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- that->colour_type = PNG_COLOR_TYPE_GRAY;
- /* PNG_COLOR_TYPE_PALETTE is not changed */
- }
+ }
+
+ if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ that->colour_type = PNG_COLOR_TYPE_RGB;
+ else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ that->colour_type = PNG_COLOR_TYPE_GRAY;
+ /* PNG_COLOR_TYPE_PALETTE is not changed */
this->next->mod(this->next, that, pp, display);
}
@@ -8301,7 +8450,8 @@
png_byte bit_depth = 0;
unsigned int palette_number = 0;
- while (next_format(&colour_type, &bit_depth, &palette_number, 0))
+ while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg,
+ pm->test_tRNS))
{
png_uint_32 counter = 0;
size_t base_pos;
@@ -8604,7 +8754,9 @@
vi->outlog = outlog(dp->pm, in_depth, out_depth);
if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||
- (dp->this.colour_type == 3 && dp->this.is_transparent))
+ (dp->this.colour_type == 3 && dp->this.is_transparent) ||
+ ((dp->this.colour_type == 0 || dp->this.colour_type == 2) &&
+ dp->this.has_tRNS))
{
vi->do_background = dp->do_background;
@@ -8634,7 +8786,7 @@
vi->background_blue = b;
}
}
- else
+ else /* Do not expect any background processing */
vi->do_background = 0;
if (vi->do_background == 0)
@@ -9350,6 +9502,7 @@
png_uint_32 y;
PNG_CONST store_palette_entry *in_palette = dp->this.palette;
PNG_CONST int in_is_transparent = dp->this.is_transparent;
+ int process_tRNS;
int out_npalette = -1;
int out_is_transparent = 0; /* Just refers to the palette case */
store_palette out_palette;
@@ -9365,6 +9518,7 @@
processing = (vi.gamma_correction > 0 && !dp->threshold_test)
|| in_bd != out_bd || in_ct != out_ct || vi.do_background;
+ process_tRNS = dp->this.has_tRNS && vi.do_background;
/* TODO: FIX THIS: MAJOR BUG! If the transformations all happen inside
* the palette there is no way of finding out, because libpng fails to
@@ -9403,8 +9557,8 @@
/* Handle input alpha - png_set_background will cause the output
* alpha to disappear so there is nothing to check.
*/
- if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || (in_ct == 3 &&
- in_is_transparent))
+ if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||
+ (in_ct == 3 && in_is_transparent))
{
PNG_CONST unsigned int input_alpha = in_ct == 3 ?
dp->this.palette[in_index].alpha :
@@ -9433,6 +9587,35 @@
*/
alpha = input_alpha >> vi.isbit_shift;
alpha /= vi.sbit_max;
+ }
+ }
+
+ else if (process_tRNS)
+ {
+ /* alpha needs to be set appropriately for this pixel, it is
+ * currently 1 and needs to be 0 for an input pixel which matches
+ * the values in tRNS.
+ */
+ switch (in_ct)
+ {
+ case 0: /* gray */
+ if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
+ dp->this.transparent.red)
+ alpha = 0;
+ break;
+
+ case 2: /* RGB */
+ if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
+ dp->this.transparent.red &&
+ sample(std, in_ct, in_bd, x, 1, 0, 0) ==
+ dp->this.transparent.green &&
+ sample(std, in_ct, in_bd, x, 2, 0, 0) ==
+ dp->this.transparent.blue)
+ alpha = 0;
+ break;
+
+ default:
+ break;
}
}
@@ -9545,7 +9728,7 @@
modification_reset(d.pm->modifications);
- /* Get a png_struct for writing the image. */
+ /* Get a png_struct for reading the image. */
pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
standard_palette_init(&d.this);
@@ -9684,9 +9867,13 @@
/* Don't test more than one instance of each palette - it's pointless, in
* fact this test is somewhat excessive since libpng doesn't make this
* decision based on colour type or bit depth!
- */
- while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
- if (palette_number == 0)
+ *
+ * CHANGED: now test two palettes and, as a side effect, images with and
+ * without tRNS.
+ */
+ while (next_format(&colour_type, &bit_depth, &palette_number,
+ pm->test_lbg_gamma_threshold, pm->test_tRNS))
+ if (palette_number < 2)
{
double test_gamma = 1.0;
while (test_gamma >= .4)
@@ -9746,7 +9933,8 @@
png_byte bit_depth = 0;
unsigned int palette_number = 0;
- while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
+ while (next_format(&colour_type, &bit_depth, &palette_number,
+ pm->test_lbg_gamma_transform, pm->test_tRNS))
{
unsigned int i, j;
@@ -9776,7 +9964,8 @@
png_byte colour_type = 0, bit_depth = 0;
unsigned int npalette = 0;
- while (next_format(&colour_type, &bit_depth, &npalette, 1/*gamma*/))
+ while (next_format(&colour_type, &bit_depth, &npalette,
+ pm->test_lbg_gamma_sbit, pm->test_tRNS))
if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
((colour_type == 3 && sbit < 8) ||
(colour_type != 3 && sbit < bit_depth)))
@@ -9967,8 +10156,17 @@
}
background.index = 193; /* rgb(193,193,193) to detect errors */
+
if (!(colour_type & PNG_COLOR_MASK_COLOR))
{
+ /* Because, currently, png_set_background is always called with
+ * 'need_expand' false in this case and because the gamma test itself
+ * doesn't cause an expand to 8-bit for lower bit depths the colour must
+ * be reduced to the correct range.
+ */
+ if (bit_depth < 8)
+ background.gray &= (png_uint_16)((1U << bit_depth)-1);
+
/* Grayscale input, we do not convert to RGB (TBD), so we must set the
* background to gray - else libpng seems to fail.
*/
@@ -10017,9 +10215,18 @@
/* Skip the non-alpha cases - there is no setting of a transparency colour at
* present.
- */
- while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
- if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0)
+ *
+ * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do,
+ * however the palette case fails miserably so is commented out below.
+ */
+ while (next_format(&colour_type, &bit_depth, &palette_number,
+ pm->test_lbg_gamma_composition, pm->test_tRNS))
+ if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0
+#if 0 /* TODO: FIXME */
+ /*TODO: FIXME: this should work */
+ || colour_type == 3
+#endif
+ || (colour_type != 3 && palette_number != 0))
{
unsigned int i, j;
@@ -10751,6 +10958,18 @@
pm.ngammas = ARRAY_SIZE(gammas);
pm.ngamma_tests = 0; /* default to off */
+ /* Low bit depth gray images don't do well in the gamma tests, until
+ * this is fixed turn them off for some gamma cases:
+ */
+# ifdef PNG_WRITE_tRNS_SUPPORTED
+ pm.test_tRNS = 1;
+# endif
+ pm.test_lbg = 0;
+ pm.test_lbg_gamma_threshold = 1;
+ pm.test_lbg_gamma_transform = 0/*PNG_LIBPNG_VER >= 10700*/;
+ pm.test_lbg_gamma_sbit = 1;
+ pm.test_lbg_gamma_composition = 0;
+
/* And the test encodings */
pm.encodings = test_encodings;
pm.nencodings = ARRAY_SIZE(test_encodings);
@@ -10863,7 +11082,7 @@
pm.test_gamma_transform = 1;
pm.test_gamma_sbit = 1;
pm.test_gamma_scale16 = 1;
- pm.test_gamma_background = 1;
+ pm.test_gamma_background = 1; /* composition */
pm.test_gamma_alpha_mode = 1;
}
@@ -10911,6 +11130,24 @@
else if (strcmp(*argv, "--noexpand16") == 0)
pm.test_gamma_expand16 = 0;
+
+ else if (strcmp(*argv, "--low-depth-gray") == 0)
+ pm.test_lbg = pm.test_lbg_gamma_threshold =
+ pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
+ pm.test_lbg_gamma_composition = 1;
+
+ else if (strcmp(*argv, "--nolow-depth-gray") == 0)
+ pm.test_lbg = pm.test_lbg_gamma_threshold =
+ pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
+ pm.test_lbg_gamma_composition = 0;
+
+# ifdef PNG_WRITE_tRNS_SUPPORTED
+ else if (strcmp(*argv, "--tRNS") == 0)
+ pm.test_tRNS = 1;
+# endif
+
+ else if (strcmp(*argv, "--notRNS") == 0)
+ pm.test_tRNS = 0;
else if (strcmp(*argv, "--more-gammas") == 0)
pm.ngamma_tests = 3U;
@@ -11102,7 +11339,7 @@
Try
{
/* Make useful base images */
- make_transform_images(&pm.this);
+ make_transform_images(&pm);
/* Perform the standard and gamma tests. */
if (pm.test_standard)

View File

@ -1,3 +1,16 @@
-------------------------------------------------------------------
Fri Nov 13 07:25:01 UTC 2015 - pgajdos@suse.com
- update to 1.6.19:
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
Fixed the recently reported 1's complement security issue.
Fixed png_save_int_32 when int is not 2's complement by replacing
the value that is illegal in the PNG spec, in both signed and
unsigned values, with 0.
etc., see ANNOUNCE and CHANGES for details
- removed: libpng-rgb_to_gray-checks.patch (upstreamed)
-------------------------------------------------------------------
Fri Aug 7 14:19:31 UTC 2015 - pgajdos@suse.com

View File

@ -19,7 +19,7 @@
#
%define major 1
%define minor 6
%define micro 17
%define micro 19
%define branch %{major}%{minor}
%define libname libpng%{branch}-%{branch}
@ -35,7 +35,6 @@ Source1: ftp://ftp.simplesystems.org/pub/png/src/libpng16/libpng-%{versio
Source2: libpng16.keyring
Source3: rpm-macros.libpng-tools
Source4: baselibs.conf
Patch0: libpng-rgb_to_gray-checks.patch
#BuildRequires: gpg-offline
BuildRequires: libtool
BuildRequires: pkg-config
@ -111,7 +110,6 @@ PNG files.
%prep
%setup -n libpng-%{version}
%patch0
%build
# PNG_SAFE_LIMITS_SUPPORTED: http://www.openwall.com/lists/oss-security/2015/01/10/1