diff --git a/ANNOUNCE b/ANNOUNCE index dc5d53599..1521c1ba1 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -299,7 +299,6 @@ version 1.5.0beta36 [July 29, 2010] pass. A new test program, pngvalid.c, validates the gamma code. Errors in the 16 bit gamma correction (overflows) have been corrected. - Gamma handling arithmetic is in a new file, pngarith.c cHRM chunk testing is done consistently (previously the floating point API bypassed it, because the test really didn't work on FP, now the test is performed on the actual values to be stored in the PNG file so it diff --git a/CHANGES b/CHANGES index 6a0c01b8e..8b529576b 100644 --- a/CHANGES +++ b/CHANGES @@ -2770,7 +2770,7 @@ version 1.5.0beta35 [July 24, 2010] #ifdef blocks in pngconf.h version 1.5.0beta36 [July 29, 2010] - Patches by John Bowler: + Patches by John Bowler: Fixed point APIs are now supported throughout (no missing APIs). Internal fixed point arithmetic support exists for all internal floating point operations. @@ -2781,7 +2781,6 @@ version 1.5.0beta36 [July 29, 2010] pass. A new test program, pngvalid.c, validates the gamma code. Errors in the 16 bit gamma correction (overflows) have been corrected. - Gamma handling arithmetic is in a new file, pngarith.c cHRM chunk testing is done consistently (previously the floating point API bypassed it, because the test really didn't work on FP, now the test is performed on the actual values to be stored in the PNG file so it diff --git a/png.c b/png.c index 8993842a1..8425ff3b2 100644 --- a/png.c +++ b/png.c @@ -888,7 +888,6 @@ png_check_IHDR(png_structp png_ptr, if (error == 1) png_error(png_ptr, "Invalid IHDR data"); } -#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) /* ASCII to fp functions */ @@ -918,16 +917,16 @@ png_check_fp_number(png_charp string, png_size_t size, int *statep, int type; /* First find the type of the next character */ { - char ch = string[i]; - if (ch >= 48 && ch <= 57) - type = PNG_FP_DIGIT; - else switch (ch) - { - case 43: case 45: type = PNG_FP_SIGN; break; - case 46: type = PNG_FP_DOT; break; - case 69: case 101: type = PNG_FP_E; break; - default: goto PNG_FP_End; - } + char ch = string[i]; + if (ch >= 48 && ch <= 57) + type = PNG_FP_DIGIT; + else switch (ch) + { + case 43: case 45: type = PNG_FP_SIGN; break; + case 46: type = PNG_FP_DOT; break; + case 69: case 101: type = PNG_FP_E; break; + default: goto PNG_FP_End; + } } /* Now deal with this type according to the current @@ -937,57 +936,57 @@ png_check_fp_number(png_charp string, png_size_t size, int *statep, switch ((state & PNG_FP_STATE) + type) { case PNG_FP_INTEGER + PNG_FP_SIGN: - if (state & PNG_FP_SAW_ANY) - goto PNG_FP_End; /* not a part of the number */ - png_fp_add(state, PNG_FP_SAW_SIGN); - break; + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + png_fp_add(state, PNG_FP_SAW_SIGN); + break; case PNG_FP_INTEGER + PNG_FP_DOT: - /* Ok as trailer, ok as lead of fraction. */ - if (state & PNG_FP_SAW_DOT) /* two dots */ - goto PNG_FP_End; - else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ - png_fp_add(state, PNG_FP_SAW_DOT); - else - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - break; + /* Ok as trailer, ok as lead of fraction. */ + if (state & PNG_FP_SAW_DOT) /* two dots */ + goto PNG_FP_End; + else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ + png_fp_add(state, PNG_FP_SAW_DOT); + else + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + break; case PNG_FP_INTEGER + PNG_FP_DIGIT: - if (state & PNG_FP_SAW_DOT) /* delayed fraction */ - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); - break; + if (state & PNG_FP_SAW_DOT) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; case PNG_FP_INTEGER + PNG_FP_E: - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - png_fp_set(state, PNG_FP_EXPONENT); - break; + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + png_fp_set(state, PNG_FP_EXPONENT); + break; /* case PNG_FP_FRACTION + PNG_FP_SIGN: - goto PNG_FP_End; ** no sign in exponent */ + goto PNG_FP_End; ** no sign in exponent */ /* case PNG_FP_FRACTION + PNG_FP_DOT: - goto PNG_FP_End; ** Because SAW_DOT is always set */ + goto PNG_FP_End; ** Because SAW_DOT is always set */ case PNG_FP_FRACTION + PNG_FP_DIGIT: - png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); - break; + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; case PNG_FP_FRACTION + PNG_FP_E: - /* This is correct because the trailing '.' on an - * integer is handled above - so we can only get here - * with the sequence ".E" (with no preceding digits). - */ - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - png_fp_set(state, PNG_FP_EXPONENT); - break; + /* This is correct because the trailing '.' on an + * integer is handled above - so we can only get here + * with the sequence ".E" (with no preceding digits). + */ + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + png_fp_set(state, PNG_FP_EXPONENT); + break; case PNG_FP_EXPONENT + PNG_FP_SIGN: - if (state & PNG_FP_SAW_ANY) - goto PNG_FP_End; /* not a part of the number */ - png_fp_add(state, PNG_FP_SAW_SIGN); - break; + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + png_fp_add(state, PNG_FP_SAW_SIGN); + break; /* case PNG_FP_EXPONENT + PNG_FP_DOT: - goto PNG_FP_End; */ + goto PNG_FP_End; */ case PNG_FP_EXPONENT + PNG_FP_DIGIT: - png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); - break; + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; /* case PNG_FP_EXPONEXT + PNG_FP_E: - goto PNG_FP_End; */ + goto PNG_FP_End; */ default: goto PNG_FP_End; /* I.e. break 2 */ } @@ -1040,8 +1039,8 @@ png_pow10(int power) do { if (power & 1) d *= mult; - mult *= mult; - power >>= 1; + mult *= mult; + power >>= 1; } while (power > 0); @@ -1077,258 +1076,258 @@ png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, if (fp < 0) { fp = -fp; - *ascii++ = 45; /* '-' PLUS 1 TOTAL 1*/ - --size; + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1*/ + --size; } if (fp >= DBL_MIN && fp <= DBL_MAX) { - int exp; /* A base 10 exponent */ - double base; /* 10^exp */ + int exp; /* A base 10 exponent */ + double base; /* 10^exp */ - /* First extract a base 10 exponent of the number, - * the calculation below rounds down when converting - * from base 2 to base 10 (multiply by log10(2) - - * 0.3010, but 77/256 is 0.3008, so exp needs to - * be increased. Note that the arithmetic shift - * performs a floor() unlike C arithmetic - using a - * C multiply would break the following for negative - * exponents. - */ - (void)frexp(fp, &exp); /* exponent to base 2 */ - exp = (exp * 77) >> 8; /* <= exponent to base 10 */ - /* Avoid underflow here. */ - base = png_pow10(exp); /* May underflow */ - while (base < DBL_MIN || base < fp) - { - /* And this may overflow. */ - double test = png_pow10(exp+1); - if (test <= DBL_MAX) - ++exp, base = test; - else - break; - } + /* First extract a base 10 exponent of the number, + * the calculation below rounds down when converting + * from base 2 to base 10 (multiply by log10(2) - + * 0.3010, but 77/256 is 0.3008, so exp needs to + * be increased. Note that the arithmetic shift + * performs a floor() unlike C arithmetic - using a + * C multiply would break the following for negative + * exponents. + */ + (void)frexp(fp, &exp); /* exponent to base 2 */ + exp = (exp * 77) >> 8; /* <= exponent to base 10 */ + /* Avoid underflow here. */ + base = png_pow10(exp); /* May underflow */ + while (base < DBL_MIN || base < fp) + { + /* And this may overflow. */ + double test = png_pow10(exp+1); + if (test <= DBL_MAX) + ++exp, base = test; + else + break; + } - /* Normalize fp and correct exp, after this fp is in the - * range [.1,1) and exp is both the exponent and the digit - * *before* which the decimal point should be inserted - * (starting with 0 for the first digit). Note that this - * works even if 10^exp is out of range because of the - * test on DBL_MAX above. - */ - fp /= base; - while (fp >= 1) fp /= 10, ++exp; + /* Normalize fp and correct exp, after this fp is in the + * range [.1,1) and exp is both the exponent and the digit + * *before* which the decimal point should be inserted + * (starting with 0 for the first digit). Note that this + * works even if 10^exp is out of range because of the + * test on DBL_MAX above. + */ + fp /= base; + while (fp >= 1) fp /= 10, ++exp; - /* Because of the code above fp may, at this point, be - * less than .1, this is ok because the code below can - * handle the leading zeros this generates, so no attempt - * is made to correct that here. - */ + /* Because of the code above fp may, at this point, be + * less than .1, this is ok because the code below can + * handle the leading zeros this generates, so no attempt + * is made to correct that here. + */ - { - int czero, clead, cdigits; - char exponent[10]; + { + int czero, clead, cdigits; + char exponent[10]; - /* Allow up to two leading zeros - this will not lengthen - * the number compared to using E-n. - */ - if (exp < 0 && exp > -3) /* PLUS 3 TOTAL 4 */ - { - czero = -exp; /* PLUS 2 digits: TOTAL 3 */ - exp = 0; /* Dot added below before first output. */ - } - else - czero = 0; /* No zeros to add */ + /* Allow up to two leading zeros - this will not lengthen + * the number compared to using E-n. + */ + if (exp < 0 && exp > -3) /* PLUS 3 TOTAL 4 */ + { + czero = -exp; /* PLUS 2 digits: TOTAL 3 */ + exp = 0; /* Dot added below before first output. */ + } + else + czero = 0; /* No zeros to add */ - /* Generate the digit list, stripping trailing zeros and - * inserting a '.' before a digit if the exponent is 0. - */ - clead = czero; /* Count of leading zeros */ - cdigits = 0; /* Count of digits in list. */ - do - { - double d; + /* Generate the digit list, stripping trailing zeros and + * inserting a '.' before a digit if the exponent is 0. + */ + clead = czero; /* Count of leading zeros */ + cdigits = 0; /* Count of digits in list. */ + do + { + double d; - fp *= 10; - /* Use modf here, not floor and subtract, so that - * the separation is done in one step. At the end - * of the loop don't break the number into parts so - * that the final digit is rounded. - */ - if (cdigits+czero-clead+1 < (int)precision) - fp = modf(fp, &d); - else - { - /* End of loop - round the whole number. */ - d = floor(fp + .5); + fp *= 10; + /* Use modf here, not floor and subtract, so that + * the separation is done in one step. At the end + * of the loop don't break the number into parts so + * that the final digit is rounded. + */ + if (cdigits+czero-clead+1 < (int)precision) + fp = modf(fp, &d); + else + { + /* End of loop - round the whole number. */ + d = floor(fp + .5); - if (d > 9) - { - /* Rounding up to 10, handle that here. */ - if (czero > 0) - { - --czero, d = 1; - if (cdigits == 0) --clead; + if (d > 9) + { + /* Rounding up to 10, handle that here. */ + if (czero > 0) + { + --czero, d = 1; + if (cdigits == 0) --clead; } - else - { - while (cdigits > 0 && d > 9) - { - int ch = *--ascii; - if (exp != (-1)) - ++exp; - else if (ch == 46) - { - ch = *--ascii, ++size; - /* Advance exp to '1', so that the - * decimal point happens after the - * previous digit. - */ - exp = 1; - } + else + { + while (cdigits > 0 && d > 9) + { + int ch = *--ascii; + if (exp != (-1)) + ++exp; + else if (ch == 46) + { + ch = *--ascii, ++size; + /* Advance exp to '1', so that the + * decimal point happens after the + * previous digit. + */ + exp = 1; + } - --cdigits; - d = ch - 47; /* I.e. 1+(ch-48) */ - } + --cdigits; + d = ch - 47; /* I.e. 1+(ch-48) */ + } - /* Did we reach the beginning? If so adjust the - * exponent but take into account the leading - * decimal point. - */ - if (d > 9) /* cdigits == 0 */ - { - if (exp == (-1)) - { - /* Leading decimal point (plus zeros?), if - * we lose the decimal point here it must - * be reentered below. - */ - int ch = *--ascii; - if (ch == 46) - ++size, exp = 1; - /* Else lost a leading zero, so 'exp' is - * still ok at (-1) - */ - } - else - ++exp; + /* Did we reach the beginning? If so adjust the + * exponent but take into account the leading + * decimal point. + */ + if (d > 9) /* cdigits == 0 */ + { + if (exp == (-1)) + { + /* Leading decimal point (plus zeros?), if + * we lose the decimal point here it must + * be reentered below. + */ + int ch = *--ascii; + if (ch == 46) + ++size, exp = 1; + /* Else lost a leading zero, so 'exp' is + * still ok at (-1) + */ + } + else + ++exp; - /* In all cases we output a '1' */ - d = 1; - } - } - } - fp = 0; /* Guarantees termination below. */ - } + /* In all cases we output a '1' */ + d = 1; + } + } + } + fp = 0; /* Guarantees termination below. */ + } - if (d == 0) - { - ++czero; - if (cdigits == 0) ++clead; - } - else - { - /* Included embedded zeros in the digit count. */ - cdigits += czero - clead; - clead = 0; + if (d == 0) + { + ++czero; + if (cdigits == 0) ++clead; + } + else + { + /* Included embedded zeros in the digit count. */ + cdigits += czero - clead; + clead = 0; - while (czero > 0) - { - /* exp == (-1) means we just output the decimal - * place - after the DP don't adjust 'exp' any - * more! - */ - if (exp != (-1)) - { - if (exp == 0) *ascii++ = 46, --size; - /* PLUS 1: TOTAL 4 */ - --exp; - } - *ascii++ = 48, --czero; - } + while (czero > 0) + { + /* exp == (-1) means we just output the decimal + * place - after the DP don't adjust 'exp' any + * more! + */ + if (exp != (-1)) + { + if (exp == 0) *ascii++ = 46, --size; + /* PLUS 1: TOTAL 4 */ + --exp; + } + *ascii++ = 48, --czero; + } - if (exp != (-1)) - { - if (exp == 0) *ascii++ = 46, --size; /* counted above */ - --exp; - } - *ascii++ = 48 + (int)d, ++cdigits; - } - } - while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); + if (exp != (-1)) + { + if (exp == 0) *ascii++ = 46, --size; /* counted above */ + --exp; + } + *ascii++ = 48 + (int)d, ++cdigits; + } + } + while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); - /* The total output count (max) is now 4+precision */ + /* The total output count (max) is now 4+precision */ - /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At - * this point exp==(-1) is effectively if flag - it got - * to '-1' because of the decrement after outputing - * the decimal point above (the exponent required is - * *not* -1!) - */ - if (exp >= (-1) && exp <= 2) - { - /* The following only happens if we didn't output the - * leading zeros above for negative exponent, so this - * doest add to the digit requirement. Note that the - * two zeros here can only be output if the two leading - * zeros were *not* output, so this doesn't increase - * the output count. - */ - while (--exp >= 0) *ascii++ = 48; - *ascii = 0; - /* Total buffer requirement (including the '\0') is - * 5+precision - see check at the start. - */ - return; - } + /* Check for an exponent, if we don't need one we are + * done and just need to terminate the string. At + * this point exp==(-1) is effectively if flag - it got + * to '-1' because of the decrement after outputing + * the decimal point above (the exponent required is + * *not* -1!) + */ + if (exp >= (-1) && exp <= 2) + { + /* The following only happens if we didn't output the + * leading zeros above for negative exponent, so this + * doest add to the digit requirement. Note that the + * two zeros here can only be output if the two leading + * zeros were *not* output, so this doesn't increase + * the output count. + */ + while (--exp >= 0) *ascii++ = 48; + *ascii = 0; + /* Total buffer requirement (including the '\0') is + * 5+precision - see check at the start. + */ + return; + } - /* Here if an exponent is required, adjust size for - * the digits we output but did not count. The total - * digit output here so far is at most 1+precision - no - * decimal point and no leading or trailing zeros have - * been output. - */ - size -= cdigits; + /* Here if an exponent is required, adjust size for + * the digits we output but did not count. The total + * digit output here so far is at most 1+precision - no + * decimal point and no leading or trailing zeros have + * been output. + */ + size -= cdigits; - *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision*/ - if (exp < 0) - { - *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ - exp = -exp; - } + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision*/ + if (exp < 0) + { + *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ + exp = -exp; + } - cdigits = 0; - while (exp > 0) - { - exponent[cdigits++] = 48 + exp % 10; - exp /= 10; - } + cdigits = 0; + while (exp > 0) + { + exponent[cdigits++] = 48 + exp % 10; + exp /= 10; + } - /* Need another size check here for the exponent digits, so - * this need not be considered above. - */ - if ((int)size > cdigits) - { - while (cdigits > 0) *ascii++ = exponent[--cdigits]; - *ascii = 0; - return; - } - } + /* Need another size check here for the exponent digits, so + * this need not be considered above. + */ + if ((int)size > cdigits) + { + while (cdigits > 0) *ascii++ = exponent[--cdigits]; + *ascii = 0; + return; + } + } } else if (!(fp >= DBL_MIN)) { *ascii++ = 48; /* '0' */ - *ascii = 0; - return; + *ascii = 0; + return; } else { *ascii++ = 105; /* 'i' */ - *ascii++ = 110; /* 'n' */ - *ascii++ = 102; /* 'f' */ - *ascii = 0; - return; + *ascii++ = 110; /* 'n' */ + *ascii++ = 102; /* 'f' */ + *ascii = 0; + return; } } @@ -1369,82 +1368,82 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, { if (a == 0 || times == 0) { - *res = 0; + *res = 0; return 1; } else { #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a; - r *= times; - r /= div; - r = floor(r+.5); - /* A png_fixed_point is a 32 bit integer. */ - if (r <= 2147483647. && r >= -2147483648.) - { - *res = (png_fixed_point)r; - return 1; - } + double r = a; + r *= times; + r /= div; + r = floor(r+.5); + /* A png_fixed_point is a 32 bit integer. */ + if (r <= 2147483647. && r >= -2147483648.) + { + *res = (png_fixed_point)r; + return 1; + } #else - int negative = 0; - png_uint_32 A, T, D; - if (a < 0) negative = 1, A = -a; else A = a; - if (times < 0) negative = !negative, T = -times; else T = times; - if (div < 0) negative = !negative, D = -div; else D = div; + int negative = 0; + png_uint_32 A, T, D; + if (a < 0) negative = 1, A = -a; else A = a; + if (times < 0) negative = !negative, T = -times; else T = times; + if (div < 0) negative = !negative, D = -div; else D = div; - /* Following can't overflow because the arguments only - * have 31 bits each, however the result may be 32 bits. - */ - png_uint_32 s16 = (A >> 16) * (T & 0xffff) + - (A & 0xffff) * (T >> 16); - /* Can't overflow because the a*times bit is only 30 - * bits at most. - */ - png_uint_32 s32 = (A >> 16) * (T >> 16) + (s16 >> 16); - png_uint_32 s00 = (A & 0xffff) * (T & 0xffff); + /* Following can't overflow because the arguments only + * have 31 bits each, however the result may be 32 bits. + */ + png_uint_32 s16 = (A >> 16) * (T & 0xffff) + + (A & 0xffff) * (T >> 16); + /* Can't overflow because the a*times bit is only 30 + * bits at most. + */ + png_uint_32 s32 = (A >> 16) * (T >> 16) + (s16 >> 16); + png_uint_32 s00 = (A & 0xffff) * (T & 0xffff); - s16 = (s16 & 0xffff) << 16; - s00 += s16; - if (s00 < s16) ++s32; /* carry */ + s16 = (s16 & 0xffff) << 16; + s00 += s16; + if (s00 < s16) ++s32; /* carry */ - if (s32 < D) /* else overflow */ - { - /* s32.s00 is now the 64 bit product, do a standard - * division, we know that s32 < D, so the maximum - * required shift is 31. - */ - int bitshift = 32; - png_fixed_point result = 0; /* NOTE: signed */ + if (s32 < D) /* else overflow */ + { + /* s32.s00 is now the 64 bit product, do a standard + * division, we know that s32 < D, so the maximum + * required shift is 31. + */ + int bitshift = 32; + png_fixed_point result = 0; /* NOTE: signed */ - while (--bitshift >= 0) - { - png_uint_32 d32, d00; - if (bitshift > 0) - d32 = D >> (32-bitshift), d00 = D << bitshift; - else - d32 = 0, d00 = D; + while (--bitshift >= 0) + { + png_uint_32 d32, d00; + if (bitshift > 0) + d32 = D >> (32-bitshift), d00 = D << bitshift; + else + d32 = 0, d00 = D; - if (s32 > d32) - { - if (s00 < d00) --s32; /* carry */ - s32 -= d32, s00 -= d00, result += 1<= d00) - s32 = 0, s00 -= d00, result += 1< d32) + { + if (s00 < d00) --s32; /* carry */ + s32 -= d32, s00 -= d00, result += 1<= d00) + s32 = 0, s00 -= d00, result += 1<= (D >> 1)) ++result; + /* Handle the rounding. */ + if (s00 >= (D >> 1)) ++result; - if (negative) result = -result; + if (negative) result = -result; - /* Check for overflow. */ - if (negative && result <= 0 || !negative && result >= 0) - { - *res = result; - return 1; - } - } + /* Check for overflow. */ + if (negative && result <= 0 || !negative && result >= 0) + { + *res = result; + return 1; + } + } #endif } } @@ -1837,12 +1836,12 @@ png_gamma_8bit_correct(unsigned value, png_fixed_point gamma) if (value > 0 && value < 255) { # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - return (png_byte)floor(255*pow(value/255.,gamma*.00001)+.5); + return (png_byte)floor(255*pow(value/255.,gamma*.00001)+.5); # else - png_uint_32 log = png_log8bit(value); - png_fixed_point res; - if (png_muldiv(&res, gamma, log, PNG_FP_1)) - return png_exp8bit(res); + png_uint_32 log = png_log8bit(value); + png_fixed_point res; + if (png_muldiv(&res, gamma, log, PNG_FP_1)) + return png_exp8bit(res); # endif /* Overflow. */ @@ -1858,12 +1857,12 @@ png_gamma_16bit_correct(unsigned value, png_fixed_point gamma) if (value > 0 && value < 65535) { # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - return (png_uint_16)floor(65535*pow(value/65535.,gamma*.00001)+.5); + return (png_uint_16)floor(65535*pow(value/65535.,gamma*.00001)+.5); # else - png_uint_32 log = png_log16bit(value); - png_fixed_point res; - if (png_muldiv(&res, gamma, log, PNG_FP_1)) - return png_exp16bit(res); + png_uint_32 log = png_log16bit(value); + png_fixed_point res; + if (png_muldiv(&res, gamma, log, PNG_FP_1)) + return png_exp16bit(res); # endif /* Overflow. */ @@ -1928,40 +1927,40 @@ png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, */ if (png_gamma_significant(gamma)) { - /* The old code would overflow at the end and this would cause the - * 'pow' function to return a result >1, resulting in an - * arithmetic error. This code follows the spec exactly; ig is - * the recovered input sample, it always has 8-16 bits. - * - * We want input * 65535/max, rounded, the arithmetic fits in 32 - * bits (unsigned) so long as max <= 32767. - */ - unsigned j; - for (j = 0; j < 256; j++) - { - png_uint_16 ig = (j << (8-shift)) + i; + /* The old code would overflow at the end and this would cause the + * 'pow' function to return a result >1, resulting in an + * arithmetic error. This code follows the spec exactly; ig is + * the recovered input sample, it always has 8-16 bits. + * + * We want input * 65535/max, rounded, the arithmetic fits in 32 + * bits (unsigned) so long as max <= 32767. + */ + unsigned j; + for (j = 0; j < 256; j++) + { + png_uint_16 ig = (j << (8-shift)) + i; # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Inline the 'max' scaling operation: */ - sub_table[j] = (png_uint_16)floor(65535*pow(ig/(double)max, - gamma*.00001)+.5); + /* Inline the 'max' scaling operation: */ + sub_table[j] = (png_uint_16)floor(65535*pow(ig/(double)max, + gamma*.00001)+.5); # else - if (shift) - ig = (ig * 65535U + max_by_2)/max; - sub_table[j] = png_gamma_16bit_correct(ig, gamma); + if (shift) + ig = (ig * 65535U + max_by_2)/max; + sub_table[j] = png_gamma_16bit_correct(ig, gamma); # endif - } + } } else { /* We must still build a table, but do it the fast way. */ - unsigned j; - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; - if (shift) - ig = (ig * 65535U + max_by_2)/max; - sub_table[j] = ig; - } + unsigned j; + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; + if (shift) + ig = (ig * 65535U + max_by_2)/max; + sub_table[j] = ig; + } } } } @@ -2017,8 +2016,8 @@ png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, while (last <= bound) { - table[last & (0xffU >> shift)][last >> (8U - shift)] = out; - last++; + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; + last++; } } @@ -2061,18 +2060,18 @@ png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) { png_build_8bit_table(png_ptr, &png_ptr->gamma_table, png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, - png_ptr->screen_gamma) : PNG_FP_1); + png_ptr->screen_gamma) : PNG_FP_1); #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) { png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->gamma)); + png_reciprocal(png_ptr->gamma)); png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->gamma/* Probably doing rgb_to_gray */); + png_ptr->gamma/* Probably doing rgb_to_gray */); } #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ } @@ -2118,10 +2117,10 @@ png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) if (png_ptr->transformations & PNG_16_TO_8) { - /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively - * the significant bits in the *input* when the output will - * eventually be 8 bits. By default it is 11. - */ + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will + * eventually be 8 bits. By default it is 11. + */ if (shift < (16U - PNG_MAX_GAMMA_8)) shift = (16U - PNG_MAX_GAMMA_8); } @@ -2132,25 +2131,25 @@ png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) png_ptr->gamma_shift = shift; if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, - png_ptr->screen_gamma) : PNG_FP_1); + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, - png_ptr->screen_gamma) : PNG_FP_1); + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->gamma)); + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + png_reciprocal(png_ptr->gamma)); - /* Notice that the '16 from 1' table should be full precision, however - * the lookup on this table still uses gamma_shift, os it can't be. - * TODO: fix this. - */ + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, os it can't be. + * TODO: fix this. + */ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : png_ptr->gamma/* Probably doing rgb_to_gray */); @@ -2159,3 +2158,4 @@ png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) } } #endif /* READ_GAMMA */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/pngread.c b/pngread.c index 2e18f4fcb..5ef250634 100644 --- a/pngread.c +++ b/pngread.c @@ -866,14 +866,14 @@ png_read_image(png_structp png_ptr, png_bytepp image) { if (!(png_ptr->transformations & PNG_INTERLACE)) { - /* Caller called png_start_read_image or png_read_update_info without - * first turning on the PNG_INTERLACE transform. We can fix this here, - * but the caller should do it! - */ - png_warning(png_ptr, "Interlace handling should be turned on when " - "using png_read_image"); - /* Make sure this is set correctly */ - png_ptr->num_rows = png_ptr->height; + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, + * but the caller should do it! + */ + png_warning(png_ptr, "Interlace handling should be turned on when " + "using png_read_image"); + /* Make sure this is set correctly */ + png_ptr->num_rows = png_ptr->height; } /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in diff --git a/pngrtran.c b/pngrtran.c index f9b506e94..6fe7399cf 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -917,7 +917,7 @@ png_init_read_transformations(png_structp png_ptr) istop=(int)png_ptr->num_trans; for (i=0; itrans_alpha[i] = (png_byte)(255 - - png_ptr->trans_alpha[i]); + png_ptr->trans_alpha[i]); } } #endif @@ -985,21 +985,21 @@ png_init_read_transformations(png_structp png_ptr) case PNG_BACKGROUND_GAMMA_FILE: g = png_reciprocal(png_ptr->gamma); gs = png_reciprocal2(png_ptr->gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: g = png_reciprocal(png_ptr->background_gamma); gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); break; default: g = PNG_FP_1; /* back_1 */ gs = PNG_FP_1; /* back */ - break; + break; } - if ( png_gamma_significant(gs) ) + if ( png_gamma_significant(gs) ) { back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; @@ -1067,8 +1067,8 @@ png_init_read_transformations(png_structp png_ptr) else /* color_type != PNG_COLOR_TYPE_PALETTE */ { - png_fixed_point g = PNG_FP_1; - png_fixed_point gs = PNG_FP_1; + png_fixed_point g = PNG_FP_1; + png_fixed_point gs = PNG_FP_1; switch (png_ptr->background_gamma_type) { @@ -1085,12 +1085,12 @@ png_init_read_transformations(png_structp png_ptr) case PNG_BACKGROUND_GAMMA_UNIQUE: g = png_reciprocal(png_ptr->background_gamma); gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); + png_ptr->screen_gamma); break; } png_ptr->background_1.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, g); + png_ptr->background.gray, g); png_ptr->background.gray = png_gamma_correct(png_ptr, png_ptr->background.gray, gs); diff --git a/pngrutil.c b/pngrutil.c index 85ad57598..3ae466f59 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -992,10 +992,10 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) { - png_warning(png_ptr, - "Ignoring incorrect gAMA value when sRGB is also present"); + png_warning(png_ptr, + "Ignoring incorrect gAMA value when sRGB is also present"); #ifdef PNG_CONSOLE_IO_SUPPORTED - fprintf(stderr, "incorrect gamma=(%d/100000)\n", info_ptr->gamma); + fprintf(stderr, "incorrect gamma=(%d/100000)\n", info_ptr->gamma); #endif } } @@ -1889,12 +1889,12 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_size_t heighti = index; if (png_ptr->chunkdata[index] == 45 /* negative height */ || !png_check_fp_number(png_ptr->chunkdata, slength, &state, &index) || - index != slength) - png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); + index != slength) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); else - /* This is the (only) success case. */ - png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], - png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], + png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); } /* Clean up - just free the temporarily allocated buffer. */ @@ -3476,10 +3476,10 @@ png_get_num_rows(png_structp png_ptr) if (png_ptr != NULL) { if (png_ptr->flags & PNG_FLAG_ROW_INIT) - return png_ptr->num_rows; + return png_ptr->num_rows; else - png_error(png_ptr, "Call png_start_read_image or png_read_update_info " - "before png_get_num_rows"); + png_error(png_ptr, "Call png_start_read_image or png_read_update_info " + "before png_get_num_rows"); } /* Here on error */ diff --git a/pngvalid.c b/pngvalid.c index 5070e0ae1..43358cb3f 100644 --- a/pngvalid.c +++ b/pngvalid.c @@ -281,7 +281,7 @@ sucker_message(png_structp pp, char *buffer, size_t bufsize, const char *msg) if (ps->current != NULL) { pos = safecat(buffer, bufsize, pos, ps->current->name); - pos = safecat(buffer, bufsize, pos, sep); + pos = safecat(buffer, bufsize, pos, sep); } } else if (pp == ps->pwrite) @@ -390,8 +390,8 @@ sucker_read_buffer_next(png_sucker *ps) if (pbNew != NULL) { ps->next = pbNew; - ps->readpos = 0; - return 1; + ps->readpos = 0; + return 1; } png_error(ps->pread, "buffer lost"); @@ -413,10 +413,10 @@ sucker_read(png_structp pp, png_bytep pb, png_size_t st) if (cbAvail > 0) { if (cbAvail > st) cbAvail = st; - memcpy(pb, ps->next->buffer + ps->readpos, cbAvail); - st -= cbAvail; - pb += cbAvail; - ps->readpos += cbAvail; + memcpy(pb, ps->next->buffer + ps->readpos, cbAvail); + st -= cbAvail; + pb += cbAvail; + ps->readpos += cbAvail; } else if (!sucker_read_buffer_next(ps)) png_error(pp, "read beyond end of file"); @@ -492,9 +492,9 @@ sucker_read_set(png_sucker *ps, png_uint_32 id) if (pf->id == id) { ps->current = pf; - ps->next = NULL; - sucker_read_buffer_next(ps); - return; + ps->next = NULL; + sucker_read_buffer_next(ps); + return; } pf = pf->next; @@ -761,174 +761,174 @@ modifier_read(png_structp pp, png_bytep pb, png_size_t st) static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; case modifier_start: sucker_read(pp, pm->buffer, 8); /* size of signature. */ - pm->buffer_count = 8; - pm->buffer_position = 0; + pm->buffer_count = 8; + pm->buffer_position = 0; - if (memcmp(pm->buffer, sign, 8) != 0) - png_error(pp, "invalid PNG file signature"); - pm->state = modifier_signature; - break; + if (memcmp(pm->buffer, sign, 8) != 0) + png_error(pp, "invalid PNG file signature"); + pm->state = modifier_signature; + break; case modifier_signature: - sucker_read(pp, pm->buffer, 13+12); /* size of IHDR */ - pm->buffer_count = 13+12; - pm->buffer_position = 0; + sucker_read(pp, pm->buffer, 13+12); /* size of IHDR */ + pm->buffer_count = 13+12; + pm->buffer_position = 0; - if (png_get_uint_32(pm->buffer) != 13 || - png_get_uint_32(pm->buffer+4) != CHUNK_IHDR) - png_error(pp, "invalid IHDR"); + if (png_get_uint_32(pm->buffer) != 13 || + png_get_uint_32(pm->buffer+4) != CHUNK_IHDR) + png_error(pp, "invalid IHDR"); - /* Check the list of modifiers for modifications to the IHDR. */ + /* Check the list of modifiers for modifications to the IHDR. */ mod = pm->modifications; - while (mod != NULL) - { - if (mod->chunk == CHUNK_IHDR && mod->modify_fn && - (*mod->modify_fn)(pp, pm, mod, 0)) - { - mod->modified = 1; - modifier_setbuffer(pm); - } + while (mod != NULL) + { + if (mod->chunk == CHUNK_IHDR && mod->modify_fn && + (*mod->modify_fn)(pp, pm, mod, 0)) + { + mod->modified = 1; + modifier_setbuffer(pm); + } - /* Ignore removal or add if IHDR! */ - mod = mod->next; - } + /* Ignore removal or add if IHDR! */ + mod = mod->next; + } - /* Cache information from the IHDR (the modified one.) */ - pm->bit_depth = pm->buffer[8+8]; - pm->colour_type = pm->buffer[8+8+1]; + /* Cache information from the IHDR (the modified one.) */ + pm->bit_depth = pm->buffer[8+8]; + pm->colour_type = pm->buffer[8+8+1]; - pm->state = modifier_IHDR; - pm->flush = 0; - break; + pm->state = modifier_IHDR; + pm->flush = 0; + break; default: /* Read a new chunk and process it until we see PLTE, IDAT or - * IEND. 'flush' indicates that there is still some data to - * output from the preceding chunk. - */ - if ((cb = pm->flush) > 0) - { - if (cb > st) cb = st; - pm->flush -= cb; - sucker_read(pp, pb, cb); - pb += cb; - st -= cb; - if (st <= 0) return; - } + * IEND. 'flush' indicates that there is still some data to + * output from the preceding chunk. + */ + if ((cb = pm->flush) > 0) + { + if (cb > st) cb = st; + pm->flush -= cb; + sucker_read(pp, pb, cb); + pb += cb; + st -= cb; + if (st <= 0) return; + } - /* No more bytes to flush, read a header, or handle a pending - * chunk. - */ - if (pm->pending_chunk != 0) - { - png_save_uint_32(pm->buffer, pm->pending_len); - png_save_uint_32(pm->buffer+4, pm->pending_chunk); - pm->pending_len = 0; - pm->pending_chunk = 0; - } + /* No more bytes to flush, read a header, or handle a pending + * chunk. + */ + if (pm->pending_chunk != 0) + { + png_save_uint_32(pm->buffer, pm->pending_len); + png_save_uint_32(pm->buffer+4, pm->pending_chunk); + pm->pending_len = 0; + pm->pending_chunk = 0; + } else - sucker_read(pp, pm->buffer, 8); + sucker_read(pp, pm->buffer, 8); - pm->buffer_count = 8; - pm->buffer_position = 0; + pm->buffer_count = 8; + pm->buffer_position = 0; - /* Check for something to modify or a terminator chunk. */ - len = png_get_uint_32(pm->buffer); - chunk = png_get_uint_32(pm->buffer+4); + /* Check for something to modify or a terminator chunk. */ + len = png_get_uint_32(pm->buffer); + chunk = png_get_uint_32(pm->buffer+4); - /* Terminators first, they may have to be delayed for added - * chunks - */ - if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT || chunk == CHUNK_IEND) - { - mod = pm->modifications; + /* Terminators first, they may have to be delayed for added + * chunks + */ + if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT || chunk == CHUNK_IEND) + { + mod = pm->modifications; - while (mod != NULL) - { - if ((mod->add == chunk || - mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT) && - mod->modify_fn != NULL && !mod->modified && !mod->added) - { - /* Regardless of what the modify function does do not run this - * again. - */ - mod->added = 1; + while (mod != NULL) + { + if ((mod->add == chunk || + mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT) && + mod->modify_fn != NULL && !mod->modified && !mod->added) + { + /* Regardless of what the modify function does do not run this + * again. + */ + mod->added = 1; - if ((*mod->modify_fn)(pp, pm, mod, 1/*add*/)) - { - /* Reset the CRC on a new chunk */ - if (pm->buffer_count > 0) - modifier_setbuffer(pm); - else - { - pm->buffer_position = 0; - mod->removed = 1; - } + if ((*mod->modify_fn)(pp, pm, mod, 1/*add*/)) + { + /* Reset the CRC on a new chunk */ + if (pm->buffer_count > 0) + modifier_setbuffer(pm); + else + { + pm->buffer_position = 0; + mod->removed = 1; + } - /* The buffer has been filled with something (we assume) so - * output this. Pend the current chunk. - */ - pm->pending_len = len; - pm->pending_chunk = chunk; - break; /* out of while */ - } - } + /* The buffer has been filled with something (we assume) so + * output this. Pend the current chunk. + */ + pm->pending_len = len; + pm->pending_chunk = chunk; + break; /* out of while */ + } + } - mod = mod->next; - } + mod = mod->next; + } - /* Don't do any further processing if the buffer was modified - - * otherwise the code will end up modifying a chunk that was just - * added. - */ - if (mod != NULL) - break; /* out of switch */ - } + /* Don't do any further processing if the buffer was modified - + * otherwise the code will end up modifying a chunk that was just + * added. + */ + if (mod != NULL) + break; /* out of switch */ + } - /* If we get to here then this chunk may need to be modified. To do - * this is must be less than 1024 bytes in total size, otherwise - * it just gets flushed. - */ - if (len+12 <= sizeof pm->buffer) - { - sucker_read(pp, pm->buffer+pm->buffer_count, - len+12-pm->buffer_count); - pm->buffer_count = len+12; + /* If we get to here then this chunk may need to be modified. To do + * this is must be less than 1024 bytes in total size, otherwise + * it just gets flushed. + */ + if (len+12 <= sizeof pm->buffer) + { + sucker_read(pp, pm->buffer+pm->buffer_count, + len+12-pm->buffer_count); + pm->buffer_count = len+12; - /* Check for a modification, else leave it be. */ - mod = pm->modifications; - while (mod != NULL) - { - if (mod->chunk == chunk) - { - if (mod->modify_fn == NULL) - { - /* Remove this chunk */ - pm->buffer_count = pm->buffer_position = 0; - mod->removed = 1; - break; /* Terminate the while loop */ - } - else if ((*mod->modify_fn)(pp, pm, mod, 0)) - { - mod->modified = 1; - /* The chunk may have been removed: */ - if (pm->buffer_count == 0) - { - pm->buffer_position = 0; - break; - } - modifier_setbuffer(pm); - } - } + /* Check for a modification, else leave it be. */ + mod = pm->modifications; + while (mod != NULL) + { + if (mod->chunk == chunk) + { + if (mod->modify_fn == NULL) + { + /* Remove this chunk */ + pm->buffer_count = pm->buffer_position = 0; + mod->removed = 1; + break; /* Terminate the while loop */ + } + else if ((*mod->modify_fn)(pp, pm, mod, 0)) + { + mod->modified = 1; + /* The chunk may have been removed: */ + if (pm->buffer_count == 0) + { + pm->buffer_position = 0; + break; + } + modifier_setbuffer(pm); + } + } - mod = mod->next; - } - } - else - pm->flush = len+12 - pm->buffer_count; /* data + crc */ + mod = mod->next; + } + } + else + pm->flush = len+12 - pm->buffer_count; /* data + crc */ - /* Take the data from the buffer (if there is any). */ - break; + /* Take the data from the buffer (if there is any). */ + break; } /* Here to read from the modifier buffer (not directly from @@ -954,22 +954,22 @@ set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id, { if (setjmp(pm->this.jmpbuf) == 0) { - png_set_read_fn(pp, pm, modifier_read); + png_set_read_fn(pp, pm, modifier_read); - pm->state = modifier_start; - pm->bit_depth = 0; - pm->colour_type = 255; + pm->state = modifier_start; + pm->bit_depth = 0; + pm->colour_type = 255; - pm->pending_len = 0; - pm->pending_chunk = 0; - pm->flush = 0; - pm->buffer_count = 0; - pm->buffer_position = 0; + pm->pending_len = 0; + pm->pending_chunk = 0; + pm->flush = 0; + pm->buffer_count = 0; + pm->buffer_position = 0; } else { - sucker_read_reset(&pm->this); - pp = NULL; + sucker_read_reset(&pm->this); + pp = NULL; } } @@ -1073,11 +1073,11 @@ standard_row(png_structp pp, png_byte buffer[STD_ROWMAX], png_byte colour_type, /* 65535 pixels, but rotate the values. */ while (i<128) { - /* Three bytes per pixel, r, g, b, make b by r^g */ - buffer[3*i+0] = (v >> 8) & 0xff; - buffer[3*i+1] = v & 0xff; - buffer[3*i+2] = ((v >> 8) ^ v) & 0xff; - ++v; + /* Three bytes per pixel, r, g, b, make b by r^g */ + buffer[3*i+0] = (v >> 8) & 0xff; + buffer[3*i+1] = v & 0xff; + buffer[3*i+2] = ((v >> 8) ^ v) & 0xff; + ++v; ++i; } return; @@ -1085,11 +1085,11 @@ standard_row(png_structp pp, png_byte buffer[STD_ROWMAX], png_byte colour_type, /* 65535 pixels, r, g, b, a; just replicate */ while (i<128) { - buffer[4*i+0] = (v >> 8) & 0xff; - buffer[4*i+1] = v & 0xff; - buffer[4*i+2] = (v >> 8) & 0xff; - buffer[4*i+3] = v & 0xff; - ++v; + buffer[4*i+0] = (v >> 8) & 0xff; + buffer[4*i+1] = v & 0xff; + buffer[4*i+2] = (v >> 8) & 0xff; + buffer[4*i+3] = v & 0xff; + ++v; ++i; } return; @@ -1099,15 +1099,15 @@ standard_row(png_structp pp, png_byte buffer[STD_ROWMAX], png_byte colour_type, */ while (i<128) { - png_uint_32 t = v++; - buffer[6*i+0] = (t >> 8) & 0xff; - buffer[6*i+1] = t & 0xff; - t *= 257; - buffer[6*i+2] = (t >> 8) & 0xff; - buffer[6*i+3] = t & 0xff; - t *= 17; - buffer[6*i+4] = (t >> 8) & 0xff; - buffer[6*i+5] = t & 0xff; + png_uint_32 t = v++; + buffer[6*i+0] = (t >> 8) & 0xff; + buffer[6*i+1] = t & 0xff; + t *= 257; + buffer[6*i+2] = (t >> 8) & 0xff; + buffer[6*i+3] = t & 0xff; + t *= 17; + buffer[6*i+4] = (t >> 8) & 0xff; + buffer[6*i+5] = t & 0xff; ++i; } return; @@ -1115,16 +1115,16 @@ standard_row(png_structp pp, png_byte buffer[STD_ROWMAX], png_byte colour_type, /* As above in the 32 bit case. */ while (i<128) { - png_uint_32 t = v++; - buffer[8*i+0] = (t >> 8) & 0xff; - buffer[8*i+1] = t & 0xff; - buffer[8*i+4] = (t >> 8) & 0xff; - buffer[8*i+5] = t & 0xff; - t *= 257; - buffer[8*i+2] = (t >> 8) & 0xff; - buffer[8*i+3] = t & 0xff; - buffer[8*i+6] = (t >> 8) & 0xff; - buffer[8*i+7] = t & 0xff; + png_uint_32 t = v++; + buffer[8*i+0] = (t >> 8) & 0xff; + buffer[8*i+1] = t & 0xff; + buffer[8*i+4] = (t >> 8) & 0xff; + buffer[8*i+5] = t & 0xff; + t *= 257; + buffer[8*i+2] = (t >> 8) & 0xff; + buffer[8*i+3] = t & 0xff; + buffer[8*i+6] = (t >> 8) & 0xff; + buffer[8*i+7] = t & 0xff; ++i; } return; @@ -1144,16 +1144,16 @@ make_standard(png_sucker* ps, png_byte colour_type, int bdlo, int bdhi) png_infop pi; { - size_t pos; - char name[64]; /* Same size as the buffer in a file. */ + size_t pos; + char name[64]; /* Same size as the buffer in a file. */ - /* Build a name */ - pos = safecat(name, sizeof name, 0, bit_depths[bdlo]); - pos = safecat(name, sizeof name, pos, "bit "); - pos = safecat(name, sizeof name, pos, colour_types[colour_type]); + /* Build a name */ + pos = safecat(name, sizeof name, 0, bit_depths[bdlo]); + pos = safecat(name, sizeof name, pos, "bit "); + pos = safecat(name, sizeof name, pos, colour_types[colour_type]); - /* Get a png_struct for writing the image. */ - pp = set_sucker_for_write(ps, &pi, name); + /* Get a png_struct for writing the image. */ + pp = set_sucker_for_write(ps, &pi, name); } if (pp == NULL) return; @@ -1161,19 +1161,19 @@ make_standard(png_sucker* ps, png_byte colour_type, int bdlo, int bdhi) if (setjmp(ps->jmpbuf) != 0) { sucker_write_reset(ps); - continue; + continue; } h = standard_height(pp, colour_type, bit_depth), png_set_IHDR(pp, pi, standard_width(pp, colour_type, bit_depth), h, bit_depth, colour_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, - PNG_FILTER_TYPE_BASE); + PNG_FILTER_TYPE_BASE); if (colour_type == 3) /* palette */ { - int i; + int i; png_color pal[256]; - for (i=0; i<256; ++i) pal[i].red = pal[i].green = pal[i].blue = i; + for (i=0; i<256; ++i) pal[i].red = pal[i].green = pal[i].blue = i; png_set_PLTE(pp, pi, pal, 256); } @@ -1186,7 +1186,7 @@ make_standard(png_sucker* ps, png_byte colour_type, int bdlo, int bdhi) else for (y=0; yjmpbuf) != 0) { sucker_read_reset(ps); - continue; + continue; } h = standard_height(pp, colour_type, bit_depth); @@ -1259,19 +1259,19 @@ test_standard(png_sucker* ps, png_byte colour_type, int bdlo, int bdhi) if (colour_type == 3) /* palette */ { - png_colorp pal; - int num; - if (png_get_PLTE(pp, pi, &pal, &num) & PNG_INFO_PLTE) - { - int i; - if (num != 256) - png_error(pp, "validate: color type 3 PLTE chunk size changed"); - for (i=0; ibuffer, cb); png_save_uint_32(pm->buffer+4, CHUNK_sBIT); while (cb > 0) - (pm->buffer+8)[--cb] = sbit; + (pm->buffer+8)[--cb] = sbit; return 1; } @@ -1562,166 +1562,166 @@ gamma_test(png_modifier *pm, const png_byte colour_type, */ const int processing = (fabs(screen_gamma*file_gamma-1) >= PNG_GAMMA_THRESHOLD && !threshold_test && !speed && colour_type != 3) - || bit_depth != out_bd; + || bit_depth != out_bd; const int samples_per_pixel = (out_ct & 2) ? 3 : 1; const double gamma = 1/(file_gamma*screen_gamma); /* Overall correction */ for (y=0; y> (bit_depth-sbit); - double i, sample, encoded_sample, output, encoded_error, error; - double es_lo, es_hi; + if (processing) for (x=0; x> (bit_depth-sbit); + double i, sample, encoded_sample, output, encoded_error, error; + double es_lo, es_hi; - /* First check on the 'perfect' result obtained from the digitized - * input value, id, and compare this against the actual digitized - * result, 'od'. 'i' is the input result in the range 0..1: - * - * NOTE: sbit should be taken into account here but isn't, as - * described above. - */ - i = isbit; i /= (1U< maxerrout) - maxerrout = encoded_error; + if (encoded_error > maxerrout) + maxerrout = encoded_error; - if (encoded_error < .5+maxout) - continue; + if (encoded_error < .5+maxout) + continue; - /* There may be an error, calculate the actual sample values - - * unencoded light intensity values. Note that in practice these - * are not unencoded because they include a 'viewing correction' to - * decrease or (normally) increase the perceptual contrast of the - * image. There's nothing we can do about this - we don't know what - * it is - so assume the unencoded value is perceptually linear. - */ - sample = pow(i, 1/file_gamma); /* In range 0..1 */ - output = od; - output /= outmax; - output = pow(output, screen_gamma); + /* There may be an error, calculate the actual sample values - + * unencoded light intensity values. Note that in practice these + * are not unencoded because they include a 'viewing correction' to + * decrease or (normally) increase the perceptual contrast of the + * image. There's nothing we can do about this - we don't know what + * it is - so assume the unencoded value is perceptually linear. + */ + sample = pow(i, 1/file_gamma); /* In range 0..1 */ + output = od; + output /= outmax; + output = pow(output, screen_gamma); - /* Now we have the numbers for real errors, both absolute values as - * as a percentage of the correct value (output): - */ - error = fabs(sample-output); - if (error > maxerrabs) - maxerrabs = error; - /* The following is an attempt to ignore the tendency of - * quantization to dominate the percentage errors for low output - * sample values: - */ - if (sample*maxpc > .5+maxabs) - { - double pcerr = error/sample; - if (pcerr > maxerrpc) maxerrpc = pcerr; - } + /* Now we have the numbers for real errors, both absolute values as + * as a percentage of the correct value (output): + */ + error = fabs(sample-output); + if (error > maxerrabs) + maxerrabs = error; + /* The following is an attempt to ignore the tendency of + * quantization to dominate the percentage errors for low output + * sample values: + */ + if (sample*maxpc > .5+maxabs) + { + double pcerr = error/sample; + if (pcerr > maxerrpc) maxerrpc = pcerr; + } - /* Now calculate the digitization limits for 'encoded_sample' using - * the 'max' values. Note that maxout is in the encoded space but - * maxpc and maxabs are in linear light space. - * - * First find the maximum error in linear light space, range 0..1: - */ - { - double tmp = sample * maxpc; - if (tmp < maxabs) tmp = maxabs; + /* Now calculate the digitization limits for 'encoded_sample' using + * the 'max' values. Note that maxout is in the encoded space but + * maxpc and maxabs are in linear light space. + * + * First find the maximum error in linear light space, range 0..1: + */ + { + double tmp = sample * maxpc; + if (tmp < maxabs) tmp = maxabs; - /* Low bound - the minimum of the three: */ - es_lo = encoded_sample - maxout; - if (es_lo > 0 && sample-tmp > 0) - { - double l = outmax * pow(sample-tmp, 1/screen_gamma); - if (l < es_lo) es_lo = l; - } - else - es_lo = 0; + /* Low bound - the minimum of the three: */ + es_lo = encoded_sample - maxout; + if (es_lo > 0 && sample-tmp > 0) + { + double l = outmax * pow(sample-tmp, 1/screen_gamma); + if (l < es_lo) es_lo = l; + } + else + es_lo = 0; - es_hi = encoded_sample + maxout; - if (es_hi < outmax && sample+tmp < 1) - { - double h = outmax * pow(sample+tmp, 1/screen_gamma); - if (h > es_hi) es_hi = h; - } - else - es_hi = outmax; - } + es_hi = encoded_sample + maxout; + if (es_hi < outmax && sample+tmp < 1) + { + double h = outmax * pow(sample+tmp, 1/screen_gamma); + if (h > es_hi) es_hi = h; + } + else + es_hi = outmax; + } - /* The primary test is that the final encoded value returned by the - * library should be between the two limits (inclusive) that were - * calculated above. At this point quantization of the output must - * be taken into account. - */ - if (od+.5 < es_lo || od-.5 > es_hi) - { - /* Thee has been an error in processing. */ - double is_lo, is_hi; + /* The primary test is that the final encoded value returned by the + * library should be between the two limits (inclusive) that were + * calculated above. At this point quantization of the output must + * be taken into account. + */ + if (od+.5 < es_lo || od-.5 > es_hi) + { + /* Thee has been an error in processing. */ + double is_lo, is_hi; - if (use_input_precision) - { - /* Ok, something is wrong - this actually happens in current - * libpng sbit processing. Assume that the input value (id, - * adjusted for sbit) can be anywhere between value-.5 and - * value+.5 - quite a large range if sbit is low. - */ - double tmp = (isbit - .5)/((1U< 0) - { - is_lo = outmax * pow(tmp, gamma) - maxout; - if (is_lo < 0) is_lo = 0; - } - else - is_lo = 0; + if (use_input_precision) + { + /* Ok, something is wrong - this actually happens in current + * libpng sbit processing. Assume that the input value (id, + * adjusted for sbit) can be anywhere between value-.5 and + * value+.5 - quite a large range if sbit is low. + */ + double tmp = (isbit - .5)/((1U< 0) + { + is_lo = outmax * pow(tmp, gamma) - maxout; + if (is_lo < 0) is_lo = 0; + } + else + is_lo = 0; - tmp = (isbit + .5)/((1U< outmax) is_hi = outmax; - } - else - is_hi = outmax; + tmp = (isbit + .5)/((1U< outmax) is_hi = outmax; + } + else + is_hi = outmax; - if (!(od+.5 < is_lo || od-.5 > is_hi)) - continue; - } + if (!(od+.5 < is_lo || od-.5 > is_hi)) + continue; + } - { - char msg[256]; - sprintf(msg, - "error: %.3f; %u{%u;%u} -> %u not %.2f (%.1f-%.1f)", - od-encoded_sample, id, sbit, isbit, od, encoded_sample, - use_input_precision ? is_lo : es_lo, - use_input_precision ? is_hi : es_hi); - png_warning(pp, msg); - } - } - } - else if (!speed && memcmp(std, display, cb) != 0) - { - char msg[64]; - /* No transform is expected on the threshold tests. */ - sprintf(msg, "gamma: below threshold row %d (of %d) changed", y, h); - png_error(pp, msg); - } + { + char msg[256]; + sprintf(msg, + "error: %.3f; %u{%u;%u} -> %u not %.2f (%.1f-%.1f)", + od-encoded_sample, id, sbit, isbit, od, encoded_sample, + use_input_precision ? is_lo : es_lo, + use_input_precision ? is_hi : es_hi); + png_warning(pp, msg); + } + } + } + else if (!speed && memcmp(std, display, cb) != 0) + { + char msg[64]; + /* No transform is expected on the threshold tests. */ + sprintf(msg, "gamma: below threshold row %d (of %d) changed", y, h); + png_error(pp, msg); + } } } @@ -1778,8 +1778,8 @@ perform_gamma_threshold_tests(png_modifier *pm) double gamma = 1.0; while (gamma >= .4) { - gamma_threshold_test(pm, colour_type, bit_depth, gamma, 1/gamma); - gamma *= .95; + gamma_threshold_test(pm, colour_type, bit_depth, gamma, 1/gamma); + gamma *= .95; } /* And a special test for sRGB */ @@ -1827,9 +1827,9 @@ static void perform_gamma_transform_tests(png_modifier *pm, int speed) for (i=0; ingammas; ++i) for (j=0; jngammas; ++j) if (i != j) { - gamma_transform_test(pm, colour_type, bit_depth, 1/pm->gammas[i], - pm->gammas[j], bit_depth, speed, pm->use_input_precision, - 0/*do not strip16*/); + gamma_transform_test(pm, colour_type, bit_depth, 1/pm->gammas[i], + pm->gammas[j], bit_depth, speed, pm->use_input_precision, + 0/*do not strip16*/); if (fail(pm)) return; } } @@ -1848,20 +1848,20 @@ static void perform_gamma_sbit_tests(png_modifier *pm, int speed) for (i=0; ingammas; ++i) for (j=0; jngammas; ++j) if (i != j) { - if (sbit < 8) - { - gamma_transform_test(pm, 0, 8, 1/pm->gammas[i], pm->gammas[j], sbit, - speed, pm->use_input_precision_sbit, 0/*strip16*/); - if (fail(pm)) return; - gamma_transform_test(pm, 2, 8, 1/pm->gammas[i], pm->gammas[j], sbit, - speed, pm->use_input_precision_sbit, 0/*strip16*/); - if (fail(pm)) return; - } - gamma_transform_test(pm, 0, 16, 1/pm->gammas[i], pm->gammas[j], sbit, - speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (sbit < 8) + { + gamma_transform_test(pm, 0, 8, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (fail(pm)) return; + gamma_transform_test(pm, 2, 8, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); + if (fail(pm)) return; + } + gamma_transform_test(pm, 0, 16, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); if (fail(pm)) return; - gamma_transform_test(pm, 2, 16, 1/pm->gammas[i], pm->gammas[j], sbit, - speed, pm->use_input_precision_sbit, 0/*strip16*/); + gamma_transform_test(pm, 2, 16, 1/pm->gammas[i], pm->gammas[j], sbit, + speed, pm->use_input_precision_sbit, 0/*strip16*/); if (fail(pm)) return; } } @@ -1931,13 +1931,13 @@ perform_gamma_test(png_modifier *pm, int speed, int summary) printf("Gamma correction with sBIT:\n"); if (pm->sbitlow < 8) { - printf(" 2 bit gray: %.5f\n", pm->error_gray_2); - printf(" 4 bit gray: %.5f\n", pm->error_gray_4); - printf(" 8 bit gray: %.5f\n", pm->error_gray_8); + printf(" 2 bit gray: %.5f\n", pm->error_gray_2); + printf(" 4 bit gray: %.5f\n", pm->error_gray_4); + printf(" 8 bit gray: %.5f\n", pm->error_gray_8); } printf(" 16 bit gray: %.5f\n", pm->error_gray_16); if (pm->sbitlow < 8) - printf(" 8 bit color: %.5f\n", pm->error_color_8); + printf(" 8 bit color: %.5f\n", pm->error_color_8); printf(" 16 bit color: %.5f\n", pm->error_color_16); } @@ -2003,7 +2003,7 @@ int main(int argc, const char **argv) else if (strcmp(*argv, "-q") == 0) pm.this.verbose = pm.log = summary = 0; else if (strcmp(*argv, "-g") == 0) - pm.ngammas = (sizeof gammas)/(sizeof gammas[0]); + pm.ngammas = (sizeof gammas)/(sizeof gammas[0]); else if (strcmp(*argv, "-w") == 0) pm.this.treat_warnings_as_errors = 0; else if (strcmp(*argv, "-speed") == 0) @@ -2014,27 +2014,27 @@ int main(int argc, const char **argv) { --argc; if (strcmp(4+*argv, "abs8") == 0) - pm.maxabs8 = atof(*++argv); - else if (strcmp(4+*argv, "abs16") == 0) - pm.maxabs16 = atof(*++argv); - else if (strcmp(4+*argv, "out8") == 0) - pm.maxout8 = atof(*++argv); - else if (strcmp(4+*argv, "out16") == 0) - pm.maxout16 = atof(*++argv); - else if (strcmp(4+*argv, "pc8") == 0) - pm.maxpc8 = atof(*++argv); - else if (strcmp(4+*argv, "pc16") == 0) - pm.maxpc16 = atof(*++argv); - else - { - fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv); - exit(1); - } + pm.maxabs8 = atof(*++argv); + else if (strcmp(4+*argv, "abs16") == 0) + pm.maxabs16 = atof(*++argv); + else if (strcmp(4+*argv, "out8") == 0) + pm.maxout8 = atof(*++argv); + else if (strcmp(4+*argv, "out16") == 0) + pm.maxout16 = atof(*++argv); + else if (strcmp(4+*argv, "pc8") == 0) + pm.maxpc8 = atof(*++argv); + else if (strcmp(4+*argv, "pc16") == 0) + pm.maxpc16 = atof(*++argv); + else + { + fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv); + exit(1); + } } else { fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv); - exit(1); + exit(1); } /* Make useful base images */ @@ -2052,9 +2052,9 @@ int main(int argc, const char **argv) #else "fixed", #endif - (pm.this.nerrors || pm.this.treat_warnings_as_errors && - pm.this.nwarnings) ? "(errors)" : (pm.this.nwarnings ? - "(warnings)" : "(no errors or warnings)") + (pm.this.nerrors || pm.this.treat_warnings_as_errors && + pm.this.nwarnings) ? "(errors)" : (pm.this.nwarnings ? + "(warnings)" : "(no errors or warnings)") ); /* Error exit if there are any errors, and maybe if there are any diff --git a/pngwrite.c b/pngwrite.c index 15d7f6e18..de30bdd5f 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -148,7 +148,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) int j; for (j = 0; j<(int)info_ptr->num_trans; j++) info_ptr->trans_alpha[j] = - (png_byte)(255 - info_ptr->trans_alpha[j]); + (png_byte)(255 - info_ptr->trans_alpha[j]); } #endif png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),