diff options
author | John Bowler <jbowler@acm.org> | 2011-06-17 21:36:09 -0500 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2011-06-17 21:36:09 -0500 |
commit | 484a48e22193403cfaab4e9b731955facbc5da8e (patch) | |
tree | 5ccf7da375a48a9ecaaa9f9ec6477f401192b9b6 /pngrtran.c | |
parent | cc5226bf2a93b2216db4d64a78503f7b449ee3b1 (diff) | |
download | libpng-484a48e22193403cfaab4e9b731955facbc5da8e.tar.gz |
[master] Fixed error in "ACCURATE" 16-to-8 scaling.
Diffstat (limited to 'pngrtran.c')
-rw-r--r-- | pngrtran.c | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/pngrtran.c b/pngrtran.c index 0a3874718..79a7cd6b3 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.4.8 [June 8, 2011] + * Last changed in libpng 1.4.8 [June 18, 2011] * Copyright (c) 1998-2011 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.) @@ -1799,32 +1799,18 @@ png_do_chop(png_row_infop row_info, png_bytep row) for (i = 0; i<istop; i++, sp += 2, dp++) { #ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED - /* This does a more accurate scaling of the 16-bit color - * value, rather than a simple low-byte truncation. - * - * What the ideal calculation should be: - * *dp = (((((png_uint_32)(*sp) << 8) | - * (png_uint_32)(*(sp + 1))) * 255 + 127) - * / (png_uint_32)65535L; - * - * GRR: no, I think this is what it really should be: - * *dp = (((((png_uint_32)(*sp) << 8) | - * (png_uint_32)(*(sp + 1))) + 128L) - * / (png_uint_32)257L; - * - * GRR: here's the exact calculation with shifts: - * temp = (((png_uint_32)(*sp) << 8) | - * (png_uint_32)(*(sp + 1))) + 128L; - * *dp = (temp - (temp >> 8)) >> 8; - * - * Approximate calculation with shift/add instead of multiply/divide: - * *dp = ((((png_uint_32)(*sp) << 8) | - * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8; - * - * What we actually do to avoid extra shifting and conversion: - */ - - *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0); + /* This does a more accurate scaling of the 16-bit color + * value, rather than a simple low-byte truncation. + * + * Prior to libpng-1.4.8 and 1.5.4, the calculation here was + * incorrect, so if you used ACCURATE_SCALE you will now see + * a slightly different result. In libpng-1.5.4 and + * later you will need to use the new png_set_scale_16_to_8() + * API to obtain accurate 16-to-8 scaling. + */ + png_int_32 tmp = *sp++; /* must be signed! */ + tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; + *dp++ = (png_byte)tmp; #else /* Simply discard the low order byte */ *dp = *sp; |