[libpng16] Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the

compiled library size. It never worked properly and as far as we can
tell, no one uses it. The png_set_filter_heuristics() and
png_set_filter_heuristics_fixed() APIs are retained but deprecated
and do nothing.
This commit is contained in:
Glenn Randers-Pehrson 2015-05-31 22:40:36 -05:00
parent a008dd8344
commit 89edbf8317
5 changed files with 30 additions and 538 deletions

View File

@ -1,4 +1,4 @@
Libpng 1.6.18beta06 - May 31, 2015
Libpng 1.6.18beta06 - June 1, 2015
This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version.
@ -62,7 +62,12 @@ Version 1.6.18beta05 [May 31, 2015]
Fixed old cut&paste bug in the weighted filter selection code in
pngwutil.c, introduced in libpng-0.95, March 1997.
Version 1.6.18beta06 [May 31, 2015]
Version 1.6.18beta06 [June 1, 2015]
Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the
compiled library size. It never worked properly and as far as we can
tell, no one uses it. The png_set_filter_heuristics() and
png_set_filter_heuristics_fixed() APIs are retained but deprecated
and do nothing.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -5247,7 +5247,12 @@ Version 1.6.18beta05 [May 31, 2015]
Fixed old cut&paste bug in the weighted filter selection code in
pngwutil.c, introduced in libpng-0.95, March 1997.
Version 1.6.18beta06 [May 31, 2015]
Version 1.6.18beta06 [June 1, 2015]
Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the
compiled library size. It never worked properly and as far as we can
tell, no one uses it. The png_set_filter_heuristics() and
png_set_filter_heuristics_fixed() APIs are retained but deprecated
and do nothing.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

40
png.h
View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.6.18beta06, May 31, 2015
* libpng version 1.6.18beta06, June 1, 2015
*
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@ -12,7 +12,7 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.18beta06, May 31, 2015: Glenn
* libpng versions 0.97, January 1998, through 1.6.18beta06, June 1, 2015: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@ -248,7 +248,7 @@
*
* This code is released under the libpng license.
*
* libpng versions 1.2.6, August 15, 2004, through 1.6.18beta06, May 31, 2015, are
* libpng versions 1.2.6, August 15, 2004, through 1.6.18beta06, June 1, 2015, are
* Copyright (c) 2004, 2006-2015 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors:
@ -360,7 +360,7 @@
* Y2K compliance in libpng:
* =========================
*
* May 31, 2015
* June 1, 2015
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
@ -430,7 +430,7 @@
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.18beta06"
#define PNG_HEADER_VERSION_STRING \
" libpng version 1.6.18beta06 - May 31, 2015\n"
" libpng version 1.6.18beta06 - June 1, 2015\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@ -1624,35 +1624,7 @@ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
#define PNG_FILTER_VALUE_LAST 5
#ifdef PNG_WRITE_SUPPORTED
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */
/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
* defines, either the default (minimum-sum-of-absolute-differences), or
* the experimental method (weighted-minimum-sum-of-absolute-differences).
*
* Weights are factors >= 1.0, indicating how important it is to keep the
* filter type consistent between rows. Larger numbers mean the current
* filter is that many times as likely to be the same as the "num_weights"
* previous filters. This is cumulative for each previous row with a weight.
* There needs to be "num_weights" values in "filter_weights", or it can be
* NULL if the weights aren't being specified. Weights have no influence on
* the selection of the first row filter. Well chosen weights can (in theory)
* improve the compression for a given image.
*
* Costs are factors >= 1.0 indicating the relative decoding costs of a
* filter type. Higher costs indicate more decoding expense, and are
* therefore less likely to be selected over a filter with lower computational
* costs. There needs to be a value in "filter_costs" for each valid filter
* type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
* setting the costs. Costs try to improve the speed of decompression without
* unduly increasing the compressed image size.
*
* A negative weight or cost indicates the default value is to be used, and
* values in the range [0.0, 1.0) indicate the value is to remain unchanged.
* The default values for both weights and costs are currently 1.0, but may
* change if good general weighting/cost heuristics can be found. If both
* the weights and costs are set to 1.0, this degenerates the WEIGHTED method
* to the UNWEIGHTED method, but with added encoding time/computation.
*/
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
int heuristic_method, int num_weights, png_const_doublep filter_weights,
png_const_doublep filter_costs))

View File

