--- a/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwutil.c Tue Dec 01 12:38:28 2015 +0000
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/libpng/pngwutil.c Tue Dec 08 19:01:33 2015 +0300
@@ -29,8 +29,8 @@
* However, the following notice accompanied the original version of this
* file and, per its terms, should not be removed:
*
- * Last changed in libpng 1.6.15 [November 20, 2014]
- * Copyright (c) 1998-2014 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.19 [November 12, 2015]
+ * Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@@ -51,10 +51,10 @@
void PNGAPI
png_save_uint_32(png_bytep buf, png_uint_32 i)
{
- buf[0] = (png_byte)((i >> 24) & 0xff);
- buf[1] = (png_byte)((i >> 16) & 0xff);
- buf[2] = (png_byte)((i >> 8) & 0xff);
- buf[3] = (png_byte)(i & 0xff);
+ buf[0] = (png_byte)(i >> 24);
+ buf[1] = (png_byte)(i >> 16);
+ buf[2] = (png_byte)(i >> 8);
+ buf[3] = (png_byte)(i );
}
/* Place a 16-bit number into a buffer in PNG byte order.
@@ -64,8 +64,8 @@
void PNGAPI
png_save_uint_16(png_bytep buf, unsigned int i)
{
- buf[0] = (png_byte)((i >> 8) & 0xff);
- buf[1] = (png_byte)(i & 0xff);
+ buf[0] = (png_byte)(i >> 8);
+ buf[1] = (png_byte)(i );
}
#endif
@@ -207,7 +207,7 @@
if (png_ptr == NULL)
return;
- /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
+ /* On 64-bit architectures 'length' may not fit in a png_uint_32. */
if (length > PNG_UINT_31_MAX)
png_error(png_ptr, "length exceeds PNG maximum");
@@ -336,7 +336,7 @@
*/
(void)png_safecat(msg, (sizeof msg), 10, " using zstream");
#endif
-#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+#if PNG_RELEASE_BUILD
png_warning(png_ptr, msg);
/* Attempt sane error recovery */
@@ -723,7 +723,7 @@
while (*key && key_len < 79)
{
- png_byte ch = (png_byte)(0xff & *key++);
+ png_byte ch = (png_byte)*key++;
if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
*new_key++ = ch, ++key_len, space = 0;
@@ -899,7 +899,7 @@
interlace_type=PNG_INTERLACE_NONE;
#endif
- /* Save the relevent information */
+ /* Save the relevant information */
png_ptr->bit_depth = (png_byte)bit_depth;
png_ptr->color_type = (png_byte)color_type;
png_ptr->interlaced = (png_byte)interlace_type;
@@ -950,17 +950,20 @@
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
png_uint_32 num_pal)
{
- png_uint_32 i;
+ png_uint_32 max_palette_length, i;
png_const_colorp pal_ptr;
png_byte buf[3];
png_debug(1, "in png_write_PLTE");
+ max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
+ (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
+
if ((
#ifdef PNG_MNG_FEATURES_SUPPORTED
(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
#endif
- num_pal == 0) || num_pal > 256)
+ num_pal == 0) || num_pal > max_palette_length)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
@@ -1472,7 +1475,7 @@
else if (color_type == PNG_COLOR_TYPE_GRAY)
{
- /* One 16 bit value */
+ /* One 16-bit value */
if (tran->gray >= (1 << png_ptr->bit_depth))
{
png_app_warning(png_ptr,
@@ -1487,7 +1490,7 @@
else if (color_type == PNG_COLOR_TYPE_RGB)
{
- /* Three 16 bit values */
+ /* Three 16-bit values */
png_save_uint_16(buf, tran->red);
png_save_uint_16(buf + 2, tran->green);
png_save_uint_16(buf + 4, tran->blue);
@@ -1793,7 +1796,7 @@
png_write_compressed_data_out(png_ptr, &comp);
else
- png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);
+ png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);
png_write_chunk_end(png_ptr);
}
@@ -1989,6 +1992,10 @@
png_alloc_size_t buf_size;
int usr_pixel_depth;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_byte filters;
+#endif
+
png_debug(1, "in png_write_start_row");
usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
@@ -1999,50 +2006,54 @@
png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
/* Set up row buffer */
- png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
+ png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
#ifdef PNG_WRITE_FILTER_SUPPORTED
- /* Set up filtering buffer, if using this filter */
- if (png_ptr->do_filter & PNG_FILTER_SUB)
- {
- png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
-
- png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
- }
-
- /* We only need to keep the previous row if we are using one of these. */
- if ((png_ptr->do_filter &
- (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
+ filters = png_ptr->do_filter;
+
+ if (png_ptr->height == 1)
+ filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+
+ if (png_ptr->width == 1)
+ filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+
+ if (filters == 0)
+ filters = PNG_FILTER_NONE;
+
+ png_ptr->do_filter = filters;
+
+ if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG |
+ PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL)
{
- /* Set up previous row buffer */
- png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
-
- if ((png_ptr->do_filter & PNG_FILTER_UP) != 0)
- {
- png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
- png_ptr->rowbytes + 1);
-
- png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_AVG) != 0)
- {
- png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
- png_ptr->rowbytes + 1);
-
- png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
- }
-
- if ((png_ptr->do_filter & PNG_FILTER_PAETH) != 0)
- {
- png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
- png_ptr->rowbytes + 1);
-
- png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
- }
+ int num_filters = 0;
+
+ png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
+
+ if (filters & PNG_FILTER_SUB)
+ num_filters++;
+
+ if (filters & PNG_FILTER_UP)
+ num_filters++;
+
+ if (filters & PNG_FILTER_AVG)
+ num_filters++;
+
+ if (filters & PNG_FILTER_PAETH)
+ num_filters++;
+
+ if (num_filters > 1)
+ png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr,
+ buf_size));
}
+
+ /* We only need to keep the previous row if we are using one of the following
+ * filters.
+ */
+ if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
+ png_ptr->prev_row = png_voidcast(png_bytep,
+ png_calloc(png_ptr, buf_size));
#endif /* WRITE_FILTER */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
@@ -2188,7 +2199,7 @@
{
png_bytep sp;
png_bytep dp;
- int shift;
+ unsigned int shift;
int d;
int value;
png_uint_32 i;
@@ -2226,7 +2237,7 @@
{
png_bytep sp;
png_bytep dp;
- int shift;
+ unsigned int shift;
int d;
int value;
png_uint_32 i;
@@ -2263,7 +2274,7 @@
{
png_bytep sp;
png_bytep dp;
- int shift;
+ unsigned int shift;
int d;
int value;
png_uint_32 i;
@@ -2338,50 +2349,181 @@
}
#endif
+
/* This filters the row, chooses which filter to use, if it has not already
* been specified by the application, and then writes the row out with the
* chosen filter.
*/
-static void
+static void /* PRIVATE */
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_size_t row_bytes);
-#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
-#define PNG_HISHIFT 10
-#define PNG_LOMASK ((png_uint_32)0xffffL)
-#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+static png_size_t /* PRIVATE */
+png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes, const png_size_t lmins)
+{
+ png_bytep rp, dp, lp;
+ png_size_t i;
+ png_size_t sum = 0;
+ int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+
+static png_size_t /* PRIVATE */
+png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
+ const png_size_t lmins)
+{
+ png_bytep rp, dp, pp;
+ png_size_t i;
+ png_size_t sum = 0;
+ int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+
+static png_size_t /* PRIVATE */
+png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes, const png_size_t lmins)
+{
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+ png_size_t sum = 0;
+ int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+
+static png_size_t /* PRIVATE */
+png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes, const png_size_t lmins)
+{
+ png_bytep rp, dp, pp, cp, lp;
+ png_size_t i;
+ png_size_t sum = 0;
+ int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
+ i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+#endif /* WRITE_FILTER */
+
void /* PRIVATE */
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
{
- png_bytep best_row;
-#ifdef PNG_WRITE_FILTER_SUPPORTED
- png_bytep prev_row, row_buf;
- png_uint_32 mins, bpp;
+#ifndef PNG_WRITE_FILTER_SUPPORTED
+ png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
+#else
png_byte filter_to_do = png_ptr->do_filter;
+ png_bytep row_buf;
+ png_bytep best_row;
+ png_uint_32 bpp;
+ png_size_t mins;
png_size_t row_bytes = row_info->rowbytes;
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- int num_p_filters = png_ptr->num_prev_filters;
-#endif
png_debug(1, "in png_write_find_filter");
-#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
- {
- /* These will never be selected so we need not test them. */
- filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
- }
-#endif
-
/* Find out how many bytes offset each pixel is */
bpp = (row_info->pixel_depth + 7) >> 3;
- prev_row = png_ptr->prev_row;
-#endif
- best_row = png_ptr->row_buf;
-#ifdef PNG_WRITE_FILTER_SUPPORTED
- row_buf = best_row;
- mins = PNG_MAXSUM;
+ row_buf = png_ptr->row_buf;
+ mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the
+ running sum */;
/* The prediction method we use is to find which method provides the
* smallest value when summing the absolute values of the distances
@@ -2411,57 +2553,37 @@
/* We don't need to test the 'no filter' case if this is the only filter
* that has been chosen, as it doesn't actually do anything to the data.
*/
+ best_row = png_ptr->row_buf;
+
+
if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)
{
png_bytep rp;
- png_uint_32 sum = 0;
+ png_size_t sum = 0;
png_size_t i;
int v;
- for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ if (PNG_SIZE_MAX/128 <= row_bytes)
{
- v = *rp;
- sum += (v < 128) ? v : 256 - v;
- }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- png_uint_32 sumhi, sumlo;
- int j;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
-
- /* Reduce the sum if we match any of the previous rows */
- for (j = 0; j < num_p_filters; j++)
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
{
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
+ /* Check for overflow */
+ if (sum > PNG_SIZE_MAX/128 - 256)
+ break;
+
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
}
-
- /* Factor in the cost of this filter (this is here for completeness,
- * but it makes no sense to have a "cost" for the NONE filter, as
- * it has the minimum possible computational cost - none).
- */
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
-
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
}
-#endif
+ else /* Overflow is not possible */
+ {
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ {
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
+ }
+ }
+
mins = sum;
}
@@ -2469,553 +2591,109 @@
if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */
{
- png_bytep rp, lp, dp;
- png_size_t i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- *dp = *rp;
- }
-
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
- }
-
- best_row = png_ptr->sub_row;
+ (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
+ best_row = png_ptr->try_row;
}
else if ((filter_to_do & PNG_FILTER_SUB) != 0)
{
- png_bytep rp, dp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_size_t i;
- int v;
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- /* We temporarily increase the "minimum sum" by the factor we
- * would reduce the sum of this filter, so that we can do the
- * early exit comparison without scaling the sum each time.
- */
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
-
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- v = *dp = *rp;
-
- sum += (v < 128) ? v : 256 - v;
- }
-
- for (lp = row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
- {
- sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
-
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
if (sum < mins)
{
mins = sum;
- best_row = png_ptr->sub_row;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
}
}
/* Up filter */
if (filter_to_do == PNG_FILTER_UP)
{
- png_bytep rp, dp, pp;
- png_size_t i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes;
- i++, rp++, pp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
- }
-
- best_row = png_ptr->up_row;
+ (void) png_setup_up_row(png_ptr, row_bytes, mins);
+ best_row = png_ptr->try_row;
}
else if ((filter_to_do & PNG_FILTER_UP) != 0)
{
- png_bytep rp, dp, pp;
- png_uint_32 sum = 0, lmins = mins;
- png_size_t i;
- int v;
-
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
-
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
- pp = prev_row + 1; i < row_bytes; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
-
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum = png_setup_up_row(png_ptr, row_bytes, lmins);
if (sum < mins)
{
mins = sum;
- best_row = png_ptr->up_row;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
}
}
/* Avg filter */
if (filter_to_do == PNG_FILTER_AVG)
{
- png_bytep rp, dp, pp, lp;
- png_uint_32 i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
- }
-
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
- & 0xff);
- }
- best_row = png_ptr->avg_row;
+ (void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins);
+ best_row = png_ptr->try_row;
}
else if ((filter_to_do & PNG_FILTER_AVG) != 0)
{
- png_bytep rp, dp, pp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_size_t i;
- int v;
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
-
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
-
- for (lp = row_buf + 1; i < row_bytes; i++)
- {
- v = *dp++ =
- (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
-
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
if (sum < mins)
{
mins = sum;
- best_row = png_ptr->avg_row;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
}
}
/* Paeth filter */
if ((filter_to_do == PNG_FILTER_PAETH) != 0)
{
- png_bytep rp, dp, pp, cp, lp;
- png_size_t i;
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
- }
- best_row = png_ptr->paeth_row;
+ (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins);
+ best_row = png_ptr->try_row;
}
else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
{
- png_bytep rp, dp, pp, cp, lp;
- png_uint_32 sum = 0, lmins = mins;
- png_size_t i;
- int v;
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 lmhi, lmlo;
- lmlo = lmins & PNG_LOMASK;
- lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (lmhi > PNG_HIMASK)
- lmins = PNG_MAXSUM;
-
- else
- lmins = (lmhi << PNG_HISHIFT) + lmlo;
- }
-#endif
-
- for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
- pp = prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
- }
-
- for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
-#ifndef PNG_SLOW_PAETH
- p = b - c;
- pc = a - c;
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-#else /* SLOW_PAETH */
- p = a + b - c;
- pa = abs(p - a);
- pb = abs(p - b);
- pc = abs(p - c);
-
- if (pa <= pb && pa <= pc)
- p = a;
-
- else if (pb <= pc)
- p = b;
-
- else
- p = c;
-#endif /* SLOW_PAETH */
-
- v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-
- sum += (v < 128) ? v : 256 - v;
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
- {
- int j;
- png_uint_32 sumhi, sumlo;
- sumlo = sum & PNG_LOMASK;
- sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
-
- for (j = 0; j < num_p_filters; j++)
- {
- if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
- {
- sumlo = (sumlo * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_weights[j]) >>
- PNG_WEIGHT_SHIFT;
- }
- }
-
- sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
- PNG_COST_SHIFT;
-
- if (sumhi > PNG_HIMASK)
- sum = PNG_MAXSUM;
-
- else
- sum = (sumhi << PNG_HISHIFT) + sumlo;
- }
-#endif
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
if (sum < mins)
{
- best_row = png_ptr->paeth_row;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
}
}
-#endif /* WRITE_FILTER */
/* Do the actual writing of the filtered row data from the chosen filter. */
png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
- /* Save the type of filter we picked this time for future calculations */
- if (png_ptr->num_prev_filters > 0)
- {
- int j;
-
- for (j = 1; j < num_p_filters; j++)
- {
- png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
- }
-
- png_ptr->prev_filters[j] = best_row[0];
- }
-#endif
#endif /* WRITE_FILTER */
}
@@ -3031,6 +2709,7 @@
png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
+#ifdef PNG_WRITE_FILTER_SUPPORTED
/* Swap the current and previous rows */
if (png_ptr->prev_row != NULL)
{
@@ -3040,6 +2719,7 @@
png_ptr->prev_row = png_ptr->row_buf;
png_ptr->row_buf = tptr;
}
+#endif /* WRITE_FILTER */
/* Finish row - updates counters and flushes zlib if last row */
png_write_finish_row(png_ptr);