mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[libpng17] Combined sub_row, up_row, avg_row, and paeth_row buffers into a
single try_row buffer.
This commit is contained in:
parent
ba22b208ed
commit
8bc832389a
6
ANNOUNCE
6
ANNOUNCE
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Libpng 1.7.0beta49 - February 7, 2015
|
Libpng 1.7.0beta49 - February 10, 2015
|
||||||
|
|
||||||
This is not intended to be a public release. It will be replaced
|
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.
|
within a few weeks by a public version or by another test version.
|
||||||
@ -701,7 +701,9 @@ Version 1.7.0beta48 [February 7, 2015]
|
|||||||
Work around one more Coverity-scan dead-code warning.
|
Work around one more Coverity-scan dead-code warning.
|
||||||
Do not build png_product2() when it is unused.
|
Do not build png_product2() when it is unused.
|
||||||
|
|
||||||
Version 1.7.0beta49 [February 7, 2015]
|
Version 1.7.0beta49 [February 10, 2015]
|
||||||
|
Combined sub_row, up_row, avg_row, and paeth_row buffers into a
|
||||||
|
single try_row buffer.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
4
CHANGES
4
CHANGES
@ -4990,7 +4990,9 @@ Version 1.7.0beta48 [February 7, 2015]
|
|||||||
Work around one more Coverity-scan dead-code warning.
|
Work around one more Coverity-scan dead-code warning.
|
||||||
Do not build png_product2() when it is unused.
|
Do not build png_product2() when it is unused.
|
||||||
|
|
||||||
Version 1.7.0beta49 [February 7, 2015]
|
Version 1.7.0beta49 [February 10, 2015]
|
||||||
|
Combined sub_row, up_row, avg_row, and paeth_row buffers into a
|
||||||
|
single try_row buffer.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
12
png.h
12
png.h
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* png.h - header file for PNG reference library
|
/* png.h - header file for PNG reference library
|
||||||
*
|
*
|
||||||
* libpng version 1.7.0beta49 - February 7, 2015
|
* libpng version 1.7.0beta49 - February 10, 2015
|
||||||
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
|
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
|
||||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||||
@ -11,7 +11,7 @@
|
|||||||
* Authors and maintainers:
|
* Authors and maintainers:
|
||||||
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
|
* 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.89c, June 1996, through 0.96, May 1997: Andreas Dilger
|
||||||
* libpng versions 0.97, January 1998, through 1.7.0beta49 - February 7, 2015: Glenn
|
* libpng versions 0.97, January 1998, through 1.7.0beta49 - February 10, 2015: Glenn
|
||||||
* See also "Contributing Authors", below.
|
* See also "Contributing Authors", below.
|
||||||
*
|
*
|
||||||
* Note about libpng version numbers:
|
* Note about libpng version numbers:
|
||||||
@ -200,7 +200,7 @@
|
|||||||
*
|
*
|
||||||
* This code is released under the libpng license.
|
* This code is released under the libpng license.
|
||||||
*
|
*
|
||||||
* libpng versions 1.2.6, August 15, 2004, through 1.7.0beta49, February 7, 2015, are
|
* libpng versions 1.2.6, August 15, 2004, through 1.7.0beta49, February 10, 2015, are
|
||||||
* Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
|
* Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
|
||||||
* distributed according to the same disclaimer and license as libpng-1.2.5
|
* distributed according to the same disclaimer and license as libpng-1.2.5
|
||||||
* with the following individual added to the list of Contributing Authors:
|
* with the following individual added to the list of Contributing Authors:
|
||||||
@ -312,7 +312,7 @@
|
|||||||
* Y2K compliance in libpng:
|
* Y2K compliance in libpng:
|
||||||
* =========================
|
* =========================
|
||||||
*
|
*
|
||||||
* February 7, 2015
|
* February 10, 2015
|
||||||
*
|
*
|
||||||
* Since the PNG Development group is an ad-hoc body, we can't make
|
* Since the PNG Development group is an ad-hoc body, we can't make
|
||||||
* an official declaration.
|
* an official declaration.
|
||||||
@ -382,7 +382,7 @@
|
|||||||
/* Version information for png.h - this should match the version in png.c */
|
/* Version information for png.h - this should match the version in png.c */
|
||||||
#define PNG_LIBPNG_VER_STRING "1.7.0beta49"
|
#define PNG_LIBPNG_VER_STRING "1.7.0beta49"
|
||||||
#define PNG_HEADER_VERSION_STRING \
|
#define PNG_HEADER_VERSION_STRING \
|
||||||
" libpng version 1.7.0beta49 - February 7, 2015\n"
|
" libpng version 1.7.0beta49 - February 10, 2015\n"
|
||||||
|
|
||||||
#define PNG_LIBPNG_VER_SONUM 17
|
#define PNG_LIBPNG_VER_SONUM 17
|
||||||
#define PNG_LIBPNG_VER_DLLNUM 17
|
#define PNG_LIBPNG_VER_DLLNUM 17
|
||||||
@ -1765,7 +1765,6 @@ PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
|
|||||||
|
|
||||||
PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
|
PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
|
||||||
int method));
|
int method));
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
||||||
/* Also set zlib parameters for compressing non-IDAT chunks */
|
/* Also set zlib parameters for compressing non-IDAT chunks */
|
||||||
@ -1787,6 +1786,7 @@ PNG_EXPORT(225, void, png_set_text_compression_window_bits,
|
|||||||
PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
|
PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
|
||||||
int method));
|
int method));
|
||||||
#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
|
#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
|
||||||
|
#endif /* WRITE */
|
||||||
|
|
||||||
/* These next functions are called for input/output, memory, and error
|
/* These next functions are called for input/output, memory, and error
|
||||||
* handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
|
* handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
|
||||||
|
@ -345,13 +345,8 @@ struct png_struct_def
|
|||||||
/* This is somewhat excessive, there is no obvious reason on write to
|
/* This is somewhat excessive, there is no obvious reason on write to
|
||||||
* allocate a buffer for each possible filtered row, only for the one being
|
* allocate a buffer for each possible filtered row, only for the one being
|
||||||
* tested and the current best.
|
* tested and the current best.
|
||||||
*
|
|
||||||
* TODO: fix this
|
|
||||||
*/
|
*/
|
||||||
png_bytep sub_row; /* buffer to save "sub" row when filtering */
|
png_bytep try_row; /* buffer to save trial row when filtering */
|
||||||
png_bytep up_row; /* buffer to save "up" row when filtering */
|
|
||||||
png_bytep avg_row; /* buffer to save "avg" row when filtering */
|
|
||||||
png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* UNKNOWN CHUNK HANDLING */
|
/* UNKNOWN CHUNK HANDLING */
|
||||||
|
14
pngwrite.c
14
pngwrite.c
@ -942,15 +942,9 @@ png_write_destroy(png_structrp png_ptr)
|
|||||||
png_ptr->row_buf = NULL;
|
png_ptr->row_buf = NULL;
|
||||||
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
||||||
png_free(png_ptr, png_ptr->prev_row);
|
png_free(png_ptr, png_ptr->prev_row);
|
||||||
png_free(png_ptr, png_ptr->sub_row);
|
png_free(png_ptr, png_ptr->try_row);
|
||||||
png_free(png_ptr, png_ptr->up_row);
|
|
||||||
png_free(png_ptr, png_ptr->avg_row);
|
|
||||||
png_free(png_ptr, png_ptr->paeth_row);
|
|
||||||
png_ptr->prev_row = NULL;
|
png_ptr->prev_row = NULL;
|
||||||
png_ptr->sub_row = NULL;
|
png_ptr->try_row = NULL;
|
||||||
png_ptr->up_row = NULL;
|
|
||||||
png_ptr->avg_row = NULL;
|
|
||||||
png_ptr->paeth_row = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||||
@ -1065,8 +1059,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
|
|||||||
* it is too late to start using the filters that need it, since we
|
* it is too late to start using the filters that need it, since we
|
||||||
* will be missing the data in the previous row. If an application
|
* will be missing the data in the previous row. If an application
|
||||||
* wants to start and stop using particular filters during compression,
|
* wants to start and stop using particular filters during compression,
|
||||||
* it should start out with all of the filters, and then add and
|
* it should start out with all of the filters, and then remove them
|
||||||
* remove them after the start of compression.
|
* or add them back after the start of compression.
|
||||||
*
|
*
|
||||||
* NOTE: this is a nasty constraint on the code, because it means that the
|
* NOTE: this is a nasty constraint on the code, because it means that the
|
||||||
* prev_row buffer must be maintained even if there are currently no
|
* prev_row buffer must be maintained even if there are currently no
|
||||||
|
278
pngwutil.c
278
pngwutil.c
@ -1943,7 +1943,7 @@ png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
|
|||||||
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
||||||
void /* PRIVATE */
|
void /* PRIVATE */
|
||||||
png_write_alloc_filter_row_buffers(png_structrp png_ptr, int filters)
|
png_write_alloc_filter_row_buffers(png_structrp png_ptr, int filters)
|
||||||
/* Allocate row buffers for any filters that need them, this is also called
|
/* Allocate row buffers for any filters that need them. This is also called
|
||||||
* from png_set_filter if the filters are changed during write to ensure that
|
* from png_set_filter if the filters are changed during write to ensure that
|
||||||
* the required buffers exist. png_set_filter ensures that up/avg/paeth are
|
* the required buffers exist. png_set_filter ensures that up/avg/paeth are
|
||||||
* only set if png_ptr->prev_row is allocated.
|
* only set if png_ptr->prev_row is allocated.
|
||||||
@ -1954,29 +1954,10 @@ png_write_alloc_filter_row_buffers(png_structrp png_ptr, int filters)
|
|||||||
*/
|
*/
|
||||||
png_alloc_size_t buf_size = png_ptr->rowbytes + 1;
|
png_alloc_size_t buf_size = png_ptr->rowbytes + 1;
|
||||||
|
|
||||||
if ((filters & PNG_FILTER_SUB) != 0 && png_ptr->sub_row == NULL)
|
if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG |
|
||||||
|
PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL)
|
||||||
{
|
{
|
||||||
png_ptr->sub_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
|
png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
|
||||||
png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((filters & PNG_FILTER_UP) != 0 && png_ptr->up_row == NULL)
|
|
||||||
{
|
|
||||||
png_ptr->up_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
|
|
||||||
png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((filters & PNG_FILTER_AVG) != 0 && png_ptr->avg_row == NULL)
|
|
||||||
{
|
|
||||||
png_ptr->avg_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
|
|
||||||
png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((filters & PNG_FILTER_PAETH) != 0 && png_ptr->paeth_row == NULL)
|
|
||||||
{
|
|
||||||
png_ptr->paeth_row = png_voidcast(png_bytep, png_malloc(png_ptr,
|
|
||||||
buf_size));
|
|
||||||
png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WRITE_FILTER */
|
#endif /* WRITE_FILTER */
|
||||||
@ -2352,17 +2333,117 @@ static void /* PRIVATE */
|
|||||||
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
|
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
|
||||||
png_size_t row_bytes);
|
png_size_t row_bytes);
|
||||||
|
|
||||||
|
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
||||||
|
static void /* PRIVATE */
|
||||||
|
png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp,
|
||||||
|
png_bytep row_buf, png_size_t row_bytes)
|
||||||
|
{
|
||||||
|
png_bytep rp, dp, lp;
|
||||||
|
png_size_t i;
|
||||||
|
|
||||||
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void /* PRIVATE */
|
||||||
|
png_setup_up_row(png_structrp png_ptr, png_bytep row_buf, png_size_t row_bytes)
|
||||||
|
{
|
||||||
|
png_bytep rp, dp, pp;
|
||||||
|
png_size_t i;
|
||||||
|
|
||||||
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1,
|
||||||
|
pp = png_ptr->prev_row + 1; i < row_bytes;
|
||||||
|
i++, rp++, pp++, dp++)
|
||||||
|
{
|
||||||
|
*dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void /* PRIVATE */
|
||||||
|
png_setup_avg_row(png_structrp png_ptr,png_uint_32 bpp,
|
||||||
|
png_bytep row_buf, png_size_t row_bytes)
|
||||||
|
{
|
||||||
|
png_bytep rp, dp, pp, lp;
|
||||||
|
png_uint_32 i;
|
||||||
|
|
||||||
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1,
|
||||||
|
pp = png_ptr->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void /* PRIVATE */
|
||||||
|
png_setup_paeth_row(png_structrp png_ptr,png_uint_32 bpp,
|
||||||
|
png_bytep row_buf, png_size_t row_bytes)
|
||||||
|
{
|
||||||
|
png_bytep rp, dp, pp, cp, lp;
|
||||||
|
png_size_t i;
|
||||||
|
|
||||||
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1,
|
||||||
|
pp = png_ptr->prev_row + 1; i < bpp; i++)
|
||||||
|
{
|
||||||
|
*dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (lp = 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;
|
||||||
|
|
||||||
|
*dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
|
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
|
||||||
#define PNG_HISHIFT 10
|
#define PNG_HISHIFT 10
|
||||||
#define PNG_LOMASK ((png_uint_32)0xffffL)
|
#define PNG_LOMASK ((png_uint_32)0xffffL)
|
||||||
#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
|
#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
|
||||||
|
#endif /* WRITE_FILTER */
|
||||||
|
|
||||||
void /* PRIVATE */
|
void /* PRIVATE */
|
||||||
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
||||||
{
|
{
|
||||||
png_bytep best_row;
|
#ifndef PNG_WRITE_FILTER_SUPPORTED
|
||||||
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
|
||||||
|
#else
|
||||||
png_bytep prev_row, row_buf;
|
png_bytep prev_row, row_buf;
|
||||||
png_uint_32 mins, bpp;
|
png_uint_32 mins, bpp;
|
||||||
|
png_byte best_filter_value = PNG_FILTER_VALUE_NONE;
|
||||||
|
png_byte last_tested_row_value = PNG_FILTER_VALUE_NONE;
|
||||||
png_byte filter_to_do = png_ptr->do_filter;
|
png_byte filter_to_do = png_ptr->do_filter;
|
||||||
png_size_t row_bytes = row_info->rowbytes;
|
png_size_t row_bytes = row_info->rowbytes;
|
||||||
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||||
@ -2383,10 +2464,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
bpp = (row_info->pixel_depth + 7) >> 3;
|
bpp = (row_info->pixel_depth + 7) >> 3;
|
||||||
|
|
||||||
prev_row = png_ptr->prev_row;
|
prev_row = png_ptr->prev_row;
|
||||||
#endif
|
row_buf = png_ptr->row_buf;
|
||||||
best_row = png_ptr->row_buf;
|
|
||||||
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
|
||||||
row_buf = best_row;
|
|
||||||
mins = PNG_MAXSUM;
|
mins = PNG_MAXSUM;
|
||||||
|
|
||||||
/* The prediction method we use is to find which method provides the
|
/* The prediction method we use is to find which method provides the
|
||||||
@ -2475,22 +2553,10 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
if (filter_to_do == PNG_FILTER_SUB)
|
if (filter_to_do == PNG_FILTER_SUB)
|
||||||
/* It's the only filter so no testing is needed */
|
/* It's the only filter so no testing is needed */
|
||||||
{
|
{
|
||||||
png_bytep rp, lp, dp;
|
png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
|
||||||
png_size_t i;
|
last_tested_row_value = PNG_FILTER_VALUE_SUB;
|
||||||
|
png_setup_sub_row(png_ptr, bpp, row_buf, row_bytes);
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
|
best_filter_value = PNG_FILTER_VALUE_SUB;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((filter_to_do & PNG_FILTER_SUB) != 0)
|
else if ((filter_to_do & PNG_FILTER_SUB) != 0)
|
||||||
@ -2538,7 +2604,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
|
||||||
i++, rp++, dp++)
|
i++, rp++, dp++)
|
||||||
{
|
{
|
||||||
v = *dp = *rp;
|
v = *dp = *rp;
|
||||||
@ -2594,24 +2660,17 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
if (sum < mins)
|
if (sum < mins)
|
||||||
{
|
{
|
||||||
mins = sum;
|
mins = sum;
|
||||||
best_row = png_ptr->sub_row;
|
best_filter_value = PNG_FILTER_VALUE_SUB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Up filter */
|
/* Up filter */
|
||||||
if (filter_to_do == PNG_FILTER_UP)
|
if (filter_to_do == PNG_FILTER_UP)
|
||||||
{
|
{
|
||||||
png_bytep rp, dp, pp;
|
last_tested_row_value = PNG_FILTER_VALUE_UP;
|
||||||
png_size_t i;
|
png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
|
||||||
|
png_setup_up_row(png_ptr, row_buf, row_bytes);
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
|
best_filter_value = PNG_FILTER_VALUE_UP;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((filter_to_do & PNG_FILTER_UP) != 0)
|
else if ((filter_to_do & PNG_FILTER_UP) != 0)
|
||||||
@ -2656,7 +2715,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1,
|
||||||
pp = prev_row + 1; i < row_bytes; i++)
|
pp = prev_row + 1; i < row_bytes; i++)
|
||||||
{
|
{
|
||||||
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
|
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
|
||||||
@ -2704,28 +2763,17 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
if (sum < mins)
|
if (sum < mins)
|
||||||
{
|
{
|
||||||
mins = sum;
|
mins = sum;
|
||||||
best_row = png_ptr->up_row;
|
best_filter_value = PNG_FILTER_VALUE_UP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avg filter */
|
/* Avg filter */
|
||||||
if (filter_to_do == PNG_FILTER_AVG)
|
if (filter_to_do == PNG_FILTER_AVG)
|
||||||
{
|
{
|
||||||
png_bytep rp, dp, pp, lp;
|
last_tested_row_value = PNG_FILTER_VALUE_AVG;
|
||||||
png_uint_32 i;
|
png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
|
||||||
|
png_setup_avg_row(png_ptr, bpp, row_buf, row_bytes);
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
|
best_filter_value = PNG_FILTER_VALUE_AVG;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((filter_to_do & PNG_FILTER_AVG) != 0)
|
else if ((filter_to_do & PNG_FILTER_AVG) != 0)
|
||||||
@ -2769,7 +2817,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1,
|
||||||
pp = prev_row + 1; i < bpp; i++)
|
pp = prev_row + 1; i < bpp; i++)
|
||||||
{
|
{
|
||||||
v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
|
v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
|
||||||
@ -2825,48 +2873,17 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
if (sum < mins)
|
if (sum < mins)
|
||||||
{
|
{
|
||||||
mins = sum;
|
mins = sum;
|
||||||
best_row = png_ptr->avg_row;
|
best_filter_value = PNG_FILTER_VALUE_AVG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paeth filter */
|
/* Paeth filter */
|
||||||
if ((filter_to_do == PNG_FILTER_PAETH) != 0)
|
if ((filter_to_do == PNG_FILTER_PAETH) != 0)
|
||||||
{
|
{
|
||||||
png_bytep rp, dp, pp, cp, lp;
|
last_tested_row_value = PNG_FILTER_VALUE_PAETH;
|
||||||
png_size_t i;
|
png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
|
||||||
|
png_setup_paeth_row(png_ptr, bpp, row_buf, row_bytes);
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
|
best_filter_value = PNG_FILTER_VALUE_PAETH;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
|
else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
|
||||||
@ -2910,7 +2927,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
|
for (i = 0, rp = row_buf + 1, dp = png_ptr->try_row + 1,
|
||||||
pp = prev_row + 1; i < bpp; i++)
|
pp = prev_row + 1; i < bpp; i++)
|
||||||
{
|
{
|
||||||
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
|
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
|
||||||
@ -2999,15 +3016,38 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
|
|
||||||
if (sum < mins)
|
if (sum < mins)
|
||||||
{
|
{
|
||||||
best_row = png_ptr->paeth_row;
|
best_filter_value = PNG_FILTER_VALUE_PAETH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WRITE_FILTER */
|
|
||||||
|
|
||||||
/* Do the actual writing of the filtered row data from the chosen 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);
|
if (best_filter_value == PNG_FILTER_VALUE_NONE)
|
||||||
|
png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
png_ptr->try_row[0] = best_filter_value;
|
||||||
|
|
||||||
|
if (best_filter_value != last_tested_row_value)
|
||||||
|
{
|
||||||
|
/* TO DO: make this redundant code into functions? */
|
||||||
|
if (best_filter_value == PNG_FILTER_VALUE_SUB)
|
||||||
|
png_setup_sub_row(png_ptr, bpp, row_buf, row_bytes);
|
||||||
|
|
||||||
|
if (best_filter_value == PNG_FILTER_VALUE_UP)
|
||||||
|
png_setup_up_row(png_ptr, row_buf, row_bytes);
|
||||||
|
|
||||||
|
if (best_filter_value == PNG_FILTER_VALUE_AVG)
|
||||||
|
png_setup_avg_row(png_ptr, bpp, row_buf, row_bytes);
|
||||||
|
|
||||||
|
if (best_filter_value == PNG_FILTER_VALUE_PAETH)
|
||||||
|
png_setup_paeth_row(png_ptr, bpp, row_buf, row_bytes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
png_write_filtered_row(png_ptr, png_ptr->try_row, row_info->rowbytes+1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
|
||||||
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
||||||
/* Save the type of filter we picked this time for future calculations */
|
/* Save the type of filter we picked this time for future calculations */
|
||||||
if (png_ptr->num_prev_filters > 0)
|
if (png_ptr->num_prev_filters > 0)
|
||||||
@ -3019,9 +3059,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
|
|||||||
png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
|
png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
png_ptr->prev_filters[j] = best_row[0];
|
png_ptr->prev_filters[j] = best_filter_value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* WRITE_WEIGHTED_FILTER */
|
||||||
#endif /* WRITE_FILTER */
|
#endif /* WRITE_FILTER */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user