@ -922,10 +922,6 @@ png_write_flush(png_structrp png_ptr)
}
#endif /* WRITE_FLUSH */
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */
#endif
/* Free any memory used in png_ptr struct without freeing the struct itself. */
static void
png_write_destroy(png_structrp png_ptr)
@ -949,15 +945,6 @@ png_write_destroy(png_structrp png_ptr)
png_ptr->tst_row = NULL;
#endif
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
/* Use this to save a little code space, it doesn't free the filter_costs */
png_reset_filter_heuristics(png_ptr);
png_free(png_ptr, png_ptr->filter_costs);
png_free(png_ptr, png_ptr->inv_filter_costs);
png_ptr->filter_costs = NULL;
png_ptr->inv_filter_costs = NULL;
#endif
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
png_free(png_ptr, png_ptr->chunk_list);
png_ptr->chunk_list = NULL;
@ -1127,174 +1114,18 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
* better compression.
*/
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */
/* Convenience reset API. */
static void
png_reset_filter_heuristics(png_structrp png_ptr)
{
/* Clear out any old values in the 'weights' - this must be done because if
* the app calls set_filter_heuristics multiple times with different
* 'num_weights' values we would otherwise potentially have wrong sized
* arrays.
*/
png_ptr->num_prev_filters = 0;
png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
if (png_ptr->prev_filters != NULL)
{
png_bytep old = png_ptr->prev_filters;
png_ptr->prev_filters = NULL;
png_free(png_ptr, old);
}
if (png_ptr->filter_weights != NULL)
{
png_uint_16p old = png_ptr->filter_weights;
png_ptr->filter_weights = NULL;
png_free(png_ptr, old);
}
if (png_ptr->inv_filter_weights != NULL)
{
png_uint_16p old = png_ptr->inv_filter_weights;
png_ptr->inv_filter_weights = NULL;
png_free(png_ptr, old);
}
/* Leave the filter_costs - this array is fixed size. */
}
static int
png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
int num_weights)
{
if (png_ptr == NULL)
return 0;
/* Clear out the arrays */
png_reset_filter_heuristics(png_ptr);
/* Check arguments; the 'reset' function makes the correct settings for the
* unweighted case, but we must handle the weight case by initializing the
* arrays for the caller.
*/
if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
{
int i;
if (num_weights > 0)
{
png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
(png_uint_32)((sizeof (png_byte)) * num_weights));
/* To make sure that the weighting starts out fairly */
for (i = 0; i < num_weights; i++)
{
png_ptr->prev_filters[i] = 255;
}
png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)((sizeof (png_uint_16)) * num_weights));
png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)((sizeof (png_uint_16)) * num_weights));
for (i = 0; i < num_weights; i++)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
/* Safe to set this now */
png_ptr->num_prev_filters = (png_byte)num_weights;
}
/* If, in the future, there are other filter methods, this would
* need to be based on png_ptr->filter.
*/
if (png_ptr->filter_costs == NULL)
{
png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
(png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
}
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
{
png_ptr->inv_filter_costs[i] =
png_ptr->filter_costs[i] = PNG_COST_FACTOR;
}
/* All the arrays are inited, safe to set this: */
png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
/* Return the 'ok' code. */
return 1;
}
else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
{
return 1;
}
else
{
png_warning(png_ptr, "Unknown filter heuristic method");
return 0;
}
}
/* Provide floating and fixed point APIs */
/* Provide floating and fixed point APIs (DEPRECATED) */
#ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
int num_weights, png_const_doublep filter_weights,
png_const_doublep filter_costs)
{
png_debug(1, "in png_set_filter_heuristics");
/* The internal API allocates all the arrays and ensures that the elements of
* those arrays are set to the default value.
*/
if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0)
return;
/* If using the weighted method copy in the weights. */
if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
{
int i;
for (i = 0; i < num_weights; i++)
{
if (filter_weights[i] <= 0.0)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
else
{
png_ptr->inv_filter_weights[i] =
(png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
png_ptr->filter_weights[i] =
(png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
}
}
/* Here is where we set the relative costs of the different filters. We
* should take the desired compression level into account when setting
* the costs, so that Paeth, for instance, has a high relative cost at low
* compression levels, while it has a lower relative cost at higher
* compression settings. The filter types are in order of increasing
* relative cost, so it would be possible to do this with an algorithm.
*/
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
{
png_ptr->inv_filter_costs[i] =
(png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
png_ptr->filter_costs[i] =
(png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
}
}
PNG_UNUSED(png_ptr)
PNG_UNUSED(heuristic_method)
PNG_UNUSED(num_weights)
PNG_UNUSED(filter_weights)
PNG_UNUSED(filter_costs)
}
#endif /* FLOATING_POINT */
@ -1304,63 +1135,11 @@ png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
int num_weights, png_const_fixed_point_p filter_weights,
png_const_fixed_point_p filter_costs)
{
png_debug(1, "in png_set_filter_heuristics_fixed");
/* The internal API allocates all the arrays and ensures that the elements of
* those arrays are set to the default value.
*/
if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0)
return;
/* If using the weighted method copy in the weights. */
if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
{
int i;
for (i = 0; i < num_weights; i++)
{
if (filter_weights[i] <= 0)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
else
{
png_ptr->inv_filter_weights[i] = (png_uint_16)
((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
}
}
/* Here is where we set the relative costs of the different filters. We
* should take the desired compression level into account when setting
* the costs, so that Paeth, for instance, has a high relative cost at low
* compression levels, while it has a lower relative cost at higher
* compression settings. The filter types are in order of increasing
* relative cost, so it would be possible to do this with an algorithm.
*/
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
if (filter_costs[i] >= PNG_FP_1)
{
png_uint_32 tmp;
/* Use a 32 bit unsigned temporary here because otherwise the
* intermediate value will be a 32 bit *signed* integer (ANSI rules)
* and this will get the wrong answer on division.
*/
tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
tmp /= filter_costs[i];
png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
tmp /= PNG_FP_1;
png_ptr->filter_costs[i] = (png_uint_16)tmp;
}
}
PNG_UNUSED(png_ptr)
PNG_UNUSED(heuristic_method)
PNG_UNUSED(num_weights)
PNG_UNUSED(filter_weights)
PNG_UNUSED(filter_costs)
}
#endif /* FIXED_POINT */
#endif /* WRITE_WEIGHTED_FILTER */

View File

@ -2469,55 +2469,6 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum);
}
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#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))
static png_size_t /* PRIVATE */
png_increase_lmins(png_structrp png_ptr, png_size_t lmins)
{
/* 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.
*/
int j;
png_uint_32 lmhi, lmlo;
lmlo = lmins & PNG_LOMASK;
lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
for (j = 0; j < png_ptr->num_prev_filters; j++)
{
if (png_ptr->prev_filters[j] == png_ptr->try_row[0])
{
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_ptr->try_row[0]]) >>
PNG_COST_SHIFT;
lmhi = (lmhi * png_ptr->inv_filter_costs[png_ptr->try_row[0]]) >>
PNG_COST_SHIFT;
if (lmhi > PNG_HIMASK)
lmins = PNG_MAXSUM;
else
lmins = (lmhi << PNG_HISHIFT) + lmlo;
return (lmins);
}
#endif /* WRITE_WEIGHTED_FILTER */
#endif /* WRITE_FILTER */
void /* PRIVATE */
@ -2530,22 +2481,11 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_bytep row_buf;
png_bytep best_row;
png_uint_32 bpp;
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
int num_p_filters = png_ptr->num_prev_filters;
#endif
png_size_t mins;
png_size_t row_bytes = row_info->rowbytes;
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;
@ -2591,45 +2531,6 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t i;
int 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++)
{
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;
}
}
/* 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
if (PNG_SIZE_MAX/128 <= row_bytes)
{
for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
@ -2666,48 +2567,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
{
png_size_t sum;
png_size_t lmins = mins;
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
lmins = png_increase_lmins(png_ptr, lmins);
#endif
sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
#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
if (sum < mins)
{
mins = sum;
@ -2731,48 +2593,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
{
png_size_t sum;
png_size_t lmins = mins;
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
lmins = png_increase_lmins(png_ptr, lmins);
#endif
sum = png_setup_up_row(png_ptr, row_bytes, lmins);
#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
if (sum < mins)
{
mins = sum;
@ -2796,48 +2619,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
{
png_size_t sum;
png_size_t lmins = mins;
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
lmins = png_increase_lmins(png_ptr, lmins);
#endif
sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
#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_AVG)
{
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
if (sum < mins)
{
mins = sum;
@ -2861,48 +2645,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
{
png_size_t sum;
png_size_t lmins = mins;
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
lmins = png_increase_lmins(png_ptr, lmins);
#endif
sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
#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
if (sum < mins)
{
mins = sum;
@ -2918,20 +2663,6 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* 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_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 /* WRITE_WEIGHTED_FILTER */
#endif /* WRITE_FILTER */
}