Dependencies:   emwin_lib

Fork of DMemWin by Embedded Artists

Committer:
destinyXfate
Date:
Thu Jun 02 04:52:54 2016 +0000
Revision:
2:0e2ef1edf01b
;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
destinyXfate 2:0e2ef1edf01b 1
destinyXfate 2:0e2ef1edf01b 2 /* pngrutil.c - utilities to read a PNG file
destinyXfate 2:0e2ef1edf01b 3 *
destinyXfate 2:0e2ef1edf01b 4 * Last changed in libpng 1.2.15 January 5, 2007
destinyXfate 2:0e2ef1edf01b 5 * For conditions of distribution and use, see copyright notice in png.h
destinyXfate 2:0e2ef1edf01b 6 * Copyright (c) 1998-2007 Glenn Randers-Pehrson
destinyXfate 2:0e2ef1edf01b 7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
destinyXfate 2:0e2ef1edf01b 8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
destinyXfate 2:0e2ef1edf01b 9 *
destinyXfate 2:0e2ef1edf01b 10 * This file contains routines that are only called from within
destinyXfate 2:0e2ef1edf01b 11 * libpng itself during the course of reading an image.
destinyXfate 2:0e2ef1edf01b 12 */
destinyXfate 2:0e2ef1edf01b 13
destinyXfate 2:0e2ef1edf01b 14 #define PNG_INTERNAL
destinyXfate 2:0e2ef1edf01b 15 #include "png.h"
destinyXfate 2:0e2ef1edf01b 16
destinyXfate 2:0e2ef1edf01b 17 #if defined(PNG_READ_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 18
destinyXfate 2:0e2ef1edf01b 19 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 20 # if defined(_WIN32_WCE)
destinyXfate 2:0e2ef1edf01b 21 /* strtod() function is not supported on WindowsCE */
destinyXfate 2:0e2ef1edf01b 22 __inline double png_strtod(png_structp png_ptr, const char *nptr, char **endptr)
destinyXfate 2:0e2ef1edf01b 23 {
destinyXfate 2:0e2ef1edf01b 24 double result = 0;
destinyXfate 2:0e2ef1edf01b 25 int len;
destinyXfate 2:0e2ef1edf01b 26 wchar_t *str, *end;
destinyXfate 2:0e2ef1edf01b 27
destinyXfate 2:0e2ef1edf01b 28 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
destinyXfate 2:0e2ef1edf01b 29 str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
destinyXfate 2:0e2ef1edf01b 30 if ( NULL != str )
destinyXfate 2:0e2ef1edf01b 31 {
destinyXfate 2:0e2ef1edf01b 32 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
destinyXfate 2:0e2ef1edf01b 33 result = wcstod(str, &end);
destinyXfate 2:0e2ef1edf01b 34 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
destinyXfate 2:0e2ef1edf01b 35 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
destinyXfate 2:0e2ef1edf01b 36 png_free(str);
destinyXfate 2:0e2ef1edf01b 37 }
destinyXfate 2:0e2ef1edf01b 38 return result;
destinyXfate 2:0e2ef1edf01b 39 }
destinyXfate 2:0e2ef1edf01b 40 # else
destinyXfate 2:0e2ef1edf01b 41 # define png_strtod(p,a,b) strtod(a,b)
destinyXfate 2:0e2ef1edf01b 42 # endif
destinyXfate 2:0e2ef1edf01b 43 #endif
destinyXfate 2:0e2ef1edf01b 44
destinyXfate 2:0e2ef1edf01b 45 png_uint_32 PNGAPI
destinyXfate 2:0e2ef1edf01b 46 png_get_uint_31(png_structp png_ptr, png_bytep buf)
destinyXfate 2:0e2ef1edf01b 47 {
destinyXfate 2:0e2ef1edf01b 48 png_uint_32 i = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 49 if (i > PNG_UINT_31_MAX)
destinyXfate 2:0e2ef1edf01b 50 png_error(png_ptr, "PNG unsigned integer out of range.");
destinyXfate 2:0e2ef1edf01b 51 return (i);
destinyXfate 2:0e2ef1edf01b 52 }
destinyXfate 2:0e2ef1edf01b 53 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
destinyXfate 2:0e2ef1edf01b 54 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
destinyXfate 2:0e2ef1edf01b 55 png_uint_32 PNGAPI
destinyXfate 2:0e2ef1edf01b 56 png_get_uint_32(png_bytep buf)
destinyXfate 2:0e2ef1edf01b 57 {
destinyXfate 2:0e2ef1edf01b 58 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
destinyXfate 2:0e2ef1edf01b 59 ((png_uint_32)(*(buf + 1)) << 16) +
destinyXfate 2:0e2ef1edf01b 60 ((png_uint_32)(*(buf + 2)) << 8) +
destinyXfate 2:0e2ef1edf01b 61 (png_uint_32)(*(buf + 3));
destinyXfate 2:0e2ef1edf01b 62
destinyXfate 2:0e2ef1edf01b 63 return (i);
destinyXfate 2:0e2ef1edf01b 64 }
destinyXfate 2:0e2ef1edf01b 65
destinyXfate 2:0e2ef1edf01b 66 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
destinyXfate 2:0e2ef1edf01b 67 * data is stored in the PNG file in two's complement format, and it is
destinyXfate 2:0e2ef1edf01b 68 * assumed that the machine format for signed integers is the same. */
destinyXfate 2:0e2ef1edf01b 69 png_int_32 PNGAPI
destinyXfate 2:0e2ef1edf01b 70 png_get_int_32(png_bytep buf)
destinyXfate 2:0e2ef1edf01b 71 {
destinyXfate 2:0e2ef1edf01b 72 png_int_32 i = ((png_int_32)(*buf) << 24) +
destinyXfate 2:0e2ef1edf01b 73 ((png_int_32)(*(buf + 1)) << 16) +
destinyXfate 2:0e2ef1edf01b 74 ((png_int_32)(*(buf + 2)) << 8) +
destinyXfate 2:0e2ef1edf01b 75 (png_int_32)(*(buf + 3));
destinyXfate 2:0e2ef1edf01b 76
destinyXfate 2:0e2ef1edf01b 77 return (i);
destinyXfate 2:0e2ef1edf01b 78 }
destinyXfate 2:0e2ef1edf01b 79
destinyXfate 2:0e2ef1edf01b 80 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
destinyXfate 2:0e2ef1edf01b 81 png_uint_16 PNGAPI
destinyXfate 2:0e2ef1edf01b 82 png_get_uint_16(png_bytep buf)
destinyXfate 2:0e2ef1edf01b 83 {
destinyXfate 2:0e2ef1edf01b 84 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
destinyXfate 2:0e2ef1edf01b 85 (png_uint_16)(*(buf + 1)));
destinyXfate 2:0e2ef1edf01b 86
destinyXfate 2:0e2ef1edf01b 87 return (i);
destinyXfate 2:0e2ef1edf01b 88 }
destinyXfate 2:0e2ef1edf01b 89 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 90
destinyXfate 2:0e2ef1edf01b 91 /* Read data, and (optionally) run it through the CRC. */
destinyXfate 2:0e2ef1edf01b 92 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 93 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
destinyXfate 2:0e2ef1edf01b 94 {
destinyXfate 2:0e2ef1edf01b 95 if(png_ptr == NULL) return;
destinyXfate 2:0e2ef1edf01b 96 png_read_data(png_ptr, buf, length);
destinyXfate 2:0e2ef1edf01b 97 png_calculate_crc(png_ptr, buf, length);
destinyXfate 2:0e2ef1edf01b 98 }
destinyXfate 2:0e2ef1edf01b 99
destinyXfate 2:0e2ef1edf01b 100 /* Optionally skip data and then check the CRC. Depending on whether we
destinyXfate 2:0e2ef1edf01b 101 are reading a ancillary or critical chunk, and how the program has set
destinyXfate 2:0e2ef1edf01b 102 things up, we may calculate the CRC on the data and print a message.
destinyXfate 2:0e2ef1edf01b 103 Returns '1' if there was a CRC error, '0' otherwise. */
destinyXfate 2:0e2ef1edf01b 104 int /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 105 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
destinyXfate 2:0e2ef1edf01b 106 {
destinyXfate 2:0e2ef1edf01b 107 png_size_t i;
destinyXfate 2:0e2ef1edf01b 108 png_size_t istop = png_ptr->zbuf_size;
destinyXfate 2:0e2ef1edf01b 109
destinyXfate 2:0e2ef1edf01b 110 for (i = (png_size_t)skip; i > istop; i -= istop)
destinyXfate 2:0e2ef1edf01b 111 {
destinyXfate 2:0e2ef1edf01b 112 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
destinyXfate 2:0e2ef1edf01b 113 }
destinyXfate 2:0e2ef1edf01b 114 if (i)
destinyXfate 2:0e2ef1edf01b 115 {
destinyXfate 2:0e2ef1edf01b 116 png_crc_read(png_ptr, png_ptr->zbuf, i);
destinyXfate 2:0e2ef1edf01b 117 }
destinyXfate 2:0e2ef1edf01b 118
destinyXfate 2:0e2ef1edf01b 119 if (png_crc_error(png_ptr))
destinyXfate 2:0e2ef1edf01b 120 {
destinyXfate 2:0e2ef1edf01b 121 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
destinyXfate 2:0e2ef1edf01b 122 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
destinyXfate 2:0e2ef1edf01b 123 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
destinyXfate 2:0e2ef1edf01b 124 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
destinyXfate 2:0e2ef1edf01b 125 {
destinyXfate 2:0e2ef1edf01b 126 png_chunk_warning(png_ptr, "CRC error");
destinyXfate 2:0e2ef1edf01b 127 }
destinyXfate 2:0e2ef1edf01b 128 else
destinyXfate 2:0e2ef1edf01b 129 {
destinyXfate 2:0e2ef1edf01b 130 png_chunk_error(png_ptr, "CRC error");
destinyXfate 2:0e2ef1edf01b 131 }
destinyXfate 2:0e2ef1edf01b 132 return (1);
destinyXfate 2:0e2ef1edf01b 133 }
destinyXfate 2:0e2ef1edf01b 134
destinyXfate 2:0e2ef1edf01b 135 return (0);
destinyXfate 2:0e2ef1edf01b 136 }
destinyXfate 2:0e2ef1edf01b 137
destinyXfate 2:0e2ef1edf01b 138 /* Compare the CRC stored in the PNG file with that calculated by libpng from
destinyXfate 2:0e2ef1edf01b 139 the data it has read thus far. */
destinyXfate 2:0e2ef1edf01b 140 int /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 141 png_crc_error(png_structp png_ptr)
destinyXfate 2:0e2ef1edf01b 142 {
destinyXfate 2:0e2ef1edf01b 143 png_byte crc_bytes[4];
destinyXfate 2:0e2ef1edf01b 144 png_uint_32 crc;
destinyXfate 2:0e2ef1edf01b 145 int need_crc = 1;
destinyXfate 2:0e2ef1edf01b 146
destinyXfate 2:0e2ef1edf01b 147 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
destinyXfate 2:0e2ef1edf01b 148 {
destinyXfate 2:0e2ef1edf01b 149 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
destinyXfate 2:0e2ef1edf01b 150 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
destinyXfate 2:0e2ef1edf01b 151 need_crc = 0;
destinyXfate 2:0e2ef1edf01b 152 }
destinyXfate 2:0e2ef1edf01b 153 else /* critical */
destinyXfate 2:0e2ef1edf01b 154 {
destinyXfate 2:0e2ef1edf01b 155 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
destinyXfate 2:0e2ef1edf01b 156 need_crc = 0;
destinyXfate 2:0e2ef1edf01b 157 }
destinyXfate 2:0e2ef1edf01b 158
destinyXfate 2:0e2ef1edf01b 159 png_read_data(png_ptr, crc_bytes, 4);
destinyXfate 2:0e2ef1edf01b 160
destinyXfate 2:0e2ef1edf01b 161 if (need_crc)
destinyXfate 2:0e2ef1edf01b 162 {
destinyXfate 2:0e2ef1edf01b 163 crc = png_get_uint_32(crc_bytes);
destinyXfate 2:0e2ef1edf01b 164 return ((int)(crc != png_ptr->crc));
destinyXfate 2:0e2ef1edf01b 165 }
destinyXfate 2:0e2ef1edf01b 166 else
destinyXfate 2:0e2ef1edf01b 167 return (0);
destinyXfate 2:0e2ef1edf01b 168 }
destinyXfate 2:0e2ef1edf01b 169
destinyXfate 2:0e2ef1edf01b 170 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
destinyXfate 2:0e2ef1edf01b 171 defined(PNG_READ_iCCP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 172 /*
destinyXfate 2:0e2ef1edf01b 173 * Decompress trailing data in a chunk. The assumption is that chunkdata
destinyXfate 2:0e2ef1edf01b 174 * points at an allocated area holding the contents of a chunk with a
destinyXfate 2:0e2ef1edf01b 175 * trailing compressed part. What we get back is an allocated area
destinyXfate 2:0e2ef1edf01b 176 * holding the original prefix part and an uncompressed version of the
destinyXfate 2:0e2ef1edf01b 177 * trailing part (the malloc area passed in is freed).
destinyXfate 2:0e2ef1edf01b 178 */
destinyXfate 2:0e2ef1edf01b 179 png_charp /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 180 png_decompress_chunk(png_structp png_ptr, int comp_type,
destinyXfate 2:0e2ef1edf01b 181 png_charp chunkdata, png_size_t chunklength,
destinyXfate 2:0e2ef1edf01b 182 png_size_t prefix_size, png_size_t *newlength)
destinyXfate 2:0e2ef1edf01b 183 {
destinyXfate 2:0e2ef1edf01b 184 static char msg[] = "Error decoding compressed text";
destinyXfate 2:0e2ef1edf01b 185 png_charp text;
destinyXfate 2:0e2ef1edf01b 186 png_size_t text_size;
destinyXfate 2:0e2ef1edf01b 187
destinyXfate 2:0e2ef1edf01b 188 if (comp_type == PNG_COMPRESSION_TYPE_BASE)
destinyXfate 2:0e2ef1edf01b 189 {
destinyXfate 2:0e2ef1edf01b 190 int ret = Z_OK;
destinyXfate 2:0e2ef1edf01b 191 png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
destinyXfate 2:0e2ef1edf01b 192 png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
destinyXfate 2:0e2ef1edf01b 193 png_ptr->zstream.next_out = png_ptr->zbuf;
destinyXfate 2:0e2ef1edf01b 194 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
destinyXfate 2:0e2ef1edf01b 195
destinyXfate 2:0e2ef1edf01b 196 text_size = 0;
destinyXfate 2:0e2ef1edf01b 197 text = NULL;
destinyXfate 2:0e2ef1edf01b 198
destinyXfate 2:0e2ef1edf01b 199 while (png_ptr->zstream.avail_in)
destinyXfate 2:0e2ef1edf01b 200 {
destinyXfate 2:0e2ef1edf01b 201 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
destinyXfate 2:0e2ef1edf01b 202 if (ret != Z_OK && ret != Z_STREAM_END)
destinyXfate 2:0e2ef1edf01b 203 {
destinyXfate 2:0e2ef1edf01b 204 if (png_ptr->zstream.msg != NULL)
destinyXfate 2:0e2ef1edf01b 205 png_warning(png_ptr, png_ptr->zstream.msg);
destinyXfate 2:0e2ef1edf01b 206 else
destinyXfate 2:0e2ef1edf01b 207 png_warning(png_ptr, msg);
destinyXfate 2:0e2ef1edf01b 208 inflateReset(&png_ptr->zstream);
destinyXfate 2:0e2ef1edf01b 209 png_ptr->zstream.avail_in = 0;
destinyXfate 2:0e2ef1edf01b 210
destinyXfate 2:0e2ef1edf01b 211 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 212 {
destinyXfate 2:0e2ef1edf01b 213 text_size = prefix_size + png_sizeof(msg) + 1;
destinyXfate 2:0e2ef1edf01b 214 text = (png_charp)png_malloc_warn(png_ptr, text_size);
destinyXfate 2:0e2ef1edf01b 215 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 216 {
destinyXfate 2:0e2ef1edf01b 217 png_free(png_ptr,chunkdata);
destinyXfate 2:0e2ef1edf01b 218 png_error(png_ptr,"Not enough memory to decompress chunk");
destinyXfate 2:0e2ef1edf01b 219 }
destinyXfate 2:0e2ef1edf01b 220 png_memcpy(text, chunkdata, prefix_size);
destinyXfate 2:0e2ef1edf01b 221 }
destinyXfate 2:0e2ef1edf01b 222
destinyXfate 2:0e2ef1edf01b 223 text[text_size - 1] = 0x00;
destinyXfate 2:0e2ef1edf01b 224
destinyXfate 2:0e2ef1edf01b 225 /* Copy what we can of the error message into the text chunk */
destinyXfate 2:0e2ef1edf01b 226 text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
destinyXfate 2:0e2ef1edf01b 227 text_size = png_sizeof(msg) > text_size ? text_size :
destinyXfate 2:0e2ef1edf01b 228 png_sizeof(msg);
destinyXfate 2:0e2ef1edf01b 229 png_memcpy(text + prefix_size, msg, text_size + 1);
destinyXfate 2:0e2ef1edf01b 230 break;
destinyXfate 2:0e2ef1edf01b 231 }
destinyXfate 2:0e2ef1edf01b 232 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
destinyXfate 2:0e2ef1edf01b 233 {
destinyXfate 2:0e2ef1edf01b 234 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 235 {
destinyXfate 2:0e2ef1edf01b 236 text_size = prefix_size +
destinyXfate 2:0e2ef1edf01b 237 png_ptr->zbuf_size - png_ptr->zstream.avail_out;
destinyXfate 2:0e2ef1edf01b 238 text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
destinyXfate 2:0e2ef1edf01b 239 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 240 {
destinyXfate 2:0e2ef1edf01b 241 png_free(png_ptr,chunkdata);
destinyXfate 2:0e2ef1edf01b 242 png_error(png_ptr,"Not enough memory to decompress chunk.");
destinyXfate 2:0e2ef1edf01b 243 }
destinyXfate 2:0e2ef1edf01b 244 png_memcpy(text + prefix_size, png_ptr->zbuf,
destinyXfate 2:0e2ef1edf01b 245 text_size - prefix_size);
destinyXfate 2:0e2ef1edf01b 246 png_memcpy(text, chunkdata, prefix_size);
destinyXfate 2:0e2ef1edf01b 247 *(text + text_size) = 0x00;
destinyXfate 2:0e2ef1edf01b 248 }
destinyXfate 2:0e2ef1edf01b 249 else
destinyXfate 2:0e2ef1edf01b 250 {
destinyXfate 2:0e2ef1edf01b 251 png_charp tmp;
destinyXfate 2:0e2ef1edf01b 252
destinyXfate 2:0e2ef1edf01b 253 tmp = text;
destinyXfate 2:0e2ef1edf01b 254 text = (png_charp)png_malloc_warn(png_ptr,
destinyXfate 2:0e2ef1edf01b 255 (png_uint_32)(text_size +
destinyXfate 2:0e2ef1edf01b 256 png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
destinyXfate 2:0e2ef1edf01b 257 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 258 {
destinyXfate 2:0e2ef1edf01b 259 png_free(png_ptr, tmp);
destinyXfate 2:0e2ef1edf01b 260 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 261 png_error(png_ptr,"Not enough memory to decompress chunk..");
destinyXfate 2:0e2ef1edf01b 262 }
destinyXfate 2:0e2ef1edf01b 263 png_memcpy(text, tmp, text_size);
destinyXfate 2:0e2ef1edf01b 264 png_free(png_ptr, tmp);
destinyXfate 2:0e2ef1edf01b 265 png_memcpy(text + text_size, png_ptr->zbuf,
destinyXfate 2:0e2ef1edf01b 266 (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
destinyXfate 2:0e2ef1edf01b 267 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
destinyXfate 2:0e2ef1edf01b 268 *(text + text_size) = 0x00;
destinyXfate 2:0e2ef1edf01b 269 }
destinyXfate 2:0e2ef1edf01b 270 if (ret == Z_STREAM_END)
destinyXfate 2:0e2ef1edf01b 271 break;
destinyXfate 2:0e2ef1edf01b 272 else
destinyXfate 2:0e2ef1edf01b 273 {
destinyXfate 2:0e2ef1edf01b 274 png_ptr->zstream.next_out = png_ptr->zbuf;
destinyXfate 2:0e2ef1edf01b 275 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
destinyXfate 2:0e2ef1edf01b 276 }
destinyXfate 2:0e2ef1edf01b 277 }
destinyXfate 2:0e2ef1edf01b 278 }
destinyXfate 2:0e2ef1edf01b 279 if (ret != Z_STREAM_END)
destinyXfate 2:0e2ef1edf01b 280 {
destinyXfate 2:0e2ef1edf01b 281 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
destinyXfate 2:0e2ef1edf01b 282 char umsg[52];
destinyXfate 2:0e2ef1edf01b 283
destinyXfate 2:0e2ef1edf01b 284 if (ret == Z_BUF_ERROR)
destinyXfate 2:0e2ef1edf01b 285 sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
destinyXfate 2:0e2ef1edf01b 286 png_ptr->chunk_name);
destinyXfate 2:0e2ef1edf01b 287 else if (ret == Z_DATA_ERROR)
destinyXfate 2:0e2ef1edf01b 288 sprintf(umsg,"Data error in compressed datastream in %s chunk",
destinyXfate 2:0e2ef1edf01b 289 png_ptr->chunk_name);
destinyXfate 2:0e2ef1edf01b 290 else
destinyXfate 2:0e2ef1edf01b 291 sprintf(umsg,"Incomplete compressed datastream in %s chunk",
destinyXfate 2:0e2ef1edf01b 292 png_ptr->chunk_name);
destinyXfate 2:0e2ef1edf01b 293 png_warning(png_ptr, umsg);
destinyXfate 2:0e2ef1edf01b 294 #else
destinyXfate 2:0e2ef1edf01b 295 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 296 "Incomplete compressed datastream in chunk other than IDAT");
destinyXfate 2:0e2ef1edf01b 297 #endif
destinyXfate 2:0e2ef1edf01b 298 text_size=prefix_size;
destinyXfate 2:0e2ef1edf01b 299 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 300 {
destinyXfate 2:0e2ef1edf01b 301 text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
destinyXfate 2:0e2ef1edf01b 302 if (text == NULL)
destinyXfate 2:0e2ef1edf01b 303 {
destinyXfate 2:0e2ef1edf01b 304 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 305 png_error(png_ptr,"Not enough memory for text.");
destinyXfate 2:0e2ef1edf01b 306 }
destinyXfate 2:0e2ef1edf01b 307 png_memcpy(text, chunkdata, prefix_size);
destinyXfate 2:0e2ef1edf01b 308 }
destinyXfate 2:0e2ef1edf01b 309 *(text + text_size) = 0x00;
destinyXfate 2:0e2ef1edf01b 310 }
destinyXfate 2:0e2ef1edf01b 311
destinyXfate 2:0e2ef1edf01b 312 inflateReset(&png_ptr->zstream);
destinyXfate 2:0e2ef1edf01b 313 png_ptr->zstream.avail_in = 0;
destinyXfate 2:0e2ef1edf01b 314
destinyXfate 2:0e2ef1edf01b 315 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 316 chunkdata = text;
destinyXfate 2:0e2ef1edf01b 317 *newlength=text_size;
destinyXfate 2:0e2ef1edf01b 318 }
destinyXfate 2:0e2ef1edf01b 319 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
destinyXfate 2:0e2ef1edf01b 320 {
destinyXfate 2:0e2ef1edf01b 321 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
destinyXfate 2:0e2ef1edf01b 322 char umsg[50];
destinyXfate 2:0e2ef1edf01b 323
destinyXfate 2:0e2ef1edf01b 324 sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
destinyXfate 2:0e2ef1edf01b 325 png_warning(png_ptr, umsg);
destinyXfate 2:0e2ef1edf01b 326 #else
destinyXfate 2:0e2ef1edf01b 327 png_warning(png_ptr, "Unknown zTXt compression type");
destinyXfate 2:0e2ef1edf01b 328 #endif
destinyXfate 2:0e2ef1edf01b 329
destinyXfate 2:0e2ef1edf01b 330 *(chunkdata + prefix_size) = 0x00;
destinyXfate 2:0e2ef1edf01b 331 *newlength=prefix_size;
destinyXfate 2:0e2ef1edf01b 332 }
destinyXfate 2:0e2ef1edf01b 333
destinyXfate 2:0e2ef1edf01b 334 return chunkdata;
destinyXfate 2:0e2ef1edf01b 335 }
destinyXfate 2:0e2ef1edf01b 336 #endif
destinyXfate 2:0e2ef1edf01b 337
destinyXfate 2:0e2ef1edf01b 338 /* read and check the IDHR chunk */
destinyXfate 2:0e2ef1edf01b 339 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 340 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 341 {
destinyXfate 2:0e2ef1edf01b 342 png_byte buf[13];
destinyXfate 2:0e2ef1edf01b 343 png_uint_32 width, height;
destinyXfate 2:0e2ef1edf01b 344 int bit_depth, color_type, compression_type, filter_type;
destinyXfate 2:0e2ef1edf01b 345 int interlace_type;
destinyXfate 2:0e2ef1edf01b 346
destinyXfate 2:0e2ef1edf01b 347 png_debug(1, "in png_handle_IHDR\n");
destinyXfate 2:0e2ef1edf01b 348
destinyXfate 2:0e2ef1edf01b 349 if (png_ptr->mode & PNG_HAVE_IHDR)
destinyXfate 2:0e2ef1edf01b 350 png_error(png_ptr, "Out of place IHDR");
destinyXfate 2:0e2ef1edf01b 351
destinyXfate 2:0e2ef1edf01b 352 /* check the length */
destinyXfate 2:0e2ef1edf01b 353 if (length != 13)
destinyXfate 2:0e2ef1edf01b 354 png_error(png_ptr, "Invalid IHDR chunk");
destinyXfate 2:0e2ef1edf01b 355
destinyXfate 2:0e2ef1edf01b 356 png_ptr->mode |= PNG_HAVE_IHDR;
destinyXfate 2:0e2ef1edf01b 357
destinyXfate 2:0e2ef1edf01b 358 png_crc_read(png_ptr, buf, 13);
destinyXfate 2:0e2ef1edf01b 359 png_crc_finish(png_ptr, 0);
destinyXfate 2:0e2ef1edf01b 360
destinyXfate 2:0e2ef1edf01b 361 width = png_get_uint_31(png_ptr, buf);
destinyXfate 2:0e2ef1edf01b 362 height = png_get_uint_31(png_ptr, buf + 4);
destinyXfate 2:0e2ef1edf01b 363 bit_depth = buf[8];
destinyXfate 2:0e2ef1edf01b 364 color_type = buf[9];
destinyXfate 2:0e2ef1edf01b 365 compression_type = buf[10];
destinyXfate 2:0e2ef1edf01b 366 filter_type = buf[11];
destinyXfate 2:0e2ef1edf01b 367 interlace_type = buf[12];
destinyXfate 2:0e2ef1edf01b 368
destinyXfate 2:0e2ef1edf01b 369 /* set internal variables */
destinyXfate 2:0e2ef1edf01b 370 png_ptr->width = width;
destinyXfate 2:0e2ef1edf01b 371 png_ptr->height = height;
destinyXfate 2:0e2ef1edf01b 372 png_ptr->bit_depth = (png_byte)bit_depth;
destinyXfate 2:0e2ef1edf01b 373 png_ptr->interlaced = (png_byte)interlace_type;
destinyXfate 2:0e2ef1edf01b 374 png_ptr->color_type = (png_byte)color_type;
destinyXfate 2:0e2ef1edf01b 375 #if defined(PNG_MNG_FEATURES_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 376 png_ptr->filter_type = (png_byte)filter_type;
destinyXfate 2:0e2ef1edf01b 377 #endif
destinyXfate 2:0e2ef1edf01b 378 png_ptr->compression_type = (png_byte)compression_type;
destinyXfate 2:0e2ef1edf01b 379
destinyXfate 2:0e2ef1edf01b 380 /* find number of channels */
destinyXfate 2:0e2ef1edf01b 381 switch (png_ptr->color_type)
destinyXfate 2:0e2ef1edf01b 382 {
destinyXfate 2:0e2ef1edf01b 383 case PNG_COLOR_TYPE_GRAY:
destinyXfate 2:0e2ef1edf01b 384 case PNG_COLOR_TYPE_PALETTE:
destinyXfate 2:0e2ef1edf01b 385 png_ptr->channels = 1;
destinyXfate 2:0e2ef1edf01b 386 break;
destinyXfate 2:0e2ef1edf01b 387 case PNG_COLOR_TYPE_RGB:
destinyXfate 2:0e2ef1edf01b 388 png_ptr->channels = 3;
destinyXfate 2:0e2ef1edf01b 389 break;
destinyXfate 2:0e2ef1edf01b 390 case PNG_COLOR_TYPE_GRAY_ALPHA:
destinyXfate 2:0e2ef1edf01b 391 png_ptr->channels = 2;
destinyXfate 2:0e2ef1edf01b 392 break;
destinyXfate 2:0e2ef1edf01b 393 case PNG_COLOR_TYPE_RGB_ALPHA:
destinyXfate 2:0e2ef1edf01b 394 png_ptr->channels = 4;
destinyXfate 2:0e2ef1edf01b 395 break;
destinyXfate 2:0e2ef1edf01b 396 }
destinyXfate 2:0e2ef1edf01b 397
destinyXfate 2:0e2ef1edf01b 398 /* set up other useful info */
destinyXfate 2:0e2ef1edf01b 399 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
destinyXfate 2:0e2ef1edf01b 400 png_ptr->channels);
destinyXfate 2:0e2ef1edf01b 401 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
destinyXfate 2:0e2ef1edf01b 402 png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
destinyXfate 2:0e2ef1edf01b 403 png_debug1(3,"channels = %d\n", png_ptr->channels);
destinyXfate 2:0e2ef1edf01b 404 png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
destinyXfate 2:0e2ef1edf01b 405 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
destinyXfate 2:0e2ef1edf01b 406 color_type, interlace_type, compression_type, filter_type);
destinyXfate 2:0e2ef1edf01b 407 }
destinyXfate 2:0e2ef1edf01b 408
destinyXfate 2:0e2ef1edf01b 409 /* read and check the palette */
destinyXfate 2:0e2ef1edf01b 410 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 411 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 412 {
destinyXfate 2:0e2ef1edf01b 413 png_color palette[PNG_MAX_PALETTE_LENGTH];
destinyXfate 2:0e2ef1edf01b 414 int num, i;
destinyXfate 2:0e2ef1edf01b 415 #ifndef PNG_NO_POINTER_INDEXING
destinyXfate 2:0e2ef1edf01b 416 png_colorp pal_ptr;
destinyXfate 2:0e2ef1edf01b 417 #endif
destinyXfate 2:0e2ef1edf01b 418
destinyXfate 2:0e2ef1edf01b 419 png_debug(1, "in png_handle_PLTE\n");
destinyXfate 2:0e2ef1edf01b 420
destinyXfate 2:0e2ef1edf01b 421 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 422 png_error(png_ptr, "Missing IHDR before PLTE");
destinyXfate 2:0e2ef1edf01b 423 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 424 {
destinyXfate 2:0e2ef1edf01b 425 png_warning(png_ptr, "Invalid PLTE after IDAT");
destinyXfate 2:0e2ef1edf01b 426 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 427 return;
destinyXfate 2:0e2ef1edf01b 428 }
destinyXfate 2:0e2ef1edf01b 429 else if (png_ptr->mode & PNG_HAVE_PLTE)
destinyXfate 2:0e2ef1edf01b 430 png_error(png_ptr, "Duplicate PLTE chunk");
destinyXfate 2:0e2ef1edf01b 431
destinyXfate 2:0e2ef1edf01b 432 png_ptr->mode |= PNG_HAVE_PLTE;
destinyXfate 2:0e2ef1edf01b 433
destinyXfate 2:0e2ef1edf01b 434 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
destinyXfate 2:0e2ef1edf01b 435 {
destinyXfate 2:0e2ef1edf01b 436 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 437 "Ignoring PLTE chunk in grayscale PNG");
destinyXfate 2:0e2ef1edf01b 438 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 439 return;
destinyXfate 2:0e2ef1edf01b 440 }
destinyXfate 2:0e2ef1edf01b 441 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 442 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 443 {
destinyXfate 2:0e2ef1edf01b 444 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 445 return;
destinyXfate 2:0e2ef1edf01b 446 }
destinyXfate 2:0e2ef1edf01b 447 #endif
destinyXfate 2:0e2ef1edf01b 448
destinyXfate 2:0e2ef1edf01b 449 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
destinyXfate 2:0e2ef1edf01b 450 {
destinyXfate 2:0e2ef1edf01b 451 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 452 {
destinyXfate 2:0e2ef1edf01b 453 png_warning(png_ptr, "Invalid palette chunk");
destinyXfate 2:0e2ef1edf01b 454 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 455 return;
destinyXfate 2:0e2ef1edf01b 456 }
destinyXfate 2:0e2ef1edf01b 457 else
destinyXfate 2:0e2ef1edf01b 458 {
destinyXfate 2:0e2ef1edf01b 459 png_error(png_ptr, "Invalid palette chunk");
destinyXfate 2:0e2ef1edf01b 460 }
destinyXfate 2:0e2ef1edf01b 461 }
destinyXfate 2:0e2ef1edf01b 462
destinyXfate 2:0e2ef1edf01b 463 num = (int)length / 3;
destinyXfate 2:0e2ef1edf01b 464
destinyXfate 2:0e2ef1edf01b 465 #ifndef PNG_NO_POINTER_INDEXING
destinyXfate 2:0e2ef1edf01b 466 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
destinyXfate 2:0e2ef1edf01b 467 {
destinyXfate 2:0e2ef1edf01b 468 png_byte buf[3];
destinyXfate 2:0e2ef1edf01b 469
destinyXfate 2:0e2ef1edf01b 470 png_crc_read(png_ptr, buf, 3);
destinyXfate 2:0e2ef1edf01b 471 pal_ptr->red = buf[0];
destinyXfate 2:0e2ef1edf01b 472 pal_ptr->green = buf[1];
destinyXfate 2:0e2ef1edf01b 473 pal_ptr->blue = buf[2];
destinyXfate 2:0e2ef1edf01b 474 }
destinyXfate 2:0e2ef1edf01b 475 #else
destinyXfate 2:0e2ef1edf01b 476 for (i = 0; i < num; i++)
destinyXfate 2:0e2ef1edf01b 477 {
destinyXfate 2:0e2ef1edf01b 478 png_byte buf[3];
destinyXfate 2:0e2ef1edf01b 479
destinyXfate 2:0e2ef1edf01b 480 png_crc_read(png_ptr, buf, 3);
destinyXfate 2:0e2ef1edf01b 481 /* don't depend upon png_color being any order */
destinyXfate 2:0e2ef1edf01b 482 palette[i].red = buf[0];
destinyXfate 2:0e2ef1edf01b 483 palette[i].green = buf[1];
destinyXfate 2:0e2ef1edf01b 484 palette[i].blue = buf[2];
destinyXfate 2:0e2ef1edf01b 485 }
destinyXfate 2:0e2ef1edf01b 486 #endif
destinyXfate 2:0e2ef1edf01b 487
destinyXfate 2:0e2ef1edf01b 488 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
destinyXfate 2:0e2ef1edf01b 489 whatever the normal CRC configuration tells us. However, if we
destinyXfate 2:0e2ef1edf01b 490 have an RGB image, the PLTE can be considered ancillary, so
destinyXfate 2:0e2ef1edf01b 491 we will act as though it is. */
destinyXfate 2:0e2ef1edf01b 492 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 493 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 494 #endif
destinyXfate 2:0e2ef1edf01b 495 {
destinyXfate 2:0e2ef1edf01b 496 png_crc_finish(png_ptr, 0);
destinyXfate 2:0e2ef1edf01b 497 }
destinyXfate 2:0e2ef1edf01b 498 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 499 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
destinyXfate 2:0e2ef1edf01b 500 {
destinyXfate 2:0e2ef1edf01b 501 /* If we don't want to use the data from an ancillary chunk,
destinyXfate 2:0e2ef1edf01b 502 we have two options: an error abort, or a warning and we
destinyXfate 2:0e2ef1edf01b 503 ignore the data in this chunk (which should be OK, since
destinyXfate 2:0e2ef1edf01b 504 it's considered ancillary for a RGB or RGBA image). */
destinyXfate 2:0e2ef1edf01b 505 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
destinyXfate 2:0e2ef1edf01b 506 {
destinyXfate 2:0e2ef1edf01b 507 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
destinyXfate 2:0e2ef1edf01b 508 {
destinyXfate 2:0e2ef1edf01b 509 png_chunk_error(png_ptr, "CRC error");
destinyXfate 2:0e2ef1edf01b 510 }
destinyXfate 2:0e2ef1edf01b 511 else
destinyXfate 2:0e2ef1edf01b 512 {
destinyXfate 2:0e2ef1edf01b 513 png_chunk_warning(png_ptr, "CRC error");
destinyXfate 2:0e2ef1edf01b 514 return;
destinyXfate 2:0e2ef1edf01b 515 }
destinyXfate 2:0e2ef1edf01b 516 }
destinyXfate 2:0e2ef1edf01b 517 /* Otherwise, we (optionally) emit a warning and use the chunk. */
destinyXfate 2:0e2ef1edf01b 518 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
destinyXfate 2:0e2ef1edf01b 519 {
destinyXfate 2:0e2ef1edf01b 520 png_chunk_warning(png_ptr, "CRC error");
destinyXfate 2:0e2ef1edf01b 521 }
destinyXfate 2:0e2ef1edf01b 522 }
destinyXfate 2:0e2ef1edf01b 523 #endif
destinyXfate 2:0e2ef1edf01b 524
destinyXfate 2:0e2ef1edf01b 525 png_set_PLTE(png_ptr, info_ptr, palette, num);
destinyXfate 2:0e2ef1edf01b 526
destinyXfate 2:0e2ef1edf01b 527 #if defined(PNG_READ_tRNS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 528 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 529 {
destinyXfate 2:0e2ef1edf01b 530 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
destinyXfate 2:0e2ef1edf01b 531 {
destinyXfate 2:0e2ef1edf01b 532 if (png_ptr->num_trans > (png_uint_16)num)
destinyXfate 2:0e2ef1edf01b 533 {
destinyXfate 2:0e2ef1edf01b 534 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
destinyXfate 2:0e2ef1edf01b 535 png_ptr->num_trans = (png_uint_16)num;
destinyXfate 2:0e2ef1edf01b 536 }
destinyXfate 2:0e2ef1edf01b 537 if (info_ptr->num_trans > (png_uint_16)num)
destinyXfate 2:0e2ef1edf01b 538 {
destinyXfate 2:0e2ef1edf01b 539 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
destinyXfate 2:0e2ef1edf01b 540 info_ptr->num_trans = (png_uint_16)num;
destinyXfate 2:0e2ef1edf01b 541 }
destinyXfate 2:0e2ef1edf01b 542 }
destinyXfate 2:0e2ef1edf01b 543 }
destinyXfate 2:0e2ef1edf01b 544 #endif
destinyXfate 2:0e2ef1edf01b 545
destinyXfate 2:0e2ef1edf01b 546 }
destinyXfate 2:0e2ef1edf01b 547
destinyXfate 2:0e2ef1edf01b 548 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 549 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 550 {
destinyXfate 2:0e2ef1edf01b 551 png_debug(1, "in png_handle_IEND\n");
destinyXfate 2:0e2ef1edf01b 552
destinyXfate 2:0e2ef1edf01b 553 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
destinyXfate 2:0e2ef1edf01b 554 {
destinyXfate 2:0e2ef1edf01b 555 png_error(png_ptr, "No image in file");
destinyXfate 2:0e2ef1edf01b 556 }
destinyXfate 2:0e2ef1edf01b 557
destinyXfate 2:0e2ef1edf01b 558 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
destinyXfate 2:0e2ef1edf01b 559
destinyXfate 2:0e2ef1edf01b 560 if (length != 0)
destinyXfate 2:0e2ef1edf01b 561 {
destinyXfate 2:0e2ef1edf01b 562 png_warning(png_ptr, "Incorrect IEND chunk length");
destinyXfate 2:0e2ef1edf01b 563 }
destinyXfate 2:0e2ef1edf01b 564 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 565
destinyXfate 2:0e2ef1edf01b 566 if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
destinyXfate 2:0e2ef1edf01b 567 return;
destinyXfate 2:0e2ef1edf01b 568 }
destinyXfate 2:0e2ef1edf01b 569
destinyXfate 2:0e2ef1edf01b 570 #if defined(PNG_READ_gAMA_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 571 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 572 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 573 {
destinyXfate 2:0e2ef1edf01b 574 png_fixed_point igamma;
destinyXfate 2:0e2ef1edf01b 575 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 576 float file_gamma;
destinyXfate 2:0e2ef1edf01b 577 #endif
destinyXfate 2:0e2ef1edf01b 578 png_byte buf[4];
destinyXfate 2:0e2ef1edf01b 579
destinyXfate 2:0e2ef1edf01b 580 png_debug(1, "in png_handle_gAMA\n");
destinyXfate 2:0e2ef1edf01b 581
destinyXfate 2:0e2ef1edf01b 582 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 583 png_error(png_ptr, "Missing IHDR before gAMA");
destinyXfate 2:0e2ef1edf01b 584 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 585 {
destinyXfate 2:0e2ef1edf01b 586 png_warning(png_ptr, "Invalid gAMA after IDAT");
destinyXfate 2:0e2ef1edf01b 587 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 588 return;
destinyXfate 2:0e2ef1edf01b 589 }
destinyXfate 2:0e2ef1edf01b 590 else if (png_ptr->mode & PNG_HAVE_PLTE)
destinyXfate 2:0e2ef1edf01b 591 /* Should be an error, but we can cope with it */
destinyXfate 2:0e2ef1edf01b 592 png_warning(png_ptr, "Out of place gAMA chunk");
destinyXfate 2:0e2ef1edf01b 593
destinyXfate 2:0e2ef1edf01b 594 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
destinyXfate 2:0e2ef1edf01b 595 #if defined(PNG_READ_sRGB_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 596 && !(info_ptr->valid & PNG_INFO_sRGB)
destinyXfate 2:0e2ef1edf01b 597 #endif
destinyXfate 2:0e2ef1edf01b 598 )
destinyXfate 2:0e2ef1edf01b 599 {
destinyXfate 2:0e2ef1edf01b 600 png_warning(png_ptr, "Duplicate gAMA chunk");
destinyXfate 2:0e2ef1edf01b 601 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 602 return;
destinyXfate 2:0e2ef1edf01b 603 }
destinyXfate 2:0e2ef1edf01b 604
destinyXfate 2:0e2ef1edf01b 605 if (length != 4)
destinyXfate 2:0e2ef1edf01b 606 {
destinyXfate 2:0e2ef1edf01b 607 png_warning(png_ptr, "Incorrect gAMA chunk length");
destinyXfate 2:0e2ef1edf01b 608 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 609 return;
destinyXfate 2:0e2ef1edf01b 610 }
destinyXfate 2:0e2ef1edf01b 611
destinyXfate 2:0e2ef1edf01b 612 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 613 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 614 return;
destinyXfate 2:0e2ef1edf01b 615
destinyXfate 2:0e2ef1edf01b 616 igamma = (png_fixed_point)png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 617 /* check for zero gamma */
destinyXfate 2:0e2ef1edf01b 618 if (igamma == 0)
destinyXfate 2:0e2ef1edf01b 619 {
destinyXfate 2:0e2ef1edf01b 620 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 621 "Ignoring gAMA chunk with gamma=0");
destinyXfate 2:0e2ef1edf01b 622 return;
destinyXfate 2:0e2ef1edf01b 623 }
destinyXfate 2:0e2ef1edf01b 624
destinyXfate 2:0e2ef1edf01b 625 #if defined(PNG_READ_sRGB_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 626 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
destinyXfate 2:0e2ef1edf01b 627 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
destinyXfate 2:0e2ef1edf01b 628 {
destinyXfate 2:0e2ef1edf01b 629 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 630 "Ignoring incorrect gAMA value when sRGB is also present");
destinyXfate 2:0e2ef1edf01b 631 #ifndef PNG_NO_CONSOLE_IO
destinyXfate 2:0e2ef1edf01b 632 fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
destinyXfate 2:0e2ef1edf01b 633 #endif
destinyXfate 2:0e2ef1edf01b 634 return;
destinyXfate 2:0e2ef1edf01b 635 }
destinyXfate 2:0e2ef1edf01b 636 #endif /* PNG_READ_sRGB_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 637
destinyXfate 2:0e2ef1edf01b 638 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 639 file_gamma = (float)igamma / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 640 # ifdef PNG_READ_GAMMA_SUPPORTED
destinyXfate 2:0e2ef1edf01b 641 png_ptr->gamma = file_gamma;
destinyXfate 2:0e2ef1edf01b 642 # endif
destinyXfate 2:0e2ef1edf01b 643 png_set_gAMA(png_ptr, info_ptr, file_gamma);
destinyXfate 2:0e2ef1edf01b 644 #endif
destinyXfate 2:0e2ef1edf01b 645 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 646 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
destinyXfate 2:0e2ef1edf01b 647 #endif
destinyXfate 2:0e2ef1edf01b 648 }
destinyXfate 2:0e2ef1edf01b 649 #endif
destinyXfate 2:0e2ef1edf01b 650
destinyXfate 2:0e2ef1edf01b 651 #if defined(PNG_READ_sBIT_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 652 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 653 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 654 {
destinyXfate 2:0e2ef1edf01b 655 png_size_t truelen;
destinyXfate 2:0e2ef1edf01b 656 png_byte buf[4];
destinyXfate 2:0e2ef1edf01b 657
destinyXfate 2:0e2ef1edf01b 658 png_debug(1, "in png_handle_sBIT\n");
destinyXfate 2:0e2ef1edf01b 659
destinyXfate 2:0e2ef1edf01b 660 buf[0] = buf[1] = buf[2] = buf[3] = 0;
destinyXfate 2:0e2ef1edf01b 661
destinyXfate 2:0e2ef1edf01b 662 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 663 png_error(png_ptr, "Missing IHDR before sBIT");
destinyXfate 2:0e2ef1edf01b 664 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 665 {
destinyXfate 2:0e2ef1edf01b 666 png_warning(png_ptr, "Invalid sBIT after IDAT");
destinyXfate 2:0e2ef1edf01b 667 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 668 return;
destinyXfate 2:0e2ef1edf01b 669 }
destinyXfate 2:0e2ef1edf01b 670 else if (png_ptr->mode & PNG_HAVE_PLTE)
destinyXfate 2:0e2ef1edf01b 671 {
destinyXfate 2:0e2ef1edf01b 672 /* Should be an error, but we can cope with it */
destinyXfate 2:0e2ef1edf01b 673 png_warning(png_ptr, "Out of place sBIT chunk");
destinyXfate 2:0e2ef1edf01b 674 }
destinyXfate 2:0e2ef1edf01b 675 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
destinyXfate 2:0e2ef1edf01b 676 {
destinyXfate 2:0e2ef1edf01b 677 png_warning(png_ptr, "Duplicate sBIT chunk");
destinyXfate 2:0e2ef1edf01b 678 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 679 return;
destinyXfate 2:0e2ef1edf01b 680 }
destinyXfate 2:0e2ef1edf01b 681
destinyXfate 2:0e2ef1edf01b 682 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 683 truelen = 3;
destinyXfate 2:0e2ef1edf01b 684 else
destinyXfate 2:0e2ef1edf01b 685 truelen = (png_size_t)png_ptr->channels;
destinyXfate 2:0e2ef1edf01b 686
destinyXfate 2:0e2ef1edf01b 687 if (length != truelen || length > 4)
destinyXfate 2:0e2ef1edf01b 688 {
destinyXfate 2:0e2ef1edf01b 689 png_warning(png_ptr, "Incorrect sBIT chunk length");
destinyXfate 2:0e2ef1edf01b 690 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 691 return;
destinyXfate 2:0e2ef1edf01b 692 }
destinyXfate 2:0e2ef1edf01b 693
destinyXfate 2:0e2ef1edf01b 694 png_crc_read(png_ptr, buf, truelen);
destinyXfate 2:0e2ef1edf01b 695 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 696 return;
destinyXfate 2:0e2ef1edf01b 697
destinyXfate 2:0e2ef1edf01b 698 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
destinyXfate 2:0e2ef1edf01b 699 {
destinyXfate 2:0e2ef1edf01b 700 png_ptr->sig_bit.red = buf[0];
destinyXfate 2:0e2ef1edf01b 701 png_ptr->sig_bit.green = buf[1];
destinyXfate 2:0e2ef1edf01b 702 png_ptr->sig_bit.blue = buf[2];
destinyXfate 2:0e2ef1edf01b 703 png_ptr->sig_bit.alpha = buf[3];
destinyXfate 2:0e2ef1edf01b 704 }
destinyXfate 2:0e2ef1edf01b 705 else
destinyXfate 2:0e2ef1edf01b 706 {
destinyXfate 2:0e2ef1edf01b 707 png_ptr->sig_bit.gray = buf[0];
destinyXfate 2:0e2ef1edf01b 708 png_ptr->sig_bit.red = buf[0];
destinyXfate 2:0e2ef1edf01b 709 png_ptr->sig_bit.green = buf[0];
destinyXfate 2:0e2ef1edf01b 710 png_ptr->sig_bit.blue = buf[0];
destinyXfate 2:0e2ef1edf01b 711 png_ptr->sig_bit.alpha = buf[1];
destinyXfate 2:0e2ef1edf01b 712 }
destinyXfate 2:0e2ef1edf01b 713 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
destinyXfate 2:0e2ef1edf01b 714 }
destinyXfate 2:0e2ef1edf01b 715 #endif
destinyXfate 2:0e2ef1edf01b 716
destinyXfate 2:0e2ef1edf01b 717 #if defined(PNG_READ_cHRM_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 718 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 719 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 720 {
destinyXfate 2:0e2ef1edf01b 721 png_byte buf[4];
destinyXfate 2:0e2ef1edf01b 722 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 723 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
destinyXfate 2:0e2ef1edf01b 724 #endif
destinyXfate 2:0e2ef1edf01b 725 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
destinyXfate 2:0e2ef1edf01b 726 int_y_green, int_x_blue, int_y_blue;
destinyXfate 2:0e2ef1edf01b 727
destinyXfate 2:0e2ef1edf01b 728 png_uint_32 uint_x, uint_y;
destinyXfate 2:0e2ef1edf01b 729
destinyXfate 2:0e2ef1edf01b 730 png_debug(1, "in png_handle_cHRM\n");
destinyXfate 2:0e2ef1edf01b 731
destinyXfate 2:0e2ef1edf01b 732 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 733 png_error(png_ptr, "Missing IHDR before cHRM");
destinyXfate 2:0e2ef1edf01b 734 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 735 {
destinyXfate 2:0e2ef1edf01b 736 png_warning(png_ptr, "Invalid cHRM after IDAT");
destinyXfate 2:0e2ef1edf01b 737 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 738 return;
destinyXfate 2:0e2ef1edf01b 739 }
destinyXfate 2:0e2ef1edf01b 740 else if (png_ptr->mode & PNG_HAVE_PLTE)
destinyXfate 2:0e2ef1edf01b 741 /* Should be an error, but we can cope with it */
destinyXfate 2:0e2ef1edf01b 742 png_warning(png_ptr, "Missing PLTE before cHRM");
destinyXfate 2:0e2ef1edf01b 743
destinyXfate 2:0e2ef1edf01b 744 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
destinyXfate 2:0e2ef1edf01b 745 #if defined(PNG_READ_sRGB_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 746 && !(info_ptr->valid & PNG_INFO_sRGB)
destinyXfate 2:0e2ef1edf01b 747 #endif
destinyXfate 2:0e2ef1edf01b 748 )
destinyXfate 2:0e2ef1edf01b 749 {
destinyXfate 2:0e2ef1edf01b 750 png_warning(png_ptr, "Duplicate cHRM chunk");
destinyXfate 2:0e2ef1edf01b 751 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 752 return;
destinyXfate 2:0e2ef1edf01b 753 }
destinyXfate 2:0e2ef1edf01b 754
destinyXfate 2:0e2ef1edf01b 755 if (length != 32)
destinyXfate 2:0e2ef1edf01b 756 {
destinyXfate 2:0e2ef1edf01b 757 png_warning(png_ptr, "Incorrect cHRM chunk length");
destinyXfate 2:0e2ef1edf01b 758 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 759 return;
destinyXfate 2:0e2ef1edf01b 760 }
destinyXfate 2:0e2ef1edf01b 761
destinyXfate 2:0e2ef1edf01b 762 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 763 uint_x = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 764
destinyXfate 2:0e2ef1edf01b 765 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 766 uint_y = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 767
destinyXfate 2:0e2ef1edf01b 768 if (uint_x > 80000L || uint_y > 80000L ||
destinyXfate 2:0e2ef1edf01b 769 uint_x + uint_y > 100000L)
destinyXfate 2:0e2ef1edf01b 770 {
destinyXfate 2:0e2ef1edf01b 771 png_warning(png_ptr, "Invalid cHRM white point");
destinyXfate 2:0e2ef1edf01b 772 png_crc_finish(png_ptr, 24);
destinyXfate 2:0e2ef1edf01b 773 return;
destinyXfate 2:0e2ef1edf01b 774 }
destinyXfate 2:0e2ef1edf01b 775 int_x_white = (png_fixed_point)uint_x;
destinyXfate 2:0e2ef1edf01b 776 int_y_white = (png_fixed_point)uint_y;
destinyXfate 2:0e2ef1edf01b 777
destinyXfate 2:0e2ef1edf01b 778 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 779 uint_x = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 780
destinyXfate 2:0e2ef1edf01b 781 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 782 uint_y = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 783
destinyXfate 2:0e2ef1edf01b 784 if (uint_x + uint_y > 100000L)
destinyXfate 2:0e2ef1edf01b 785 {
destinyXfate 2:0e2ef1edf01b 786 png_warning(png_ptr, "Invalid cHRM red point");
destinyXfate 2:0e2ef1edf01b 787 png_crc_finish(png_ptr, 16);
destinyXfate 2:0e2ef1edf01b 788 return;
destinyXfate 2:0e2ef1edf01b 789 }
destinyXfate 2:0e2ef1edf01b 790 int_x_red = (png_fixed_point)uint_x;
destinyXfate 2:0e2ef1edf01b 791 int_y_red = (png_fixed_point)uint_y;
destinyXfate 2:0e2ef1edf01b 792
destinyXfate 2:0e2ef1edf01b 793 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 794 uint_x = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 795
destinyXfate 2:0e2ef1edf01b 796 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 797 uint_y = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 798
destinyXfate 2:0e2ef1edf01b 799 if (uint_x + uint_y > 100000L)
destinyXfate 2:0e2ef1edf01b 800 {
destinyXfate 2:0e2ef1edf01b 801 png_warning(png_ptr, "Invalid cHRM green point");
destinyXfate 2:0e2ef1edf01b 802 png_crc_finish(png_ptr, 8);
destinyXfate 2:0e2ef1edf01b 803 return;
destinyXfate 2:0e2ef1edf01b 804 }
destinyXfate 2:0e2ef1edf01b 805 int_x_green = (png_fixed_point)uint_x;
destinyXfate 2:0e2ef1edf01b 806 int_y_green = (png_fixed_point)uint_y;
destinyXfate 2:0e2ef1edf01b 807
destinyXfate 2:0e2ef1edf01b 808 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 809 uint_x = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 810
destinyXfate 2:0e2ef1edf01b 811 png_crc_read(png_ptr, buf, 4);
destinyXfate 2:0e2ef1edf01b 812 uint_y = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 813
destinyXfate 2:0e2ef1edf01b 814 if (uint_x + uint_y > 100000L)
destinyXfate 2:0e2ef1edf01b 815 {
destinyXfate 2:0e2ef1edf01b 816 png_warning(png_ptr, "Invalid cHRM blue point");
destinyXfate 2:0e2ef1edf01b 817 png_crc_finish(png_ptr, 0);
destinyXfate 2:0e2ef1edf01b 818 return;
destinyXfate 2:0e2ef1edf01b 819 }
destinyXfate 2:0e2ef1edf01b 820 int_x_blue = (png_fixed_point)uint_x;
destinyXfate 2:0e2ef1edf01b 821 int_y_blue = (png_fixed_point)uint_y;
destinyXfate 2:0e2ef1edf01b 822
destinyXfate 2:0e2ef1edf01b 823 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 824 white_x = (float)int_x_white / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 825 white_y = (float)int_y_white / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 826 red_x = (float)int_x_red / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 827 red_y = (float)int_y_red / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 828 green_x = (float)int_x_green / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 829 green_y = (float)int_y_green / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 830 blue_x = (float)int_x_blue / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 831 blue_y = (float)int_y_blue / (float)100000.0;
destinyXfate 2:0e2ef1edf01b 832 #endif
destinyXfate 2:0e2ef1edf01b 833
destinyXfate 2:0e2ef1edf01b 834 #if defined(PNG_READ_sRGB_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 835 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
destinyXfate 2:0e2ef1edf01b 836 {
destinyXfate 2:0e2ef1edf01b 837 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
destinyXfate 2:0e2ef1edf01b 838 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
destinyXfate 2:0e2ef1edf01b 839 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
destinyXfate 2:0e2ef1edf01b 840 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
destinyXfate 2:0e2ef1edf01b 841 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
destinyXfate 2:0e2ef1edf01b 842 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
destinyXfate 2:0e2ef1edf01b 843 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
destinyXfate 2:0e2ef1edf01b 844 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
destinyXfate 2:0e2ef1edf01b 845 {
destinyXfate 2:0e2ef1edf01b 846 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 847 "Ignoring incorrect cHRM value when sRGB is also present");
destinyXfate 2:0e2ef1edf01b 848 #ifndef PNG_NO_CONSOLE_IO
destinyXfate 2:0e2ef1edf01b 849 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 850 fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
destinyXfate 2:0e2ef1edf01b 851 white_x, white_y, red_x, red_y);
destinyXfate 2:0e2ef1edf01b 852 fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
destinyXfate 2:0e2ef1edf01b 853 green_x, green_y, blue_x, blue_y);
destinyXfate 2:0e2ef1edf01b 854 #else
destinyXfate 2:0e2ef1edf01b 855 fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
destinyXfate 2:0e2ef1edf01b 856 int_x_white, int_y_white, int_x_red, int_y_red);
destinyXfate 2:0e2ef1edf01b 857 fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
destinyXfate 2:0e2ef1edf01b 858 int_x_green, int_y_green, int_x_blue, int_y_blue);
destinyXfate 2:0e2ef1edf01b 859 #endif
destinyXfate 2:0e2ef1edf01b 860 #endif /* PNG_NO_CONSOLE_IO */
destinyXfate 2:0e2ef1edf01b 861 }
destinyXfate 2:0e2ef1edf01b 862 png_crc_finish(png_ptr, 0);
destinyXfate 2:0e2ef1edf01b 863 return;
destinyXfate 2:0e2ef1edf01b 864 }
destinyXfate 2:0e2ef1edf01b 865 #endif /* PNG_READ_sRGB_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 866
destinyXfate 2:0e2ef1edf01b 867 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 868 png_set_cHRM(png_ptr, info_ptr,
destinyXfate 2:0e2ef1edf01b 869 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
destinyXfate 2:0e2ef1edf01b 870 #endif
destinyXfate 2:0e2ef1edf01b 871 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 872 png_set_cHRM_fixed(png_ptr, info_ptr,
destinyXfate 2:0e2ef1edf01b 873 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
destinyXfate 2:0e2ef1edf01b 874 int_y_green, int_x_blue, int_y_blue);
destinyXfate 2:0e2ef1edf01b 875 #endif
destinyXfate 2:0e2ef1edf01b 876 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 877 return;
destinyXfate 2:0e2ef1edf01b 878 }
destinyXfate 2:0e2ef1edf01b 879 #endif
destinyXfate 2:0e2ef1edf01b 880
destinyXfate 2:0e2ef1edf01b 881 #if defined(PNG_READ_sRGB_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 882 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 883 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 884 {
destinyXfate 2:0e2ef1edf01b 885 int intent;
destinyXfate 2:0e2ef1edf01b 886 png_byte buf[1];
destinyXfate 2:0e2ef1edf01b 887
destinyXfate 2:0e2ef1edf01b 888 png_debug(1, "in png_handle_sRGB\n");
destinyXfate 2:0e2ef1edf01b 889
destinyXfate 2:0e2ef1edf01b 890 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 891 png_error(png_ptr, "Missing IHDR before sRGB");
destinyXfate 2:0e2ef1edf01b 892 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 893 {
destinyXfate 2:0e2ef1edf01b 894 png_warning(png_ptr, "Invalid sRGB after IDAT");
destinyXfate 2:0e2ef1edf01b 895 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 896 return;
destinyXfate 2:0e2ef1edf01b 897 }
destinyXfate 2:0e2ef1edf01b 898 else if (png_ptr->mode & PNG_HAVE_PLTE)
destinyXfate 2:0e2ef1edf01b 899 /* Should be an error, but we can cope with it */
destinyXfate 2:0e2ef1edf01b 900 png_warning(png_ptr, "Out of place sRGB chunk");
destinyXfate 2:0e2ef1edf01b 901
destinyXfate 2:0e2ef1edf01b 902 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
destinyXfate 2:0e2ef1edf01b 903 {
destinyXfate 2:0e2ef1edf01b 904 png_warning(png_ptr, "Duplicate sRGB chunk");
destinyXfate 2:0e2ef1edf01b 905 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 906 return;
destinyXfate 2:0e2ef1edf01b 907 }
destinyXfate 2:0e2ef1edf01b 908
destinyXfate 2:0e2ef1edf01b 909 if (length != 1)
destinyXfate 2:0e2ef1edf01b 910 {
destinyXfate 2:0e2ef1edf01b 911 png_warning(png_ptr, "Incorrect sRGB chunk length");
destinyXfate 2:0e2ef1edf01b 912 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 913 return;
destinyXfate 2:0e2ef1edf01b 914 }
destinyXfate 2:0e2ef1edf01b 915
destinyXfate 2:0e2ef1edf01b 916 png_crc_read(png_ptr, buf, 1);
destinyXfate 2:0e2ef1edf01b 917 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 918 return;
destinyXfate 2:0e2ef1edf01b 919
destinyXfate 2:0e2ef1edf01b 920 intent = buf[0];
destinyXfate 2:0e2ef1edf01b 921 /* check for bad intent */
destinyXfate 2:0e2ef1edf01b 922 if (intent >= PNG_sRGB_INTENT_LAST)
destinyXfate 2:0e2ef1edf01b 923 {
destinyXfate 2:0e2ef1edf01b 924 png_warning(png_ptr, "Unknown sRGB intent");
destinyXfate 2:0e2ef1edf01b 925 return;
destinyXfate 2:0e2ef1edf01b 926 }
destinyXfate 2:0e2ef1edf01b 927
destinyXfate 2:0e2ef1edf01b 928 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 929 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
destinyXfate 2:0e2ef1edf01b 930 {
destinyXfate 2:0e2ef1edf01b 931 png_fixed_point igamma;
destinyXfate 2:0e2ef1edf01b 932 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 933 igamma=info_ptr->int_gamma;
destinyXfate 2:0e2ef1edf01b 934 #else
destinyXfate 2:0e2ef1edf01b 935 # ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 936 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
destinyXfate 2:0e2ef1edf01b 937 # endif
destinyXfate 2:0e2ef1edf01b 938 #endif
destinyXfate 2:0e2ef1edf01b 939 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
destinyXfate 2:0e2ef1edf01b 940 {
destinyXfate 2:0e2ef1edf01b 941 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 942 "Ignoring incorrect gAMA value when sRGB is also present");
destinyXfate 2:0e2ef1edf01b 943 #ifndef PNG_NO_CONSOLE_IO
destinyXfate 2:0e2ef1edf01b 944 # ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 945 fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
destinyXfate 2:0e2ef1edf01b 946 # else
destinyXfate 2:0e2ef1edf01b 947 # ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 948 fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
destinyXfate 2:0e2ef1edf01b 949 # endif
destinyXfate 2:0e2ef1edf01b 950 # endif
destinyXfate 2:0e2ef1edf01b 951 #endif
destinyXfate 2:0e2ef1edf01b 952 }
destinyXfate 2:0e2ef1edf01b 953 }
destinyXfate 2:0e2ef1edf01b 954 #endif /* PNG_READ_gAMA_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 955
destinyXfate 2:0e2ef1edf01b 956 #ifdef PNG_READ_cHRM_SUPPORTED
destinyXfate 2:0e2ef1edf01b 957 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 958 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
destinyXfate 2:0e2ef1edf01b 959 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
destinyXfate 2:0e2ef1edf01b 960 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
destinyXfate 2:0e2ef1edf01b 961 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
destinyXfate 2:0e2ef1edf01b 962 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
destinyXfate 2:0e2ef1edf01b 963 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
destinyXfate 2:0e2ef1edf01b 964 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
destinyXfate 2:0e2ef1edf01b 965 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
destinyXfate 2:0e2ef1edf01b 966 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
destinyXfate 2:0e2ef1edf01b 967 {
destinyXfate 2:0e2ef1edf01b 968 png_warning(png_ptr,
destinyXfate 2:0e2ef1edf01b 969 "Ignoring incorrect cHRM value when sRGB is also present");
destinyXfate 2:0e2ef1edf01b 970 }
destinyXfate 2:0e2ef1edf01b 971 #endif /* PNG_FIXED_POINT_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 972 #endif /* PNG_READ_cHRM_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 973
destinyXfate 2:0e2ef1edf01b 974 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
destinyXfate 2:0e2ef1edf01b 975 }
destinyXfate 2:0e2ef1edf01b 976 #endif /* PNG_READ_sRGB_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 977
destinyXfate 2:0e2ef1edf01b 978 #if defined(PNG_READ_iCCP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 979 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 980 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 981 /* Note: this does not properly handle chunks that are > 64K under DOS */
destinyXfate 2:0e2ef1edf01b 982 {
destinyXfate 2:0e2ef1edf01b 983 png_charp chunkdata;
destinyXfate 2:0e2ef1edf01b 984 png_byte compression_type;
destinyXfate 2:0e2ef1edf01b 985 png_bytep pC;
destinyXfate 2:0e2ef1edf01b 986 png_charp profile;
destinyXfate 2:0e2ef1edf01b 987 png_uint_32 skip = 0;
destinyXfate 2:0e2ef1edf01b 988 png_uint_32 profile_size, profile_length;
destinyXfate 2:0e2ef1edf01b 989 png_size_t slength, prefix_length, data_length;
destinyXfate 2:0e2ef1edf01b 990
destinyXfate 2:0e2ef1edf01b 991 png_debug(1, "in png_handle_iCCP\n");
destinyXfate 2:0e2ef1edf01b 992
destinyXfate 2:0e2ef1edf01b 993 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 994 png_error(png_ptr, "Missing IHDR before iCCP");
destinyXfate 2:0e2ef1edf01b 995 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 996 {
destinyXfate 2:0e2ef1edf01b 997 png_warning(png_ptr, "Invalid iCCP after IDAT");
destinyXfate 2:0e2ef1edf01b 998 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 999 return;
destinyXfate 2:0e2ef1edf01b 1000 }
destinyXfate 2:0e2ef1edf01b 1001 else if (png_ptr->mode & PNG_HAVE_PLTE)
destinyXfate 2:0e2ef1edf01b 1002 /* Should be an error, but we can cope with it */
destinyXfate 2:0e2ef1edf01b 1003 png_warning(png_ptr, "Out of place iCCP chunk");
destinyXfate 2:0e2ef1edf01b 1004
destinyXfate 2:0e2ef1edf01b 1005 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
destinyXfate 2:0e2ef1edf01b 1006 {
destinyXfate 2:0e2ef1edf01b 1007 png_warning(png_ptr, "Duplicate iCCP chunk");
destinyXfate 2:0e2ef1edf01b 1008 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1009 return;
destinyXfate 2:0e2ef1edf01b 1010 }
destinyXfate 2:0e2ef1edf01b 1011
destinyXfate 2:0e2ef1edf01b 1012 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 1013 if (length > (png_uint_32)65535L)
destinyXfate 2:0e2ef1edf01b 1014 {
destinyXfate 2:0e2ef1edf01b 1015 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
destinyXfate 2:0e2ef1edf01b 1016 skip = length - (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 1017 length = (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 1018 }
destinyXfate 2:0e2ef1edf01b 1019 #endif
destinyXfate 2:0e2ef1edf01b 1020
destinyXfate 2:0e2ef1edf01b 1021 chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 1022 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 1023 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
destinyXfate 2:0e2ef1edf01b 1024
destinyXfate 2:0e2ef1edf01b 1025 if (png_crc_finish(png_ptr, skip))
destinyXfate 2:0e2ef1edf01b 1026 {
destinyXfate 2:0e2ef1edf01b 1027 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1028 return;
destinyXfate 2:0e2ef1edf01b 1029 }
destinyXfate 2:0e2ef1edf01b 1030
destinyXfate 2:0e2ef1edf01b 1031 chunkdata[slength] = 0x00;
destinyXfate 2:0e2ef1edf01b 1032
destinyXfate 2:0e2ef1edf01b 1033 for (profile = chunkdata; *profile; profile++)
destinyXfate 2:0e2ef1edf01b 1034 /* empty loop to find end of name */ ;
destinyXfate 2:0e2ef1edf01b 1035
destinyXfate 2:0e2ef1edf01b 1036 ++profile;
destinyXfate 2:0e2ef1edf01b 1037
destinyXfate 2:0e2ef1edf01b 1038 /* there should be at least one zero (the compression type byte)
destinyXfate 2:0e2ef1edf01b 1039 following the separator, and we should be on it */
destinyXfate 2:0e2ef1edf01b 1040 if ( profile >= chunkdata + slength)
destinyXfate 2:0e2ef1edf01b 1041 {
destinyXfate 2:0e2ef1edf01b 1042 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1043 png_warning(png_ptr, "Malformed iCCP chunk");
destinyXfate 2:0e2ef1edf01b 1044 return;
destinyXfate 2:0e2ef1edf01b 1045 }
destinyXfate 2:0e2ef1edf01b 1046
destinyXfate 2:0e2ef1edf01b 1047 /* compression_type should always be zero */
destinyXfate 2:0e2ef1edf01b 1048 compression_type = *profile++;
destinyXfate 2:0e2ef1edf01b 1049 if (compression_type)
destinyXfate 2:0e2ef1edf01b 1050 {
destinyXfate 2:0e2ef1edf01b 1051 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
destinyXfate 2:0e2ef1edf01b 1052 compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
destinyXfate 2:0e2ef1edf01b 1053 wrote nonzero) */
destinyXfate 2:0e2ef1edf01b 1054 }
destinyXfate 2:0e2ef1edf01b 1055
destinyXfate 2:0e2ef1edf01b 1056 prefix_length = profile - chunkdata;
destinyXfate 2:0e2ef1edf01b 1057 chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
destinyXfate 2:0e2ef1edf01b 1058 slength, prefix_length, &data_length);
destinyXfate 2:0e2ef1edf01b 1059
destinyXfate 2:0e2ef1edf01b 1060 profile_length = data_length - prefix_length;
destinyXfate 2:0e2ef1edf01b 1061
destinyXfate 2:0e2ef1edf01b 1062 if ( prefix_length > data_length || profile_length < 4)
destinyXfate 2:0e2ef1edf01b 1063 {
destinyXfate 2:0e2ef1edf01b 1064 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1065 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
destinyXfate 2:0e2ef1edf01b 1066 return;
destinyXfate 2:0e2ef1edf01b 1067 }
destinyXfate 2:0e2ef1edf01b 1068
destinyXfate 2:0e2ef1edf01b 1069 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
destinyXfate 2:0e2ef1edf01b 1070 pC = (png_bytep)(chunkdata+prefix_length);
destinyXfate 2:0e2ef1edf01b 1071 profile_size = ((*(pC ))<<24) |
destinyXfate 2:0e2ef1edf01b 1072 ((*(pC+1))<<16) |
destinyXfate 2:0e2ef1edf01b 1073 ((*(pC+2))<< 8) |
destinyXfate 2:0e2ef1edf01b 1074 ((*(pC+3)) );
destinyXfate 2:0e2ef1edf01b 1075
destinyXfate 2:0e2ef1edf01b 1076 if(profile_size < profile_length)
destinyXfate 2:0e2ef1edf01b 1077 profile_length = profile_size;
destinyXfate 2:0e2ef1edf01b 1078
destinyXfate 2:0e2ef1edf01b 1079 if(profile_size > profile_length)
destinyXfate 2:0e2ef1edf01b 1080 {
destinyXfate 2:0e2ef1edf01b 1081 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1082 png_warning(png_ptr, "Ignoring truncated iCCP profile.");
destinyXfate 2:0e2ef1edf01b 1083 return;
destinyXfate 2:0e2ef1edf01b 1084 }
destinyXfate 2:0e2ef1edf01b 1085
destinyXfate 2:0e2ef1edf01b 1086 png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
destinyXfate 2:0e2ef1edf01b 1087 chunkdata + prefix_length, profile_length);
destinyXfate 2:0e2ef1edf01b 1088 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1089 }
destinyXfate 2:0e2ef1edf01b 1090 #endif /* PNG_READ_iCCP_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 1091
destinyXfate 2:0e2ef1edf01b 1092 #if defined(PNG_READ_sPLT_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1093 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1094 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1095 /* Note: this does not properly handle chunks that are > 64K under DOS */
destinyXfate 2:0e2ef1edf01b 1096 {
destinyXfate 2:0e2ef1edf01b 1097 png_bytep chunkdata;
destinyXfate 2:0e2ef1edf01b 1098 png_bytep entry_start;
destinyXfate 2:0e2ef1edf01b 1099 png_sPLT_t new_palette;
destinyXfate 2:0e2ef1edf01b 1100 #ifdef PNG_NO_POINTER_INDEXING
destinyXfate 2:0e2ef1edf01b 1101 png_sPLT_entryp pp;
destinyXfate 2:0e2ef1edf01b 1102 #endif
destinyXfate 2:0e2ef1edf01b 1103 int data_length, entry_size, i;
destinyXfate 2:0e2ef1edf01b 1104 png_uint_32 skip = 0;
destinyXfate 2:0e2ef1edf01b 1105 png_size_t slength;
destinyXfate 2:0e2ef1edf01b 1106
destinyXfate 2:0e2ef1edf01b 1107 png_debug(1, "in png_handle_sPLT\n");
destinyXfate 2:0e2ef1edf01b 1108
destinyXfate 2:0e2ef1edf01b 1109 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1110 png_error(png_ptr, "Missing IHDR before sPLT");
destinyXfate 2:0e2ef1edf01b 1111 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1112 {
destinyXfate 2:0e2ef1edf01b 1113 png_warning(png_ptr, "Invalid sPLT after IDAT");
destinyXfate 2:0e2ef1edf01b 1114 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1115 return;
destinyXfate 2:0e2ef1edf01b 1116 }
destinyXfate 2:0e2ef1edf01b 1117
destinyXfate 2:0e2ef1edf01b 1118 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 1119 if (length > (png_uint_32)65535L)
destinyXfate 2:0e2ef1edf01b 1120 {
destinyXfate 2:0e2ef1edf01b 1121 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
destinyXfate 2:0e2ef1edf01b 1122 skip = length - (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 1123 length = (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 1124 }
destinyXfate 2:0e2ef1edf01b 1125 #endif
destinyXfate 2:0e2ef1edf01b 1126
destinyXfate 2:0e2ef1edf01b 1127 chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 1128 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 1129 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
destinyXfate 2:0e2ef1edf01b 1130
destinyXfate 2:0e2ef1edf01b 1131 if (png_crc_finish(png_ptr, skip))
destinyXfate 2:0e2ef1edf01b 1132 {
destinyXfate 2:0e2ef1edf01b 1133 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1134 return;
destinyXfate 2:0e2ef1edf01b 1135 }
destinyXfate 2:0e2ef1edf01b 1136
destinyXfate 2:0e2ef1edf01b 1137 chunkdata[slength] = 0x00;
destinyXfate 2:0e2ef1edf01b 1138
destinyXfate 2:0e2ef1edf01b 1139 for (entry_start = chunkdata; *entry_start; entry_start++)
destinyXfate 2:0e2ef1edf01b 1140 /* empty loop to find end of name */ ;
destinyXfate 2:0e2ef1edf01b 1141 ++entry_start;
destinyXfate 2:0e2ef1edf01b 1142
destinyXfate 2:0e2ef1edf01b 1143 /* a sample depth should follow the separator, and we should be on it */
destinyXfate 2:0e2ef1edf01b 1144 if (entry_start > chunkdata + slength)
destinyXfate 2:0e2ef1edf01b 1145 {
destinyXfate 2:0e2ef1edf01b 1146 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1147 png_warning(png_ptr, "malformed sPLT chunk");
destinyXfate 2:0e2ef1edf01b 1148 return;
destinyXfate 2:0e2ef1edf01b 1149 }
destinyXfate 2:0e2ef1edf01b 1150
destinyXfate 2:0e2ef1edf01b 1151 new_palette.depth = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1152 entry_size = (new_palette.depth == 8 ? 6 : 10);
destinyXfate 2:0e2ef1edf01b 1153 data_length = (slength - (entry_start - chunkdata));
destinyXfate 2:0e2ef1edf01b 1154
destinyXfate 2:0e2ef1edf01b 1155 /* integrity-check the data length */
destinyXfate 2:0e2ef1edf01b 1156 if (data_length % entry_size)
destinyXfate 2:0e2ef1edf01b 1157 {
destinyXfate 2:0e2ef1edf01b 1158 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1159 png_warning(png_ptr, "sPLT chunk has bad length");
destinyXfate 2:0e2ef1edf01b 1160 return;
destinyXfate 2:0e2ef1edf01b 1161 }
destinyXfate 2:0e2ef1edf01b 1162
destinyXfate 2:0e2ef1edf01b 1163 new_palette.nentries = (png_int_32) ( data_length / entry_size);
destinyXfate 2:0e2ef1edf01b 1164 if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
destinyXfate 2:0e2ef1edf01b 1165 png_sizeof(png_sPLT_entry)))
destinyXfate 2:0e2ef1edf01b 1166 {
destinyXfate 2:0e2ef1edf01b 1167 png_warning(png_ptr, "sPLT chunk too long");
destinyXfate 2:0e2ef1edf01b 1168 return;
destinyXfate 2:0e2ef1edf01b 1169 }
destinyXfate 2:0e2ef1edf01b 1170 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
destinyXfate 2:0e2ef1edf01b 1171 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
destinyXfate 2:0e2ef1edf01b 1172 if (new_palette.entries == NULL)
destinyXfate 2:0e2ef1edf01b 1173 {
destinyXfate 2:0e2ef1edf01b 1174 png_warning(png_ptr, "sPLT chunk requires too much memory");
destinyXfate 2:0e2ef1edf01b 1175 return;
destinyXfate 2:0e2ef1edf01b 1176 }
destinyXfate 2:0e2ef1edf01b 1177
destinyXfate 2:0e2ef1edf01b 1178 #ifndef PNG_NO_POINTER_INDEXING
destinyXfate 2:0e2ef1edf01b 1179 for (i = 0; i < new_palette.nentries; i++)
destinyXfate 2:0e2ef1edf01b 1180 {
destinyXfate 2:0e2ef1edf01b 1181 png_sPLT_entryp pp = new_palette.entries + i;
destinyXfate 2:0e2ef1edf01b 1182
destinyXfate 2:0e2ef1edf01b 1183 if (new_palette.depth == 8)
destinyXfate 2:0e2ef1edf01b 1184 {
destinyXfate 2:0e2ef1edf01b 1185 pp->red = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1186 pp->green = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1187 pp->blue = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1188 pp->alpha = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1189 }
destinyXfate 2:0e2ef1edf01b 1190 else
destinyXfate 2:0e2ef1edf01b 1191 {
destinyXfate 2:0e2ef1edf01b 1192 pp->red = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1193 pp->green = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1194 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1195 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1196 }
destinyXfate 2:0e2ef1edf01b 1197 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1198 }
destinyXfate 2:0e2ef1edf01b 1199 #else
destinyXfate 2:0e2ef1edf01b 1200 pp = new_palette.entries;
destinyXfate 2:0e2ef1edf01b 1201 for (i = 0; i < new_palette.nentries; i++)
destinyXfate 2:0e2ef1edf01b 1202 {
destinyXfate 2:0e2ef1edf01b 1203
destinyXfate 2:0e2ef1edf01b 1204 if (new_palette.depth == 8)
destinyXfate 2:0e2ef1edf01b 1205 {
destinyXfate 2:0e2ef1edf01b 1206 pp[i].red = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1207 pp[i].green = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1208 pp[i].blue = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1209 pp[i].alpha = *entry_start++;
destinyXfate 2:0e2ef1edf01b 1210 }
destinyXfate 2:0e2ef1edf01b 1211 else
destinyXfate 2:0e2ef1edf01b 1212 {
destinyXfate 2:0e2ef1edf01b 1213 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1214 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1215 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1216 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1217 }
destinyXfate 2:0e2ef1edf01b 1218 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
destinyXfate 2:0e2ef1edf01b 1219 }
destinyXfate 2:0e2ef1edf01b 1220 #endif
destinyXfate 2:0e2ef1edf01b 1221
destinyXfate 2:0e2ef1edf01b 1222 /* discard all chunk data except the name and stash that */
destinyXfate 2:0e2ef1edf01b 1223 new_palette.name = (png_charp)chunkdata;
destinyXfate 2:0e2ef1edf01b 1224
destinyXfate 2:0e2ef1edf01b 1225 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
destinyXfate 2:0e2ef1edf01b 1226
destinyXfate 2:0e2ef1edf01b 1227 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1228 png_free(png_ptr, new_palette.entries);
destinyXfate 2:0e2ef1edf01b 1229 }
destinyXfate 2:0e2ef1edf01b 1230 #endif /* PNG_READ_sPLT_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 1231
destinyXfate 2:0e2ef1edf01b 1232 #if defined(PNG_READ_tRNS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1233 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1234 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1235 {
destinyXfate 2:0e2ef1edf01b 1236 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
destinyXfate 2:0e2ef1edf01b 1237
destinyXfate 2:0e2ef1edf01b 1238 png_debug(1, "in png_handle_tRNS\n");
destinyXfate 2:0e2ef1edf01b 1239
destinyXfate 2:0e2ef1edf01b 1240 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1241 png_error(png_ptr, "Missing IHDR before tRNS");
destinyXfate 2:0e2ef1edf01b 1242 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1243 {
destinyXfate 2:0e2ef1edf01b 1244 png_warning(png_ptr, "Invalid tRNS after IDAT");
destinyXfate 2:0e2ef1edf01b 1245 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1246 return;
destinyXfate 2:0e2ef1edf01b 1247 }
destinyXfate 2:0e2ef1edf01b 1248 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
destinyXfate 2:0e2ef1edf01b 1249 {
destinyXfate 2:0e2ef1edf01b 1250 png_warning(png_ptr, "Duplicate tRNS chunk");
destinyXfate 2:0e2ef1edf01b 1251 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1252 return;
destinyXfate 2:0e2ef1edf01b 1253 }
destinyXfate 2:0e2ef1edf01b 1254
destinyXfate 2:0e2ef1edf01b 1255 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
destinyXfate 2:0e2ef1edf01b 1256 {
destinyXfate 2:0e2ef1edf01b 1257 png_byte buf[2];
destinyXfate 2:0e2ef1edf01b 1258
destinyXfate 2:0e2ef1edf01b 1259 if (length != 2)
destinyXfate 2:0e2ef1edf01b 1260 {
destinyXfate 2:0e2ef1edf01b 1261 png_warning(png_ptr, "Incorrect tRNS chunk length");
destinyXfate 2:0e2ef1edf01b 1262 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1263 return;
destinyXfate 2:0e2ef1edf01b 1264 }
destinyXfate 2:0e2ef1edf01b 1265
destinyXfate 2:0e2ef1edf01b 1266 png_crc_read(png_ptr, buf, 2);
destinyXfate 2:0e2ef1edf01b 1267 png_ptr->num_trans = 1;
destinyXfate 2:0e2ef1edf01b 1268 png_ptr->trans_values.gray = png_get_uint_16(buf);
destinyXfate 2:0e2ef1edf01b 1269 }
destinyXfate 2:0e2ef1edf01b 1270 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
destinyXfate 2:0e2ef1edf01b 1271 {
destinyXfate 2:0e2ef1edf01b 1272 png_byte buf[6];
destinyXfate 2:0e2ef1edf01b 1273
destinyXfate 2:0e2ef1edf01b 1274 if (length != 6)
destinyXfate 2:0e2ef1edf01b 1275 {
destinyXfate 2:0e2ef1edf01b 1276 png_warning(png_ptr, "Incorrect tRNS chunk length");
destinyXfate 2:0e2ef1edf01b 1277 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1278 return;
destinyXfate 2:0e2ef1edf01b 1279 }
destinyXfate 2:0e2ef1edf01b 1280 png_crc_read(png_ptr, buf, (png_size_t)length);
destinyXfate 2:0e2ef1edf01b 1281 png_ptr->num_trans = 1;
destinyXfate 2:0e2ef1edf01b 1282 png_ptr->trans_values.red = png_get_uint_16(buf);
destinyXfate 2:0e2ef1edf01b 1283 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
destinyXfate 2:0e2ef1edf01b 1284 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
destinyXfate 2:0e2ef1edf01b 1285 }
destinyXfate 2:0e2ef1edf01b 1286 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 1287 {
destinyXfate 2:0e2ef1edf01b 1288 if (!(png_ptr->mode & PNG_HAVE_PLTE))
destinyXfate 2:0e2ef1edf01b 1289 {
destinyXfate 2:0e2ef1edf01b 1290 /* Should be an error, but we can cope with it. */
destinyXfate 2:0e2ef1edf01b 1291 png_warning(png_ptr, "Missing PLTE before tRNS");
destinyXfate 2:0e2ef1edf01b 1292 }
destinyXfate 2:0e2ef1edf01b 1293 if (length > (png_uint_32)png_ptr->num_palette ||
destinyXfate 2:0e2ef1edf01b 1294 length > PNG_MAX_PALETTE_LENGTH)
destinyXfate 2:0e2ef1edf01b 1295 {
destinyXfate 2:0e2ef1edf01b 1296 png_warning(png_ptr, "Incorrect tRNS chunk length");
destinyXfate 2:0e2ef1edf01b 1297 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1298 return;
destinyXfate 2:0e2ef1edf01b 1299 }
destinyXfate 2:0e2ef1edf01b 1300 if (length == 0)
destinyXfate 2:0e2ef1edf01b 1301 {
destinyXfate 2:0e2ef1edf01b 1302 png_warning(png_ptr, "Zero length tRNS chunk");
destinyXfate 2:0e2ef1edf01b 1303 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1304 return;
destinyXfate 2:0e2ef1edf01b 1305 }
destinyXfate 2:0e2ef1edf01b 1306 png_crc_read(png_ptr, readbuf, (png_size_t)length);
destinyXfate 2:0e2ef1edf01b 1307 png_ptr->num_trans = (png_uint_16)length;
destinyXfate 2:0e2ef1edf01b 1308 }
destinyXfate 2:0e2ef1edf01b 1309 else
destinyXfate 2:0e2ef1edf01b 1310 {
destinyXfate 2:0e2ef1edf01b 1311 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
destinyXfate 2:0e2ef1edf01b 1312 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1313 return;
destinyXfate 2:0e2ef1edf01b 1314 }
destinyXfate 2:0e2ef1edf01b 1315
destinyXfate 2:0e2ef1edf01b 1316 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1317 return;
destinyXfate 2:0e2ef1edf01b 1318
destinyXfate 2:0e2ef1edf01b 1319 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
destinyXfate 2:0e2ef1edf01b 1320 &(png_ptr->trans_values));
destinyXfate 2:0e2ef1edf01b 1321 }
destinyXfate 2:0e2ef1edf01b 1322 #endif
destinyXfate 2:0e2ef1edf01b 1323
destinyXfate 2:0e2ef1edf01b 1324 #if defined(PNG_READ_bKGD_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1325 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1326 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1327 {
destinyXfate 2:0e2ef1edf01b 1328 png_size_t truelen;
destinyXfate 2:0e2ef1edf01b 1329 png_byte buf[6];
destinyXfate 2:0e2ef1edf01b 1330
destinyXfate 2:0e2ef1edf01b 1331 png_debug(1, "in png_handle_bKGD\n");
destinyXfate 2:0e2ef1edf01b 1332
destinyXfate 2:0e2ef1edf01b 1333 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1334 png_error(png_ptr, "Missing IHDR before bKGD");
destinyXfate 2:0e2ef1edf01b 1335 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1336 {
destinyXfate 2:0e2ef1edf01b 1337 png_warning(png_ptr, "Invalid bKGD after IDAT");
destinyXfate 2:0e2ef1edf01b 1338 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1339 return;
destinyXfate 2:0e2ef1edf01b 1340 }
destinyXfate 2:0e2ef1edf01b 1341 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
destinyXfate 2:0e2ef1edf01b 1342 !(png_ptr->mode & PNG_HAVE_PLTE))
destinyXfate 2:0e2ef1edf01b 1343 {
destinyXfate 2:0e2ef1edf01b 1344 png_warning(png_ptr, "Missing PLTE before bKGD");
destinyXfate 2:0e2ef1edf01b 1345 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1346 return;
destinyXfate 2:0e2ef1edf01b 1347 }
destinyXfate 2:0e2ef1edf01b 1348 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
destinyXfate 2:0e2ef1edf01b 1349 {
destinyXfate 2:0e2ef1edf01b 1350 png_warning(png_ptr, "Duplicate bKGD chunk");
destinyXfate 2:0e2ef1edf01b 1351 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1352 return;
destinyXfate 2:0e2ef1edf01b 1353 }
destinyXfate 2:0e2ef1edf01b 1354
destinyXfate 2:0e2ef1edf01b 1355 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 1356 truelen = 1;
destinyXfate 2:0e2ef1edf01b 1357 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
destinyXfate 2:0e2ef1edf01b 1358 truelen = 6;
destinyXfate 2:0e2ef1edf01b 1359 else
destinyXfate 2:0e2ef1edf01b 1360 truelen = 2;
destinyXfate 2:0e2ef1edf01b 1361
destinyXfate 2:0e2ef1edf01b 1362 if (length != truelen)
destinyXfate 2:0e2ef1edf01b 1363 {
destinyXfate 2:0e2ef1edf01b 1364 png_warning(png_ptr, "Incorrect bKGD chunk length");
destinyXfate 2:0e2ef1edf01b 1365 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1366 return;
destinyXfate 2:0e2ef1edf01b 1367 }
destinyXfate 2:0e2ef1edf01b 1368
destinyXfate 2:0e2ef1edf01b 1369 png_crc_read(png_ptr, buf, truelen);
destinyXfate 2:0e2ef1edf01b 1370 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1371 return;
destinyXfate 2:0e2ef1edf01b 1372
destinyXfate 2:0e2ef1edf01b 1373 /* We convert the index value into RGB components so that we can allow
destinyXfate 2:0e2ef1edf01b 1374 * arbitrary RGB values for background when we have transparency, and
destinyXfate 2:0e2ef1edf01b 1375 * so it is easy to determine the RGB values of the background color
destinyXfate 2:0e2ef1edf01b 1376 * from the info_ptr struct. */
destinyXfate 2:0e2ef1edf01b 1377 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 1378 {
destinyXfate 2:0e2ef1edf01b 1379 png_ptr->background.index = buf[0];
destinyXfate 2:0e2ef1edf01b 1380 if(info_ptr->num_palette)
destinyXfate 2:0e2ef1edf01b 1381 {
destinyXfate 2:0e2ef1edf01b 1382 if(buf[0] > info_ptr->num_palette)
destinyXfate 2:0e2ef1edf01b 1383 {
destinyXfate 2:0e2ef1edf01b 1384 png_warning(png_ptr, "Incorrect bKGD chunk index value");
destinyXfate 2:0e2ef1edf01b 1385 return;
destinyXfate 2:0e2ef1edf01b 1386 }
destinyXfate 2:0e2ef1edf01b 1387 png_ptr->background.red =
destinyXfate 2:0e2ef1edf01b 1388 (png_uint_16)png_ptr->palette[buf[0]].red;
destinyXfate 2:0e2ef1edf01b 1389 png_ptr->background.green =
destinyXfate 2:0e2ef1edf01b 1390 (png_uint_16)png_ptr->palette[buf[0]].green;
destinyXfate 2:0e2ef1edf01b 1391 png_ptr->background.blue =
destinyXfate 2:0e2ef1edf01b 1392 (png_uint_16)png_ptr->palette[buf[0]].blue;
destinyXfate 2:0e2ef1edf01b 1393 }
destinyXfate 2:0e2ef1edf01b 1394 }
destinyXfate 2:0e2ef1edf01b 1395 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
destinyXfate 2:0e2ef1edf01b 1396 {
destinyXfate 2:0e2ef1edf01b 1397 png_ptr->background.red =
destinyXfate 2:0e2ef1edf01b 1398 png_ptr->background.green =
destinyXfate 2:0e2ef1edf01b 1399 png_ptr->background.blue =
destinyXfate 2:0e2ef1edf01b 1400 png_ptr->background.gray = png_get_uint_16(buf);
destinyXfate 2:0e2ef1edf01b 1401 }
destinyXfate 2:0e2ef1edf01b 1402 else
destinyXfate 2:0e2ef1edf01b 1403 {
destinyXfate 2:0e2ef1edf01b 1404 png_ptr->background.red = png_get_uint_16(buf);
destinyXfate 2:0e2ef1edf01b 1405 png_ptr->background.green = png_get_uint_16(buf + 2);
destinyXfate 2:0e2ef1edf01b 1406 png_ptr->background.blue = png_get_uint_16(buf + 4);
destinyXfate 2:0e2ef1edf01b 1407 }
destinyXfate 2:0e2ef1edf01b 1408
destinyXfate 2:0e2ef1edf01b 1409 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
destinyXfate 2:0e2ef1edf01b 1410 }
destinyXfate 2:0e2ef1edf01b 1411 #endif
destinyXfate 2:0e2ef1edf01b 1412
destinyXfate 2:0e2ef1edf01b 1413 #if defined(PNG_READ_hIST_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1414 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1415 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1416 {
destinyXfate 2:0e2ef1edf01b 1417 unsigned int num, i;
destinyXfate 2:0e2ef1edf01b 1418 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
destinyXfate 2:0e2ef1edf01b 1419
destinyXfate 2:0e2ef1edf01b 1420 png_debug(1, "in png_handle_hIST\n");
destinyXfate 2:0e2ef1edf01b 1421
destinyXfate 2:0e2ef1edf01b 1422 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1423 png_error(png_ptr, "Missing IHDR before hIST");
destinyXfate 2:0e2ef1edf01b 1424 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1425 {
destinyXfate 2:0e2ef1edf01b 1426 png_warning(png_ptr, "Invalid hIST after IDAT");
destinyXfate 2:0e2ef1edf01b 1427 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1428 return;
destinyXfate 2:0e2ef1edf01b 1429 }
destinyXfate 2:0e2ef1edf01b 1430 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
destinyXfate 2:0e2ef1edf01b 1431 {
destinyXfate 2:0e2ef1edf01b 1432 png_warning(png_ptr, "Missing PLTE before hIST");
destinyXfate 2:0e2ef1edf01b 1433 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1434 return;
destinyXfate 2:0e2ef1edf01b 1435 }
destinyXfate 2:0e2ef1edf01b 1436 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
destinyXfate 2:0e2ef1edf01b 1437 {
destinyXfate 2:0e2ef1edf01b 1438 png_warning(png_ptr, "Duplicate hIST chunk");
destinyXfate 2:0e2ef1edf01b 1439 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1440 return;
destinyXfate 2:0e2ef1edf01b 1441 }
destinyXfate 2:0e2ef1edf01b 1442
destinyXfate 2:0e2ef1edf01b 1443 num = length / 2 ;
destinyXfate 2:0e2ef1edf01b 1444 if (num != (unsigned int) png_ptr->num_palette || num >
destinyXfate 2:0e2ef1edf01b 1445 (unsigned int) PNG_MAX_PALETTE_LENGTH)
destinyXfate 2:0e2ef1edf01b 1446 {
destinyXfate 2:0e2ef1edf01b 1447 png_warning(png_ptr, "Incorrect hIST chunk length");
destinyXfate 2:0e2ef1edf01b 1448 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1449 return;
destinyXfate 2:0e2ef1edf01b 1450 }
destinyXfate 2:0e2ef1edf01b 1451
destinyXfate 2:0e2ef1edf01b 1452 for (i = 0; i < num; i++)
destinyXfate 2:0e2ef1edf01b 1453 {
destinyXfate 2:0e2ef1edf01b 1454 png_byte buf[2];
destinyXfate 2:0e2ef1edf01b 1455
destinyXfate 2:0e2ef1edf01b 1456 png_crc_read(png_ptr, buf, 2);
destinyXfate 2:0e2ef1edf01b 1457 readbuf[i] = png_get_uint_16(buf);
destinyXfate 2:0e2ef1edf01b 1458 }
destinyXfate 2:0e2ef1edf01b 1459
destinyXfate 2:0e2ef1edf01b 1460 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1461 return;
destinyXfate 2:0e2ef1edf01b 1462
destinyXfate 2:0e2ef1edf01b 1463 png_set_hIST(png_ptr, info_ptr, readbuf);
destinyXfate 2:0e2ef1edf01b 1464 }
destinyXfate 2:0e2ef1edf01b 1465 #endif
destinyXfate 2:0e2ef1edf01b 1466
destinyXfate 2:0e2ef1edf01b 1467 #if defined(PNG_READ_pHYs_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1468 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1469 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1470 {
destinyXfate 2:0e2ef1edf01b 1471 png_byte buf[9];
destinyXfate 2:0e2ef1edf01b 1472 png_uint_32 res_x, res_y;
destinyXfate 2:0e2ef1edf01b 1473 int unit_type;
destinyXfate 2:0e2ef1edf01b 1474
destinyXfate 2:0e2ef1edf01b 1475 png_debug(1, "in png_handle_pHYs\n");
destinyXfate 2:0e2ef1edf01b 1476
destinyXfate 2:0e2ef1edf01b 1477 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1478 png_error(png_ptr, "Missing IHDR before pHYs");
destinyXfate 2:0e2ef1edf01b 1479 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1480 {
destinyXfate 2:0e2ef1edf01b 1481 png_warning(png_ptr, "Invalid pHYs after IDAT");
destinyXfate 2:0e2ef1edf01b 1482 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1483 return;
destinyXfate 2:0e2ef1edf01b 1484 }
destinyXfate 2:0e2ef1edf01b 1485 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
destinyXfate 2:0e2ef1edf01b 1486 {
destinyXfate 2:0e2ef1edf01b 1487 png_warning(png_ptr, "Duplicate pHYs chunk");
destinyXfate 2:0e2ef1edf01b 1488 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1489 return;
destinyXfate 2:0e2ef1edf01b 1490 }
destinyXfate 2:0e2ef1edf01b 1491
destinyXfate 2:0e2ef1edf01b 1492 if (length != 9)
destinyXfate 2:0e2ef1edf01b 1493 {
destinyXfate 2:0e2ef1edf01b 1494 png_warning(png_ptr, "Incorrect pHYs chunk length");
destinyXfate 2:0e2ef1edf01b 1495 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1496 return;
destinyXfate 2:0e2ef1edf01b 1497 }
destinyXfate 2:0e2ef1edf01b 1498
destinyXfate 2:0e2ef1edf01b 1499 png_crc_read(png_ptr, buf, 9);
destinyXfate 2:0e2ef1edf01b 1500 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1501 return;
destinyXfate 2:0e2ef1edf01b 1502
destinyXfate 2:0e2ef1edf01b 1503 res_x = png_get_uint_32(buf);
destinyXfate 2:0e2ef1edf01b 1504 res_y = png_get_uint_32(buf + 4);
destinyXfate 2:0e2ef1edf01b 1505 unit_type = buf[8];
destinyXfate 2:0e2ef1edf01b 1506 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
destinyXfate 2:0e2ef1edf01b 1507 }
destinyXfate 2:0e2ef1edf01b 1508 #endif
destinyXfate 2:0e2ef1edf01b 1509
destinyXfate 2:0e2ef1edf01b 1510 #if defined(PNG_READ_oFFs_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1511 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1512 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1513 {
destinyXfate 2:0e2ef1edf01b 1514 png_byte buf[9];
destinyXfate 2:0e2ef1edf01b 1515 png_int_32 offset_x, offset_y;
destinyXfate 2:0e2ef1edf01b 1516 int unit_type;
destinyXfate 2:0e2ef1edf01b 1517
destinyXfate 2:0e2ef1edf01b 1518 png_debug(1, "in png_handle_oFFs\n");
destinyXfate 2:0e2ef1edf01b 1519
destinyXfate 2:0e2ef1edf01b 1520 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1521 png_error(png_ptr, "Missing IHDR before oFFs");
destinyXfate 2:0e2ef1edf01b 1522 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1523 {
destinyXfate 2:0e2ef1edf01b 1524 png_warning(png_ptr, "Invalid oFFs after IDAT");
destinyXfate 2:0e2ef1edf01b 1525 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1526 return;
destinyXfate 2:0e2ef1edf01b 1527 }
destinyXfate 2:0e2ef1edf01b 1528 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
destinyXfate 2:0e2ef1edf01b 1529 {
destinyXfate 2:0e2ef1edf01b 1530 png_warning(png_ptr, "Duplicate oFFs chunk");
destinyXfate 2:0e2ef1edf01b 1531 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1532 return;
destinyXfate 2:0e2ef1edf01b 1533 }
destinyXfate 2:0e2ef1edf01b 1534
destinyXfate 2:0e2ef1edf01b 1535 if (length != 9)
destinyXfate 2:0e2ef1edf01b 1536 {
destinyXfate 2:0e2ef1edf01b 1537 png_warning(png_ptr, "Incorrect oFFs chunk length");
destinyXfate 2:0e2ef1edf01b 1538 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1539 return;
destinyXfate 2:0e2ef1edf01b 1540 }
destinyXfate 2:0e2ef1edf01b 1541
destinyXfate 2:0e2ef1edf01b 1542 png_crc_read(png_ptr, buf, 9);
destinyXfate 2:0e2ef1edf01b 1543 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1544 return;
destinyXfate 2:0e2ef1edf01b 1545
destinyXfate 2:0e2ef1edf01b 1546 offset_x = png_get_int_32(buf);
destinyXfate 2:0e2ef1edf01b 1547 offset_y = png_get_int_32(buf + 4);
destinyXfate 2:0e2ef1edf01b 1548 unit_type = buf[8];
destinyXfate 2:0e2ef1edf01b 1549 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
destinyXfate 2:0e2ef1edf01b 1550 }
destinyXfate 2:0e2ef1edf01b 1551 #endif
destinyXfate 2:0e2ef1edf01b 1552
destinyXfate 2:0e2ef1edf01b 1553 #if defined(PNG_READ_pCAL_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1554 /* read the pCAL chunk (described in the PNG Extensions document) */
destinyXfate 2:0e2ef1edf01b 1555 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1556 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1557 {
destinyXfate 2:0e2ef1edf01b 1558 png_charp purpose;
destinyXfate 2:0e2ef1edf01b 1559 png_int_32 X0, X1;
destinyXfate 2:0e2ef1edf01b 1560 png_byte type, nparams;
destinyXfate 2:0e2ef1edf01b 1561 png_charp buf, units, endptr;
destinyXfate 2:0e2ef1edf01b 1562 png_charpp params;
destinyXfate 2:0e2ef1edf01b 1563 png_size_t slength;
destinyXfate 2:0e2ef1edf01b 1564 int i;
destinyXfate 2:0e2ef1edf01b 1565
destinyXfate 2:0e2ef1edf01b 1566 png_debug(1, "in png_handle_pCAL\n");
destinyXfate 2:0e2ef1edf01b 1567
destinyXfate 2:0e2ef1edf01b 1568 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1569 png_error(png_ptr, "Missing IHDR before pCAL");
destinyXfate 2:0e2ef1edf01b 1570 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1571 {
destinyXfate 2:0e2ef1edf01b 1572 png_warning(png_ptr, "Invalid pCAL after IDAT");
destinyXfate 2:0e2ef1edf01b 1573 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1574 return;
destinyXfate 2:0e2ef1edf01b 1575 }
destinyXfate 2:0e2ef1edf01b 1576 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
destinyXfate 2:0e2ef1edf01b 1577 {
destinyXfate 2:0e2ef1edf01b 1578 png_warning(png_ptr, "Duplicate pCAL chunk");
destinyXfate 2:0e2ef1edf01b 1579 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1580 return;
destinyXfate 2:0e2ef1edf01b 1581 }
destinyXfate 2:0e2ef1edf01b 1582
destinyXfate 2:0e2ef1edf01b 1583 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
destinyXfate 2:0e2ef1edf01b 1584 length + 1);
destinyXfate 2:0e2ef1edf01b 1585 purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 1586 if (purpose == NULL)
destinyXfate 2:0e2ef1edf01b 1587 {
destinyXfate 2:0e2ef1edf01b 1588 png_warning(png_ptr, "No memory for pCAL purpose.");
destinyXfate 2:0e2ef1edf01b 1589 return;
destinyXfate 2:0e2ef1edf01b 1590 }
destinyXfate 2:0e2ef1edf01b 1591 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 1592 png_crc_read(png_ptr, (png_bytep)purpose, slength);
destinyXfate 2:0e2ef1edf01b 1593
destinyXfate 2:0e2ef1edf01b 1594 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1595 {
destinyXfate 2:0e2ef1edf01b 1596 png_free(png_ptr, purpose);
destinyXfate 2:0e2ef1edf01b 1597 return;
destinyXfate 2:0e2ef1edf01b 1598 }
destinyXfate 2:0e2ef1edf01b 1599
destinyXfate 2:0e2ef1edf01b 1600 purpose[slength] = 0x00; /* null terminate the last string */
destinyXfate 2:0e2ef1edf01b 1601
destinyXfate 2:0e2ef1edf01b 1602 png_debug(3, "Finding end of pCAL purpose string\n");
destinyXfate 2:0e2ef1edf01b 1603 for (buf = purpose; *buf; buf++)
destinyXfate 2:0e2ef1edf01b 1604 /* empty loop */ ;
destinyXfate 2:0e2ef1edf01b 1605
destinyXfate 2:0e2ef1edf01b 1606 endptr = purpose + slength;
destinyXfate 2:0e2ef1edf01b 1607
destinyXfate 2:0e2ef1edf01b 1608 /* We need to have at least 12 bytes after the purpose string
destinyXfate 2:0e2ef1edf01b 1609 in order to get the parameter information. */
destinyXfate 2:0e2ef1edf01b 1610 if (endptr <= buf + 12)
destinyXfate 2:0e2ef1edf01b 1611 {
destinyXfate 2:0e2ef1edf01b 1612 png_warning(png_ptr, "Invalid pCAL data");
destinyXfate 2:0e2ef1edf01b 1613 png_free(png_ptr, purpose);
destinyXfate 2:0e2ef1edf01b 1614 return;
destinyXfate 2:0e2ef1edf01b 1615 }
destinyXfate 2:0e2ef1edf01b 1616
destinyXfate 2:0e2ef1edf01b 1617 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
destinyXfate 2:0e2ef1edf01b 1618 X0 = png_get_int_32((png_bytep)buf+1);
destinyXfate 2:0e2ef1edf01b 1619 X1 = png_get_int_32((png_bytep)buf+5);
destinyXfate 2:0e2ef1edf01b 1620 type = buf[9];
destinyXfate 2:0e2ef1edf01b 1621 nparams = buf[10];
destinyXfate 2:0e2ef1edf01b 1622 units = buf + 11;
destinyXfate 2:0e2ef1edf01b 1623
destinyXfate 2:0e2ef1edf01b 1624 png_debug(3, "Checking pCAL equation type and number of parameters\n");
destinyXfate 2:0e2ef1edf01b 1625 /* Check that we have the right number of parameters for known
destinyXfate 2:0e2ef1edf01b 1626 equation types. */
destinyXfate 2:0e2ef1edf01b 1627 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
destinyXfate 2:0e2ef1edf01b 1628 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
destinyXfate 2:0e2ef1edf01b 1629 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
destinyXfate 2:0e2ef1edf01b 1630 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
destinyXfate 2:0e2ef1edf01b 1631 {
destinyXfate 2:0e2ef1edf01b 1632 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
destinyXfate 2:0e2ef1edf01b 1633 png_free(png_ptr, purpose);
destinyXfate 2:0e2ef1edf01b 1634 return;
destinyXfate 2:0e2ef1edf01b 1635 }
destinyXfate 2:0e2ef1edf01b 1636 else if (type >= PNG_EQUATION_LAST)
destinyXfate 2:0e2ef1edf01b 1637 {
destinyXfate 2:0e2ef1edf01b 1638 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
destinyXfate 2:0e2ef1edf01b 1639 }
destinyXfate 2:0e2ef1edf01b 1640
destinyXfate 2:0e2ef1edf01b 1641 for (buf = units; *buf; buf++)
destinyXfate 2:0e2ef1edf01b 1642 /* Empty loop to move past the units string. */ ;
destinyXfate 2:0e2ef1edf01b 1643
destinyXfate 2:0e2ef1edf01b 1644 png_debug(3, "Allocating pCAL parameters array\n");
destinyXfate 2:0e2ef1edf01b 1645 params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
destinyXfate 2:0e2ef1edf01b 1646 *png_sizeof(png_charp))) ;
destinyXfate 2:0e2ef1edf01b 1647 if (params == NULL)
destinyXfate 2:0e2ef1edf01b 1648 {
destinyXfate 2:0e2ef1edf01b 1649 png_free(png_ptr, purpose);
destinyXfate 2:0e2ef1edf01b 1650 png_warning(png_ptr, "No memory for pCAL params.");
destinyXfate 2:0e2ef1edf01b 1651 return;
destinyXfate 2:0e2ef1edf01b 1652 }
destinyXfate 2:0e2ef1edf01b 1653
destinyXfate 2:0e2ef1edf01b 1654 /* Get pointers to the start of each parameter string. */
destinyXfate 2:0e2ef1edf01b 1655 for (i = 0; i < (int)nparams; i++)
destinyXfate 2:0e2ef1edf01b 1656 {
destinyXfate 2:0e2ef1edf01b 1657 buf++; /* Skip the null string terminator from previous parameter. */
destinyXfate 2:0e2ef1edf01b 1658
destinyXfate 2:0e2ef1edf01b 1659 png_debug1(3, "Reading pCAL parameter %d\n", i);
destinyXfate 2:0e2ef1edf01b 1660 for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
destinyXfate 2:0e2ef1edf01b 1661 /* Empty loop to move past each parameter string */ ;
destinyXfate 2:0e2ef1edf01b 1662
destinyXfate 2:0e2ef1edf01b 1663 /* Make sure we haven't run out of data yet */
destinyXfate 2:0e2ef1edf01b 1664 if (buf > endptr)
destinyXfate 2:0e2ef1edf01b 1665 {
destinyXfate 2:0e2ef1edf01b 1666 png_warning(png_ptr, "Invalid pCAL data");
destinyXfate 2:0e2ef1edf01b 1667 png_free(png_ptr, purpose);
destinyXfate 2:0e2ef1edf01b 1668 png_free(png_ptr, params);
destinyXfate 2:0e2ef1edf01b 1669 return;
destinyXfate 2:0e2ef1edf01b 1670 }
destinyXfate 2:0e2ef1edf01b 1671 }
destinyXfate 2:0e2ef1edf01b 1672
destinyXfate 2:0e2ef1edf01b 1673 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
destinyXfate 2:0e2ef1edf01b 1674 units, params);
destinyXfate 2:0e2ef1edf01b 1675
destinyXfate 2:0e2ef1edf01b 1676 png_free(png_ptr, purpose);
destinyXfate 2:0e2ef1edf01b 1677 png_free(png_ptr, params);
destinyXfate 2:0e2ef1edf01b 1678 }
destinyXfate 2:0e2ef1edf01b 1679 #endif
destinyXfate 2:0e2ef1edf01b 1680
destinyXfate 2:0e2ef1edf01b 1681 #if defined(PNG_READ_sCAL_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1682 /* read the sCAL chunk */
destinyXfate 2:0e2ef1edf01b 1683 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1684 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1685 {
destinyXfate 2:0e2ef1edf01b 1686 png_charp buffer, ep;
destinyXfate 2:0e2ef1edf01b 1687 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1688 double width, height;
destinyXfate 2:0e2ef1edf01b 1689 png_charp vp;
destinyXfate 2:0e2ef1edf01b 1690 #else
destinyXfate 2:0e2ef1edf01b 1691 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1692 png_charp swidth, sheight;
destinyXfate 2:0e2ef1edf01b 1693 #endif
destinyXfate 2:0e2ef1edf01b 1694 #endif
destinyXfate 2:0e2ef1edf01b 1695 png_size_t slength;
destinyXfate 2:0e2ef1edf01b 1696
destinyXfate 2:0e2ef1edf01b 1697 png_debug(1, "in png_handle_sCAL\n");
destinyXfate 2:0e2ef1edf01b 1698
destinyXfate 2:0e2ef1edf01b 1699 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1700 png_error(png_ptr, "Missing IHDR before sCAL");
destinyXfate 2:0e2ef1edf01b 1701 else if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1702 {
destinyXfate 2:0e2ef1edf01b 1703 png_warning(png_ptr, "Invalid sCAL after IDAT");
destinyXfate 2:0e2ef1edf01b 1704 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1705 return;
destinyXfate 2:0e2ef1edf01b 1706 }
destinyXfate 2:0e2ef1edf01b 1707 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
destinyXfate 2:0e2ef1edf01b 1708 {
destinyXfate 2:0e2ef1edf01b 1709 png_warning(png_ptr, "Duplicate sCAL chunk");
destinyXfate 2:0e2ef1edf01b 1710 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1711 return;
destinyXfate 2:0e2ef1edf01b 1712 }
destinyXfate 2:0e2ef1edf01b 1713
destinyXfate 2:0e2ef1edf01b 1714 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
destinyXfate 2:0e2ef1edf01b 1715 length + 1);
destinyXfate 2:0e2ef1edf01b 1716 buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 1717 if (buffer == NULL)
destinyXfate 2:0e2ef1edf01b 1718 {
destinyXfate 2:0e2ef1edf01b 1719 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
destinyXfate 2:0e2ef1edf01b 1720 return;
destinyXfate 2:0e2ef1edf01b 1721 }
destinyXfate 2:0e2ef1edf01b 1722 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 1723 png_crc_read(png_ptr, (png_bytep)buffer, slength);
destinyXfate 2:0e2ef1edf01b 1724
destinyXfate 2:0e2ef1edf01b 1725 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1726 {
destinyXfate 2:0e2ef1edf01b 1727 png_free(png_ptr, buffer);
destinyXfate 2:0e2ef1edf01b 1728 return;
destinyXfate 2:0e2ef1edf01b 1729 }
destinyXfate 2:0e2ef1edf01b 1730
destinyXfate 2:0e2ef1edf01b 1731 buffer[slength] = 0x00; /* null terminate the last string */
destinyXfate 2:0e2ef1edf01b 1732
destinyXfate 2:0e2ef1edf01b 1733 ep = buffer + 1; /* skip unit byte */
destinyXfate 2:0e2ef1edf01b 1734
destinyXfate 2:0e2ef1edf01b 1735 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1736 width = png_strtod(png_ptr, ep, &vp);
destinyXfate 2:0e2ef1edf01b 1737 if (*vp)
destinyXfate 2:0e2ef1edf01b 1738 {
destinyXfate 2:0e2ef1edf01b 1739 png_warning(png_ptr, "malformed width string in sCAL chunk");
destinyXfate 2:0e2ef1edf01b 1740 return;
destinyXfate 2:0e2ef1edf01b 1741 }
destinyXfate 2:0e2ef1edf01b 1742 #else
destinyXfate 2:0e2ef1edf01b 1743 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1744 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
destinyXfate 2:0e2ef1edf01b 1745 if (swidth == NULL)
destinyXfate 2:0e2ef1edf01b 1746 {
destinyXfate 2:0e2ef1edf01b 1747 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
destinyXfate 2:0e2ef1edf01b 1748 return;
destinyXfate 2:0e2ef1edf01b 1749 }
destinyXfate 2:0e2ef1edf01b 1750 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
destinyXfate 2:0e2ef1edf01b 1751 #endif
destinyXfate 2:0e2ef1edf01b 1752 #endif
destinyXfate 2:0e2ef1edf01b 1753
destinyXfate 2:0e2ef1edf01b 1754 for (ep = buffer; *ep; ep++)
destinyXfate 2:0e2ef1edf01b 1755 /* empty loop */ ;
destinyXfate 2:0e2ef1edf01b 1756 ep++;
destinyXfate 2:0e2ef1edf01b 1757
destinyXfate 2:0e2ef1edf01b 1758 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1759 height = png_strtod(png_ptr, ep, &vp);
destinyXfate 2:0e2ef1edf01b 1760 if (*vp)
destinyXfate 2:0e2ef1edf01b 1761 {
destinyXfate 2:0e2ef1edf01b 1762 png_warning(png_ptr, "malformed height string in sCAL chunk");
destinyXfate 2:0e2ef1edf01b 1763 return;
destinyXfate 2:0e2ef1edf01b 1764 }
destinyXfate 2:0e2ef1edf01b 1765 #else
destinyXfate 2:0e2ef1edf01b 1766 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1767 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
destinyXfate 2:0e2ef1edf01b 1768 if (swidth == NULL)
destinyXfate 2:0e2ef1edf01b 1769 {
destinyXfate 2:0e2ef1edf01b 1770 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
destinyXfate 2:0e2ef1edf01b 1771 return;
destinyXfate 2:0e2ef1edf01b 1772 }
destinyXfate 2:0e2ef1edf01b 1773 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
destinyXfate 2:0e2ef1edf01b 1774 #endif
destinyXfate 2:0e2ef1edf01b 1775 #endif
destinyXfate 2:0e2ef1edf01b 1776
destinyXfate 2:0e2ef1edf01b 1777 if (buffer + slength < ep
destinyXfate 2:0e2ef1edf01b 1778 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1779 || width <= 0. || height <= 0.
destinyXfate 2:0e2ef1edf01b 1780 #endif
destinyXfate 2:0e2ef1edf01b 1781 )
destinyXfate 2:0e2ef1edf01b 1782 {
destinyXfate 2:0e2ef1edf01b 1783 png_warning(png_ptr, "Invalid sCAL data");
destinyXfate 2:0e2ef1edf01b 1784 png_free(png_ptr, buffer);
destinyXfate 2:0e2ef1edf01b 1785 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1786 png_free(png_ptr, swidth);
destinyXfate 2:0e2ef1edf01b 1787 png_free(png_ptr, sheight);
destinyXfate 2:0e2ef1edf01b 1788 #endif
destinyXfate 2:0e2ef1edf01b 1789 return;
destinyXfate 2:0e2ef1edf01b 1790 }
destinyXfate 2:0e2ef1edf01b 1791
destinyXfate 2:0e2ef1edf01b 1792
destinyXfate 2:0e2ef1edf01b 1793 #ifdef PNG_FLOATING_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1794 png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
destinyXfate 2:0e2ef1edf01b 1795 #else
destinyXfate 2:0e2ef1edf01b 1796 #ifdef PNG_FIXED_POINT_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1797 png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
destinyXfate 2:0e2ef1edf01b 1798 #endif
destinyXfate 2:0e2ef1edf01b 1799 #endif
destinyXfate 2:0e2ef1edf01b 1800
destinyXfate 2:0e2ef1edf01b 1801 png_free(png_ptr, buffer);
destinyXfate 2:0e2ef1edf01b 1802 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1803 png_free(png_ptr, swidth);
destinyXfate 2:0e2ef1edf01b 1804 png_free(png_ptr, sheight);
destinyXfate 2:0e2ef1edf01b 1805 #endif
destinyXfate 2:0e2ef1edf01b 1806 }
destinyXfate 2:0e2ef1edf01b 1807 #endif
destinyXfate 2:0e2ef1edf01b 1808
destinyXfate 2:0e2ef1edf01b 1809 #if defined(PNG_READ_tIME_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1810 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1811 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1812 {
destinyXfate 2:0e2ef1edf01b 1813 png_byte buf[7];
destinyXfate 2:0e2ef1edf01b 1814 png_time mod_time;
destinyXfate 2:0e2ef1edf01b 1815
destinyXfate 2:0e2ef1edf01b 1816 png_debug(1, "in png_handle_tIME\n");
destinyXfate 2:0e2ef1edf01b 1817
destinyXfate 2:0e2ef1edf01b 1818 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1819 png_error(png_ptr, "Out of place tIME chunk");
destinyXfate 2:0e2ef1edf01b 1820 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
destinyXfate 2:0e2ef1edf01b 1821 {
destinyXfate 2:0e2ef1edf01b 1822 png_warning(png_ptr, "Duplicate tIME chunk");
destinyXfate 2:0e2ef1edf01b 1823 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1824 return;
destinyXfate 2:0e2ef1edf01b 1825 }
destinyXfate 2:0e2ef1edf01b 1826
destinyXfate 2:0e2ef1edf01b 1827 if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1828 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 1829
destinyXfate 2:0e2ef1edf01b 1830 if (length != 7)
destinyXfate 2:0e2ef1edf01b 1831 {
destinyXfate 2:0e2ef1edf01b 1832 png_warning(png_ptr, "Incorrect tIME chunk length");
destinyXfate 2:0e2ef1edf01b 1833 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1834 return;
destinyXfate 2:0e2ef1edf01b 1835 }
destinyXfate 2:0e2ef1edf01b 1836
destinyXfate 2:0e2ef1edf01b 1837 png_crc_read(png_ptr, buf, 7);
destinyXfate 2:0e2ef1edf01b 1838 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1839 return;
destinyXfate 2:0e2ef1edf01b 1840
destinyXfate 2:0e2ef1edf01b 1841 mod_time.second = buf[6];
destinyXfate 2:0e2ef1edf01b 1842 mod_time.minute = buf[5];
destinyXfate 2:0e2ef1edf01b 1843 mod_time.hour = buf[4];
destinyXfate 2:0e2ef1edf01b 1844 mod_time.day = buf[3];
destinyXfate 2:0e2ef1edf01b 1845 mod_time.month = buf[2];
destinyXfate 2:0e2ef1edf01b 1846 mod_time.year = png_get_uint_16(buf);
destinyXfate 2:0e2ef1edf01b 1847
destinyXfate 2:0e2ef1edf01b 1848 png_set_tIME(png_ptr, info_ptr, &mod_time);
destinyXfate 2:0e2ef1edf01b 1849 }
destinyXfate 2:0e2ef1edf01b 1850 #endif
destinyXfate 2:0e2ef1edf01b 1851
destinyXfate 2:0e2ef1edf01b 1852 #if defined(PNG_READ_tEXt_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1853 /* Note: this does not properly handle chunks that are > 64K under DOS */
destinyXfate 2:0e2ef1edf01b 1854 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1855 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1856 {
destinyXfate 2:0e2ef1edf01b 1857 png_textp text_ptr;
destinyXfate 2:0e2ef1edf01b 1858 png_charp key;
destinyXfate 2:0e2ef1edf01b 1859 png_charp text;
destinyXfate 2:0e2ef1edf01b 1860 png_uint_32 skip = 0;
destinyXfate 2:0e2ef1edf01b 1861 png_size_t slength;
destinyXfate 2:0e2ef1edf01b 1862 int ret;
destinyXfate 2:0e2ef1edf01b 1863
destinyXfate 2:0e2ef1edf01b 1864 png_debug(1, "in png_handle_tEXt\n");
destinyXfate 2:0e2ef1edf01b 1865
destinyXfate 2:0e2ef1edf01b 1866 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1867 png_error(png_ptr, "Missing IHDR before tEXt");
destinyXfate 2:0e2ef1edf01b 1868
destinyXfate 2:0e2ef1edf01b 1869 if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1870 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 1871
destinyXfate 2:0e2ef1edf01b 1872 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 1873 if (length > (png_uint_32)65535L)
destinyXfate 2:0e2ef1edf01b 1874 {
destinyXfate 2:0e2ef1edf01b 1875 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
destinyXfate 2:0e2ef1edf01b 1876 skip = length - (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 1877 length = (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 1878 }
destinyXfate 2:0e2ef1edf01b 1879 #endif
destinyXfate 2:0e2ef1edf01b 1880
destinyXfate 2:0e2ef1edf01b 1881 key = (png_charp)png_malloc_warn(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 1882 if (key == NULL)
destinyXfate 2:0e2ef1edf01b 1883 {
destinyXfate 2:0e2ef1edf01b 1884 png_warning(png_ptr, "No memory to process text chunk.");
destinyXfate 2:0e2ef1edf01b 1885 return;
destinyXfate 2:0e2ef1edf01b 1886 }
destinyXfate 2:0e2ef1edf01b 1887 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 1888 png_crc_read(png_ptr, (png_bytep)key, slength);
destinyXfate 2:0e2ef1edf01b 1889
destinyXfate 2:0e2ef1edf01b 1890 if (png_crc_finish(png_ptr, skip))
destinyXfate 2:0e2ef1edf01b 1891 {
destinyXfate 2:0e2ef1edf01b 1892 png_free(png_ptr, key);
destinyXfate 2:0e2ef1edf01b 1893 return;
destinyXfate 2:0e2ef1edf01b 1894 }
destinyXfate 2:0e2ef1edf01b 1895
destinyXfate 2:0e2ef1edf01b 1896 key[slength] = 0x00;
destinyXfate 2:0e2ef1edf01b 1897
destinyXfate 2:0e2ef1edf01b 1898 for (text = key; *text; text++)
destinyXfate 2:0e2ef1edf01b 1899 /* empty loop to find end of key */ ;
destinyXfate 2:0e2ef1edf01b 1900
destinyXfate 2:0e2ef1edf01b 1901 if (text != key + slength)
destinyXfate 2:0e2ef1edf01b 1902 text++;
destinyXfate 2:0e2ef1edf01b 1903
destinyXfate 2:0e2ef1edf01b 1904 text_ptr = (png_textp)png_malloc_warn(png_ptr,
destinyXfate 2:0e2ef1edf01b 1905 (png_uint_32)png_sizeof(png_text));
destinyXfate 2:0e2ef1edf01b 1906 if (text_ptr == NULL)
destinyXfate 2:0e2ef1edf01b 1907 {
destinyXfate 2:0e2ef1edf01b 1908 png_warning(png_ptr, "Not enough memory to process text chunk.");
destinyXfate 2:0e2ef1edf01b 1909 png_free(png_ptr, key);
destinyXfate 2:0e2ef1edf01b 1910 return;
destinyXfate 2:0e2ef1edf01b 1911 }
destinyXfate 2:0e2ef1edf01b 1912 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
destinyXfate 2:0e2ef1edf01b 1913 text_ptr->key = key;
destinyXfate 2:0e2ef1edf01b 1914 #ifdef PNG_iTXt_SUPPORTED
destinyXfate 2:0e2ef1edf01b 1915 text_ptr->lang = NULL;
destinyXfate 2:0e2ef1edf01b 1916 text_ptr->lang_key = NULL;
destinyXfate 2:0e2ef1edf01b 1917 text_ptr->itxt_length = 0;
destinyXfate 2:0e2ef1edf01b 1918 #endif
destinyXfate 2:0e2ef1edf01b 1919 text_ptr->text = text;
destinyXfate 2:0e2ef1edf01b 1920 text_ptr->text_length = png_strlen(text);
destinyXfate 2:0e2ef1edf01b 1921
destinyXfate 2:0e2ef1edf01b 1922 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
destinyXfate 2:0e2ef1edf01b 1923
destinyXfate 2:0e2ef1edf01b 1924 png_free(png_ptr, key);
destinyXfate 2:0e2ef1edf01b 1925 png_free(png_ptr, text_ptr);
destinyXfate 2:0e2ef1edf01b 1926 if (ret)
destinyXfate 2:0e2ef1edf01b 1927 png_warning(png_ptr, "Insufficient memory to process text chunk.");
destinyXfate 2:0e2ef1edf01b 1928 }
destinyXfate 2:0e2ef1edf01b 1929 #endif
destinyXfate 2:0e2ef1edf01b 1930
destinyXfate 2:0e2ef1edf01b 1931 #if defined(PNG_READ_zTXt_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 1932 /* note: this does not correctly handle chunks that are > 64K under DOS */
destinyXfate 2:0e2ef1edf01b 1933 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 1934 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 1935 {
destinyXfate 2:0e2ef1edf01b 1936 png_textp text_ptr;
destinyXfate 2:0e2ef1edf01b 1937 png_charp chunkdata;
destinyXfate 2:0e2ef1edf01b 1938 png_charp text;
destinyXfate 2:0e2ef1edf01b 1939 int comp_type;
destinyXfate 2:0e2ef1edf01b 1940 int ret;
destinyXfate 2:0e2ef1edf01b 1941 png_size_t slength, prefix_len, data_len;
destinyXfate 2:0e2ef1edf01b 1942
destinyXfate 2:0e2ef1edf01b 1943 png_debug(1, "in png_handle_zTXt\n");
destinyXfate 2:0e2ef1edf01b 1944 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 1945 png_error(png_ptr, "Missing IHDR before zTXt");
destinyXfate 2:0e2ef1edf01b 1946
destinyXfate 2:0e2ef1edf01b 1947 if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 1948 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 1949
destinyXfate 2:0e2ef1edf01b 1950 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 1951 /* We will no doubt have problems with chunks even half this size, but
destinyXfate 2:0e2ef1edf01b 1952 there is no hard and fast rule to tell us where to stop. */
destinyXfate 2:0e2ef1edf01b 1953 if (length > (png_uint_32)65535L)
destinyXfate 2:0e2ef1edf01b 1954 {
destinyXfate 2:0e2ef1edf01b 1955 png_warning(png_ptr,"zTXt chunk too large to fit in memory");
destinyXfate 2:0e2ef1edf01b 1956 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 1957 return;
destinyXfate 2:0e2ef1edf01b 1958 }
destinyXfate 2:0e2ef1edf01b 1959 #endif
destinyXfate 2:0e2ef1edf01b 1960
destinyXfate 2:0e2ef1edf01b 1961 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 1962 if (chunkdata == NULL)
destinyXfate 2:0e2ef1edf01b 1963 {
destinyXfate 2:0e2ef1edf01b 1964 png_warning(png_ptr,"Out of memory processing zTXt chunk.");
destinyXfate 2:0e2ef1edf01b 1965 return;
destinyXfate 2:0e2ef1edf01b 1966 }
destinyXfate 2:0e2ef1edf01b 1967 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 1968 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
destinyXfate 2:0e2ef1edf01b 1969 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 1970 {
destinyXfate 2:0e2ef1edf01b 1971 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 1972 return;
destinyXfate 2:0e2ef1edf01b 1973 }
destinyXfate 2:0e2ef1edf01b 1974
destinyXfate 2:0e2ef1edf01b 1975 chunkdata[slength] = 0x00;
destinyXfate 2:0e2ef1edf01b 1976
destinyXfate 2:0e2ef1edf01b 1977 for (text = chunkdata; *text; text++)
destinyXfate 2:0e2ef1edf01b 1978 /* empty loop */ ;
destinyXfate 2:0e2ef1edf01b 1979
destinyXfate 2:0e2ef1edf01b 1980 /* zTXt must have some text after the chunkdataword */
destinyXfate 2:0e2ef1edf01b 1981 if (text == chunkdata + slength)
destinyXfate 2:0e2ef1edf01b 1982 {
destinyXfate 2:0e2ef1edf01b 1983 comp_type = PNG_TEXT_COMPRESSION_NONE;
destinyXfate 2:0e2ef1edf01b 1984 png_warning(png_ptr, "Zero length zTXt chunk");
destinyXfate 2:0e2ef1edf01b 1985 }
destinyXfate 2:0e2ef1edf01b 1986 else
destinyXfate 2:0e2ef1edf01b 1987 {
destinyXfate 2:0e2ef1edf01b 1988 comp_type = *(++text);
destinyXfate 2:0e2ef1edf01b 1989 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
destinyXfate 2:0e2ef1edf01b 1990 {
destinyXfate 2:0e2ef1edf01b 1991 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
destinyXfate 2:0e2ef1edf01b 1992 comp_type = PNG_TEXT_COMPRESSION_zTXt;
destinyXfate 2:0e2ef1edf01b 1993 }
destinyXfate 2:0e2ef1edf01b 1994 text++; /* skip the compression_method byte */
destinyXfate 2:0e2ef1edf01b 1995 }
destinyXfate 2:0e2ef1edf01b 1996 prefix_len = text - chunkdata;
destinyXfate 2:0e2ef1edf01b 1997
destinyXfate 2:0e2ef1edf01b 1998 chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
destinyXfate 2:0e2ef1edf01b 1999 (png_size_t)length, prefix_len, &data_len);
destinyXfate 2:0e2ef1edf01b 2000
destinyXfate 2:0e2ef1edf01b 2001 text_ptr = (png_textp)png_malloc_warn(png_ptr,
destinyXfate 2:0e2ef1edf01b 2002 (png_uint_32)png_sizeof(png_text));
destinyXfate 2:0e2ef1edf01b 2003 if (text_ptr == NULL)
destinyXfate 2:0e2ef1edf01b 2004 {
destinyXfate 2:0e2ef1edf01b 2005 png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
destinyXfate 2:0e2ef1edf01b 2006 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 2007 return;
destinyXfate 2:0e2ef1edf01b 2008 }
destinyXfate 2:0e2ef1edf01b 2009 text_ptr->compression = comp_type;
destinyXfate 2:0e2ef1edf01b 2010 text_ptr->key = chunkdata;
destinyXfate 2:0e2ef1edf01b 2011 #ifdef PNG_iTXt_SUPPORTED
destinyXfate 2:0e2ef1edf01b 2012 text_ptr->lang = NULL;
destinyXfate 2:0e2ef1edf01b 2013 text_ptr->lang_key = NULL;
destinyXfate 2:0e2ef1edf01b 2014 text_ptr->itxt_length = 0;
destinyXfate 2:0e2ef1edf01b 2015 #endif
destinyXfate 2:0e2ef1edf01b 2016 text_ptr->text = chunkdata + prefix_len;
destinyXfate 2:0e2ef1edf01b 2017 text_ptr->text_length = data_len;
destinyXfate 2:0e2ef1edf01b 2018
destinyXfate 2:0e2ef1edf01b 2019 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
destinyXfate 2:0e2ef1edf01b 2020
destinyXfate 2:0e2ef1edf01b 2021 png_free(png_ptr, text_ptr);
destinyXfate 2:0e2ef1edf01b 2022 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 2023 if (ret)
destinyXfate 2:0e2ef1edf01b 2024 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
destinyXfate 2:0e2ef1edf01b 2025 }
destinyXfate 2:0e2ef1edf01b 2026 #endif
destinyXfate 2:0e2ef1edf01b 2027
destinyXfate 2:0e2ef1edf01b 2028 #if defined(PNG_READ_iTXt_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2029 /* note: this does not correctly handle chunks that are > 64K under DOS */
destinyXfate 2:0e2ef1edf01b 2030 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2031 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 2032 {
destinyXfate 2:0e2ef1edf01b 2033 png_textp text_ptr;
destinyXfate 2:0e2ef1edf01b 2034 png_charp chunkdata;
destinyXfate 2:0e2ef1edf01b 2035 png_charp key, lang, text, lang_key;
destinyXfate 2:0e2ef1edf01b 2036 int comp_flag;
destinyXfate 2:0e2ef1edf01b 2037 int comp_type = 0;
destinyXfate 2:0e2ef1edf01b 2038 int ret;
destinyXfate 2:0e2ef1edf01b 2039 png_size_t slength, prefix_len, data_len;
destinyXfate 2:0e2ef1edf01b 2040
destinyXfate 2:0e2ef1edf01b 2041 png_debug(1, "in png_handle_iTXt\n");
destinyXfate 2:0e2ef1edf01b 2042
destinyXfate 2:0e2ef1edf01b 2043 if (!(png_ptr->mode & PNG_HAVE_IHDR))
destinyXfate 2:0e2ef1edf01b 2044 png_error(png_ptr, "Missing IHDR before iTXt");
destinyXfate 2:0e2ef1edf01b 2045
destinyXfate 2:0e2ef1edf01b 2046 if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 2047 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 2048
destinyXfate 2:0e2ef1edf01b 2049 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 2050 /* We will no doubt have problems with chunks even half this size, but
destinyXfate 2:0e2ef1edf01b 2051 there is no hard and fast rule to tell us where to stop. */
destinyXfate 2:0e2ef1edf01b 2052 if (length > (png_uint_32)65535L)
destinyXfate 2:0e2ef1edf01b 2053 {
destinyXfate 2:0e2ef1edf01b 2054 png_warning(png_ptr,"iTXt chunk too large to fit in memory");
destinyXfate 2:0e2ef1edf01b 2055 png_crc_finish(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 2056 return;
destinyXfate 2:0e2ef1edf01b 2057 }
destinyXfate 2:0e2ef1edf01b 2058 #endif
destinyXfate 2:0e2ef1edf01b 2059
destinyXfate 2:0e2ef1edf01b 2060 chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
destinyXfate 2:0e2ef1edf01b 2061 if (chunkdata == NULL)
destinyXfate 2:0e2ef1edf01b 2062 {
destinyXfate 2:0e2ef1edf01b 2063 png_warning(png_ptr, "No memory to process iTXt chunk.");
destinyXfate 2:0e2ef1edf01b 2064 return;
destinyXfate 2:0e2ef1edf01b 2065 }
destinyXfate 2:0e2ef1edf01b 2066 slength = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 2067 png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
destinyXfate 2:0e2ef1edf01b 2068 if (png_crc_finish(png_ptr, 0))
destinyXfate 2:0e2ef1edf01b 2069 {
destinyXfate 2:0e2ef1edf01b 2070 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 2071 return;
destinyXfate 2:0e2ef1edf01b 2072 }
destinyXfate 2:0e2ef1edf01b 2073
destinyXfate 2:0e2ef1edf01b 2074 chunkdata[slength] = 0x00;
destinyXfate 2:0e2ef1edf01b 2075
destinyXfate 2:0e2ef1edf01b 2076 for (lang = chunkdata; *lang; lang++)
destinyXfate 2:0e2ef1edf01b 2077 /* empty loop */ ;
destinyXfate 2:0e2ef1edf01b 2078 lang++; /* skip NUL separator */
destinyXfate 2:0e2ef1edf01b 2079
destinyXfate 2:0e2ef1edf01b 2080 /* iTXt must have a language tag (possibly empty), two compression bytes,
destinyXfate 2:0e2ef1edf01b 2081 translated keyword (possibly empty), and possibly some text after the
destinyXfate 2:0e2ef1edf01b 2082 keyword */
destinyXfate 2:0e2ef1edf01b 2083
destinyXfate 2:0e2ef1edf01b 2084 if (lang >= chunkdata + slength)
destinyXfate 2:0e2ef1edf01b 2085 {
destinyXfate 2:0e2ef1edf01b 2086 comp_flag = PNG_TEXT_COMPRESSION_NONE;
destinyXfate 2:0e2ef1edf01b 2087 png_warning(png_ptr, "Zero length iTXt chunk");
destinyXfate 2:0e2ef1edf01b 2088 }
destinyXfate 2:0e2ef1edf01b 2089 else
destinyXfate 2:0e2ef1edf01b 2090 {
destinyXfate 2:0e2ef1edf01b 2091 comp_flag = *lang++;
destinyXfate 2:0e2ef1edf01b 2092 comp_type = *lang++;
destinyXfate 2:0e2ef1edf01b 2093 }
destinyXfate 2:0e2ef1edf01b 2094
destinyXfate 2:0e2ef1edf01b 2095 for (lang_key = lang; *lang_key; lang_key++)
destinyXfate 2:0e2ef1edf01b 2096 /* empty loop */ ;
destinyXfate 2:0e2ef1edf01b 2097 lang_key++; /* skip NUL separator */
destinyXfate 2:0e2ef1edf01b 2098
destinyXfate 2:0e2ef1edf01b 2099 for (text = lang_key; *text; text++)
destinyXfate 2:0e2ef1edf01b 2100 /* empty loop */ ;
destinyXfate 2:0e2ef1edf01b 2101 text++; /* skip NUL separator */
destinyXfate 2:0e2ef1edf01b 2102
destinyXfate 2:0e2ef1edf01b 2103 prefix_len = text - chunkdata;
destinyXfate 2:0e2ef1edf01b 2104
destinyXfate 2:0e2ef1edf01b 2105 key=chunkdata;
destinyXfate 2:0e2ef1edf01b 2106 if (comp_flag)
destinyXfate 2:0e2ef1edf01b 2107 chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
destinyXfate 2:0e2ef1edf01b 2108 (size_t)length, prefix_len, &data_len);
destinyXfate 2:0e2ef1edf01b 2109 else
destinyXfate 2:0e2ef1edf01b 2110 data_len=png_strlen(chunkdata + prefix_len);
destinyXfate 2:0e2ef1edf01b 2111 text_ptr = (png_textp)png_malloc_warn(png_ptr,
destinyXfate 2:0e2ef1edf01b 2112 (png_uint_32)png_sizeof(png_text));
destinyXfate 2:0e2ef1edf01b 2113 if (text_ptr == NULL)
destinyXfate 2:0e2ef1edf01b 2114 {
destinyXfate 2:0e2ef1edf01b 2115 png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
destinyXfate 2:0e2ef1edf01b 2116 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 2117 return;
destinyXfate 2:0e2ef1edf01b 2118 }
destinyXfate 2:0e2ef1edf01b 2119 text_ptr->compression = (int)comp_flag + 1;
destinyXfate 2:0e2ef1edf01b 2120 text_ptr->lang_key = chunkdata+(lang_key-key);
destinyXfate 2:0e2ef1edf01b 2121 text_ptr->lang = chunkdata+(lang-key);
destinyXfate 2:0e2ef1edf01b 2122 text_ptr->itxt_length = data_len;
destinyXfate 2:0e2ef1edf01b 2123 text_ptr->text_length = 0;
destinyXfate 2:0e2ef1edf01b 2124 text_ptr->key = chunkdata;
destinyXfate 2:0e2ef1edf01b 2125 text_ptr->text = chunkdata + prefix_len;
destinyXfate 2:0e2ef1edf01b 2126
destinyXfate 2:0e2ef1edf01b 2127 ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
destinyXfate 2:0e2ef1edf01b 2128
destinyXfate 2:0e2ef1edf01b 2129 png_free(png_ptr, text_ptr);
destinyXfate 2:0e2ef1edf01b 2130 png_free(png_ptr, chunkdata);
destinyXfate 2:0e2ef1edf01b 2131 if (ret)
destinyXfate 2:0e2ef1edf01b 2132 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
destinyXfate 2:0e2ef1edf01b 2133 }
destinyXfate 2:0e2ef1edf01b 2134 #endif
destinyXfate 2:0e2ef1edf01b 2135
destinyXfate 2:0e2ef1edf01b 2136 /* This function is called when we haven't found a handler for a
destinyXfate 2:0e2ef1edf01b 2137 chunk. If there isn't a problem with the chunk itself (ie bad
destinyXfate 2:0e2ef1edf01b 2138 chunk name, CRC, or a critical chunk), the chunk is silently ignored
destinyXfate 2:0e2ef1edf01b 2139 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
destinyXfate 2:0e2ef1edf01b 2140 case it will be saved away to be written out later. */
destinyXfate 2:0e2ef1edf01b 2141 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2142 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
destinyXfate 2:0e2ef1edf01b 2143 {
destinyXfate 2:0e2ef1edf01b 2144 png_uint_32 skip = 0;
destinyXfate 2:0e2ef1edf01b 2145
destinyXfate 2:0e2ef1edf01b 2146 png_debug(1, "in png_handle_unknown\n");
destinyXfate 2:0e2ef1edf01b 2147
destinyXfate 2:0e2ef1edf01b 2148 if (png_ptr->mode & PNG_HAVE_IDAT)
destinyXfate 2:0e2ef1edf01b 2149 {
destinyXfate 2:0e2ef1edf01b 2150 #ifdef PNG_USE_LOCAL_ARRAYS
destinyXfate 2:0e2ef1edf01b 2151 PNG_IDAT;
destinyXfate 2:0e2ef1edf01b 2152 #endif
destinyXfate 2:0e2ef1edf01b 2153 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
destinyXfate 2:0e2ef1edf01b 2154 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 2155 }
destinyXfate 2:0e2ef1edf01b 2156
destinyXfate 2:0e2ef1edf01b 2157 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
destinyXfate 2:0e2ef1edf01b 2158
destinyXfate 2:0e2ef1edf01b 2159 if (!(png_ptr->chunk_name[0] & 0x20))
destinyXfate 2:0e2ef1edf01b 2160 {
destinyXfate 2:0e2ef1edf01b 2161 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2162 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
destinyXfate 2:0e2ef1edf01b 2163 PNG_HANDLE_CHUNK_ALWAYS
destinyXfate 2:0e2ef1edf01b 2164 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2165 && png_ptr->read_user_chunk_fn == NULL
destinyXfate 2:0e2ef1edf01b 2166 #endif
destinyXfate 2:0e2ef1edf01b 2167 )
destinyXfate 2:0e2ef1edf01b 2168 #endif
destinyXfate 2:0e2ef1edf01b 2169 png_chunk_error(png_ptr, "unknown critical chunk");
destinyXfate 2:0e2ef1edf01b 2170 }
destinyXfate 2:0e2ef1edf01b 2171
destinyXfate 2:0e2ef1edf01b 2172 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2173 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
destinyXfate 2:0e2ef1edf01b 2174 (png_ptr->read_user_chunk_fn != NULL))
destinyXfate 2:0e2ef1edf01b 2175 {
destinyXfate 2:0e2ef1edf01b 2176 png_unknown_chunk chunk;
destinyXfate 2:0e2ef1edf01b 2177
destinyXfate 2:0e2ef1edf01b 2178 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 2179 if (length > (png_uint_32)65535L)
destinyXfate 2:0e2ef1edf01b 2180 {
destinyXfate 2:0e2ef1edf01b 2181 png_warning(png_ptr, "unknown chunk too large to fit in memory");
destinyXfate 2:0e2ef1edf01b 2182 skip = length - (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 2183 length = (png_uint_32)65535L;
destinyXfate 2:0e2ef1edf01b 2184 }
destinyXfate 2:0e2ef1edf01b 2185 #endif
destinyXfate 2:0e2ef1edf01b 2186 png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
destinyXfate 2:0e2ef1edf01b 2187 chunk.data = (png_bytep)png_malloc(png_ptr, length);
destinyXfate 2:0e2ef1edf01b 2188 chunk.size = (png_size_t)length;
destinyXfate 2:0e2ef1edf01b 2189 png_crc_read(png_ptr, (png_bytep)chunk.data, length);
destinyXfate 2:0e2ef1edf01b 2190 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2191 if(png_ptr->read_user_chunk_fn != NULL)
destinyXfate 2:0e2ef1edf01b 2192 {
destinyXfate 2:0e2ef1edf01b 2193 /* callback to user unknown chunk handler */
destinyXfate 2:0e2ef1edf01b 2194 if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
destinyXfate 2:0e2ef1edf01b 2195 {
destinyXfate 2:0e2ef1edf01b 2196 if (!(png_ptr->chunk_name[0] & 0x20))
destinyXfate 2:0e2ef1edf01b 2197 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
destinyXfate 2:0e2ef1edf01b 2198 PNG_HANDLE_CHUNK_ALWAYS)
destinyXfate 2:0e2ef1edf01b 2199 {
destinyXfate 2:0e2ef1edf01b 2200 png_free(png_ptr, chunk.data);
destinyXfate 2:0e2ef1edf01b 2201 png_chunk_error(png_ptr, "unknown critical chunk");
destinyXfate 2:0e2ef1edf01b 2202 }
destinyXfate 2:0e2ef1edf01b 2203 png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
destinyXfate 2:0e2ef1edf01b 2204 }
destinyXfate 2:0e2ef1edf01b 2205 }
destinyXfate 2:0e2ef1edf01b 2206 else
destinyXfate 2:0e2ef1edf01b 2207 #endif
destinyXfate 2:0e2ef1edf01b 2208 png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
destinyXfate 2:0e2ef1edf01b 2209 png_free(png_ptr, chunk.data);
destinyXfate 2:0e2ef1edf01b 2210 }
destinyXfate 2:0e2ef1edf01b 2211 else
destinyXfate 2:0e2ef1edf01b 2212 #endif
destinyXfate 2:0e2ef1edf01b 2213 skip = length;
destinyXfate 2:0e2ef1edf01b 2214
destinyXfate 2:0e2ef1edf01b 2215 png_crc_finish(png_ptr, skip);
destinyXfate 2:0e2ef1edf01b 2216
destinyXfate 2:0e2ef1edf01b 2217 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2218 if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
destinyXfate 2:0e2ef1edf01b 2219 return;
destinyXfate 2:0e2ef1edf01b 2220 #endif
destinyXfate 2:0e2ef1edf01b 2221 }
destinyXfate 2:0e2ef1edf01b 2222
destinyXfate 2:0e2ef1edf01b 2223 /* This function is called to verify that a chunk name is valid.
destinyXfate 2:0e2ef1edf01b 2224 This function can't have the "critical chunk check" incorporated
destinyXfate 2:0e2ef1edf01b 2225 into it, since in the future we will need to be able to call user
destinyXfate 2:0e2ef1edf01b 2226 functions to handle unknown critical chunks after we check that
destinyXfate 2:0e2ef1edf01b 2227 the chunk name itself is valid. */
destinyXfate 2:0e2ef1edf01b 2228
destinyXfate 2:0e2ef1edf01b 2229 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
destinyXfate 2:0e2ef1edf01b 2230
destinyXfate 2:0e2ef1edf01b 2231 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2232 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
destinyXfate 2:0e2ef1edf01b 2233 {
destinyXfate 2:0e2ef1edf01b 2234 png_debug(1, "in png_check_chunk_name\n");
destinyXfate 2:0e2ef1edf01b 2235 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
destinyXfate 2:0e2ef1edf01b 2236 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
destinyXfate 2:0e2ef1edf01b 2237 {
destinyXfate 2:0e2ef1edf01b 2238 png_chunk_error(png_ptr, "invalid chunk type");
destinyXfate 2:0e2ef1edf01b 2239 }
destinyXfate 2:0e2ef1edf01b 2240 }
destinyXfate 2:0e2ef1edf01b 2241
destinyXfate 2:0e2ef1edf01b 2242 /* Combines the row recently read in with the existing pixels in the
destinyXfate 2:0e2ef1edf01b 2243 row. This routine takes care of alpha and transparency if requested.
destinyXfate 2:0e2ef1edf01b 2244 This routine also handles the two methods of progressive display
destinyXfate 2:0e2ef1edf01b 2245 of interlaced images, depending on the mask value.
destinyXfate 2:0e2ef1edf01b 2246 The mask value describes which pixels are to be combined with
destinyXfate 2:0e2ef1edf01b 2247 the row. The pattern always repeats every 8 pixels, so just 8
destinyXfate 2:0e2ef1edf01b 2248 bits are needed. A one indicates the pixel is to be combined,
destinyXfate 2:0e2ef1edf01b 2249 a zero indicates the pixel is to be skipped. This is in addition
destinyXfate 2:0e2ef1edf01b 2250 to any alpha or transparency value associated with the pixel. If
destinyXfate 2:0e2ef1edf01b 2251 you want all pixels to be combined, pass 0xff (255) in mask. */
destinyXfate 2:0e2ef1edf01b 2252 #ifndef PNG_HAVE_MMX_COMBINE_ROW
destinyXfate 2:0e2ef1edf01b 2253 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2254 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
destinyXfate 2:0e2ef1edf01b 2255 {
destinyXfate 2:0e2ef1edf01b 2256 png_debug(1,"in png_combine_row\n");
destinyXfate 2:0e2ef1edf01b 2257 if (mask == 0xff)
destinyXfate 2:0e2ef1edf01b 2258 {
destinyXfate 2:0e2ef1edf01b 2259 png_memcpy(row, png_ptr->row_buf + 1,
destinyXfate 2:0e2ef1edf01b 2260 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
destinyXfate 2:0e2ef1edf01b 2261 }
destinyXfate 2:0e2ef1edf01b 2262 else
destinyXfate 2:0e2ef1edf01b 2263 {
destinyXfate 2:0e2ef1edf01b 2264 switch (png_ptr->row_info.pixel_depth)
destinyXfate 2:0e2ef1edf01b 2265 {
destinyXfate 2:0e2ef1edf01b 2266 case 1:
destinyXfate 2:0e2ef1edf01b 2267 {
destinyXfate 2:0e2ef1edf01b 2268 png_bytep sp = png_ptr->row_buf + 1;
destinyXfate 2:0e2ef1edf01b 2269 png_bytep dp = row;
destinyXfate 2:0e2ef1edf01b 2270 int s_inc, s_start, s_end;
destinyXfate 2:0e2ef1edf01b 2271 int m = 0x80;
destinyXfate 2:0e2ef1edf01b 2272 int shift;
destinyXfate 2:0e2ef1edf01b 2273 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2274 png_uint_32 row_width = png_ptr->width;
destinyXfate 2:0e2ef1edf01b 2275
destinyXfate 2:0e2ef1edf01b 2276 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2277 if (png_ptr->transformations & PNG_PACKSWAP)
destinyXfate 2:0e2ef1edf01b 2278 {
destinyXfate 2:0e2ef1edf01b 2279 s_start = 0;
destinyXfate 2:0e2ef1edf01b 2280 s_end = 7;
destinyXfate 2:0e2ef1edf01b 2281 s_inc = 1;
destinyXfate 2:0e2ef1edf01b 2282 }
destinyXfate 2:0e2ef1edf01b 2283 else
destinyXfate 2:0e2ef1edf01b 2284 #endif
destinyXfate 2:0e2ef1edf01b 2285 {
destinyXfate 2:0e2ef1edf01b 2286 s_start = 7;
destinyXfate 2:0e2ef1edf01b 2287 s_end = 0;
destinyXfate 2:0e2ef1edf01b 2288 s_inc = -1;
destinyXfate 2:0e2ef1edf01b 2289 }
destinyXfate 2:0e2ef1edf01b 2290
destinyXfate 2:0e2ef1edf01b 2291 shift = s_start;
destinyXfate 2:0e2ef1edf01b 2292
destinyXfate 2:0e2ef1edf01b 2293 for (i = 0; i < row_width; i++)
destinyXfate 2:0e2ef1edf01b 2294 {
destinyXfate 2:0e2ef1edf01b 2295 if (m & mask)
destinyXfate 2:0e2ef1edf01b 2296 {
destinyXfate 2:0e2ef1edf01b 2297 int value;
destinyXfate 2:0e2ef1edf01b 2298
destinyXfate 2:0e2ef1edf01b 2299 value = (*sp >> shift) & 0x01;
destinyXfate 2:0e2ef1edf01b 2300 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2301 *dp |= (png_byte)(value << shift);
destinyXfate 2:0e2ef1edf01b 2302 }
destinyXfate 2:0e2ef1edf01b 2303
destinyXfate 2:0e2ef1edf01b 2304 if (shift == s_end)
destinyXfate 2:0e2ef1edf01b 2305 {
destinyXfate 2:0e2ef1edf01b 2306 shift = s_start;
destinyXfate 2:0e2ef1edf01b 2307 sp++;
destinyXfate 2:0e2ef1edf01b 2308 dp++;
destinyXfate 2:0e2ef1edf01b 2309 }
destinyXfate 2:0e2ef1edf01b 2310 else
destinyXfate 2:0e2ef1edf01b 2311 shift += s_inc;
destinyXfate 2:0e2ef1edf01b 2312
destinyXfate 2:0e2ef1edf01b 2313 if (m == 1)
destinyXfate 2:0e2ef1edf01b 2314 m = 0x80;
destinyXfate 2:0e2ef1edf01b 2315 else
destinyXfate 2:0e2ef1edf01b 2316 m >>= 1;
destinyXfate 2:0e2ef1edf01b 2317 }
destinyXfate 2:0e2ef1edf01b 2318 break;
destinyXfate 2:0e2ef1edf01b 2319 }
destinyXfate 2:0e2ef1edf01b 2320 case 2:
destinyXfate 2:0e2ef1edf01b 2321 {
destinyXfate 2:0e2ef1edf01b 2322 png_bytep sp = png_ptr->row_buf + 1;
destinyXfate 2:0e2ef1edf01b 2323 png_bytep dp = row;
destinyXfate 2:0e2ef1edf01b 2324 int s_start, s_end, s_inc;
destinyXfate 2:0e2ef1edf01b 2325 int m = 0x80;
destinyXfate 2:0e2ef1edf01b 2326 int shift;
destinyXfate 2:0e2ef1edf01b 2327 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2328 png_uint_32 row_width = png_ptr->width;
destinyXfate 2:0e2ef1edf01b 2329 int value;
destinyXfate 2:0e2ef1edf01b 2330
destinyXfate 2:0e2ef1edf01b 2331 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2332 if (png_ptr->transformations & PNG_PACKSWAP)
destinyXfate 2:0e2ef1edf01b 2333 {
destinyXfate 2:0e2ef1edf01b 2334 s_start = 0;
destinyXfate 2:0e2ef1edf01b 2335 s_end = 6;
destinyXfate 2:0e2ef1edf01b 2336 s_inc = 2;
destinyXfate 2:0e2ef1edf01b 2337 }
destinyXfate 2:0e2ef1edf01b 2338 else
destinyXfate 2:0e2ef1edf01b 2339 #endif
destinyXfate 2:0e2ef1edf01b 2340 {
destinyXfate 2:0e2ef1edf01b 2341 s_start = 6;
destinyXfate 2:0e2ef1edf01b 2342 s_end = 0;
destinyXfate 2:0e2ef1edf01b 2343 s_inc = -2;
destinyXfate 2:0e2ef1edf01b 2344 }
destinyXfate 2:0e2ef1edf01b 2345
destinyXfate 2:0e2ef1edf01b 2346 shift = s_start;
destinyXfate 2:0e2ef1edf01b 2347
destinyXfate 2:0e2ef1edf01b 2348 for (i = 0; i < row_width; i++)
destinyXfate 2:0e2ef1edf01b 2349 {
destinyXfate 2:0e2ef1edf01b 2350 if (m & mask)
destinyXfate 2:0e2ef1edf01b 2351 {
destinyXfate 2:0e2ef1edf01b 2352 value = (*sp >> shift) & 0x03;
destinyXfate 2:0e2ef1edf01b 2353 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2354 *dp |= (png_byte)(value << shift);
destinyXfate 2:0e2ef1edf01b 2355 }
destinyXfate 2:0e2ef1edf01b 2356
destinyXfate 2:0e2ef1edf01b 2357 if (shift == s_end)
destinyXfate 2:0e2ef1edf01b 2358 {
destinyXfate 2:0e2ef1edf01b 2359 shift = s_start;
destinyXfate 2:0e2ef1edf01b 2360 sp++;
destinyXfate 2:0e2ef1edf01b 2361 dp++;
destinyXfate 2:0e2ef1edf01b 2362 }
destinyXfate 2:0e2ef1edf01b 2363 else
destinyXfate 2:0e2ef1edf01b 2364 shift += s_inc;
destinyXfate 2:0e2ef1edf01b 2365 if (m == 1)
destinyXfate 2:0e2ef1edf01b 2366 m = 0x80;
destinyXfate 2:0e2ef1edf01b 2367 else
destinyXfate 2:0e2ef1edf01b 2368 m >>= 1;
destinyXfate 2:0e2ef1edf01b 2369 }
destinyXfate 2:0e2ef1edf01b 2370 break;
destinyXfate 2:0e2ef1edf01b 2371 }
destinyXfate 2:0e2ef1edf01b 2372 case 4:
destinyXfate 2:0e2ef1edf01b 2373 {
destinyXfate 2:0e2ef1edf01b 2374 png_bytep sp = png_ptr->row_buf + 1;
destinyXfate 2:0e2ef1edf01b 2375 png_bytep dp = row;
destinyXfate 2:0e2ef1edf01b 2376 int s_start, s_end, s_inc;
destinyXfate 2:0e2ef1edf01b 2377 int m = 0x80;
destinyXfate 2:0e2ef1edf01b 2378 int shift;
destinyXfate 2:0e2ef1edf01b 2379 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2380 png_uint_32 row_width = png_ptr->width;
destinyXfate 2:0e2ef1edf01b 2381 int value;
destinyXfate 2:0e2ef1edf01b 2382
destinyXfate 2:0e2ef1edf01b 2383 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2384 if (png_ptr->transformations & PNG_PACKSWAP)
destinyXfate 2:0e2ef1edf01b 2385 {
destinyXfate 2:0e2ef1edf01b 2386 s_start = 0;
destinyXfate 2:0e2ef1edf01b 2387 s_end = 4;
destinyXfate 2:0e2ef1edf01b 2388 s_inc = 4;
destinyXfate 2:0e2ef1edf01b 2389 }
destinyXfate 2:0e2ef1edf01b 2390 else
destinyXfate 2:0e2ef1edf01b 2391 #endif
destinyXfate 2:0e2ef1edf01b 2392 {
destinyXfate 2:0e2ef1edf01b 2393 s_start = 4;
destinyXfate 2:0e2ef1edf01b 2394 s_end = 0;
destinyXfate 2:0e2ef1edf01b 2395 s_inc = -4;
destinyXfate 2:0e2ef1edf01b 2396 }
destinyXfate 2:0e2ef1edf01b 2397 shift = s_start;
destinyXfate 2:0e2ef1edf01b 2398
destinyXfate 2:0e2ef1edf01b 2399 for (i = 0; i < row_width; i++)
destinyXfate 2:0e2ef1edf01b 2400 {
destinyXfate 2:0e2ef1edf01b 2401 if (m & mask)
destinyXfate 2:0e2ef1edf01b 2402 {
destinyXfate 2:0e2ef1edf01b 2403 value = (*sp >> shift) & 0xf;
destinyXfate 2:0e2ef1edf01b 2404 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2405 *dp |= (png_byte)(value << shift);
destinyXfate 2:0e2ef1edf01b 2406 }
destinyXfate 2:0e2ef1edf01b 2407
destinyXfate 2:0e2ef1edf01b 2408 if (shift == s_end)
destinyXfate 2:0e2ef1edf01b 2409 {
destinyXfate 2:0e2ef1edf01b 2410 shift = s_start;
destinyXfate 2:0e2ef1edf01b 2411 sp++;
destinyXfate 2:0e2ef1edf01b 2412 dp++;
destinyXfate 2:0e2ef1edf01b 2413 }
destinyXfate 2:0e2ef1edf01b 2414 else
destinyXfate 2:0e2ef1edf01b 2415 shift += s_inc;
destinyXfate 2:0e2ef1edf01b 2416 if (m == 1)
destinyXfate 2:0e2ef1edf01b 2417 m = 0x80;
destinyXfate 2:0e2ef1edf01b 2418 else
destinyXfate 2:0e2ef1edf01b 2419 m >>= 1;
destinyXfate 2:0e2ef1edf01b 2420 }
destinyXfate 2:0e2ef1edf01b 2421 break;
destinyXfate 2:0e2ef1edf01b 2422 }
destinyXfate 2:0e2ef1edf01b 2423 default:
destinyXfate 2:0e2ef1edf01b 2424 {
destinyXfate 2:0e2ef1edf01b 2425 png_bytep sp = png_ptr->row_buf + 1;
destinyXfate 2:0e2ef1edf01b 2426 png_bytep dp = row;
destinyXfate 2:0e2ef1edf01b 2427 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
destinyXfate 2:0e2ef1edf01b 2428 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2429 png_uint_32 row_width = png_ptr->width;
destinyXfate 2:0e2ef1edf01b 2430 png_byte m = 0x80;
destinyXfate 2:0e2ef1edf01b 2431
destinyXfate 2:0e2ef1edf01b 2432
destinyXfate 2:0e2ef1edf01b 2433 for (i = 0; i < row_width; i++)
destinyXfate 2:0e2ef1edf01b 2434 {
destinyXfate 2:0e2ef1edf01b 2435 if (m & mask)
destinyXfate 2:0e2ef1edf01b 2436 {
destinyXfate 2:0e2ef1edf01b 2437 png_memcpy(dp, sp, pixel_bytes);
destinyXfate 2:0e2ef1edf01b 2438 }
destinyXfate 2:0e2ef1edf01b 2439
destinyXfate 2:0e2ef1edf01b 2440 sp += pixel_bytes;
destinyXfate 2:0e2ef1edf01b 2441 dp += pixel_bytes;
destinyXfate 2:0e2ef1edf01b 2442
destinyXfate 2:0e2ef1edf01b 2443 if (m == 1)
destinyXfate 2:0e2ef1edf01b 2444 m = 0x80;
destinyXfate 2:0e2ef1edf01b 2445 else
destinyXfate 2:0e2ef1edf01b 2446 m >>= 1;
destinyXfate 2:0e2ef1edf01b 2447 }
destinyXfate 2:0e2ef1edf01b 2448 break;
destinyXfate 2:0e2ef1edf01b 2449 }
destinyXfate 2:0e2ef1edf01b 2450 }
destinyXfate 2:0e2ef1edf01b 2451 }
destinyXfate 2:0e2ef1edf01b 2452 }
destinyXfate 2:0e2ef1edf01b 2453 #endif /* !PNG_HAVE_MMX_COMBINE_ROW */
destinyXfate 2:0e2ef1edf01b 2454
destinyXfate 2:0e2ef1edf01b 2455 #ifdef PNG_READ_INTERLACING_SUPPORTED
destinyXfate 2:0e2ef1edf01b 2456 #ifndef PNG_HAVE_MMX_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
destinyXfate 2:0e2ef1edf01b 2457 /* OLD pre-1.0.9 interface:
destinyXfate 2:0e2ef1edf01b 2458 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
destinyXfate 2:0e2ef1edf01b 2459 png_uint_32 transformations)
destinyXfate 2:0e2ef1edf01b 2460 */
destinyXfate 2:0e2ef1edf01b 2461 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2462 png_do_read_interlace(png_structp png_ptr)
destinyXfate 2:0e2ef1edf01b 2463 {
destinyXfate 2:0e2ef1edf01b 2464 png_row_infop row_info = &(png_ptr->row_info);
destinyXfate 2:0e2ef1edf01b 2465 png_bytep row = png_ptr->row_buf + 1;
destinyXfate 2:0e2ef1edf01b 2466 int pass = png_ptr->pass;
destinyXfate 2:0e2ef1edf01b 2467 png_uint_32 transformations = png_ptr->transformations;
destinyXfate 2:0e2ef1edf01b 2468 #ifdef PNG_USE_LOCAL_ARRAYS
destinyXfate 2:0e2ef1edf01b 2469 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
destinyXfate 2:0e2ef1edf01b 2470 /* offset to next interlace block */
destinyXfate 2:0e2ef1edf01b 2471 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
destinyXfate 2:0e2ef1edf01b 2472 #endif
destinyXfate 2:0e2ef1edf01b 2473
destinyXfate 2:0e2ef1edf01b 2474 png_debug(1,"in png_do_read_interlace (stock C version)\n");
destinyXfate 2:0e2ef1edf01b 2475 if (row != NULL && row_info != NULL)
destinyXfate 2:0e2ef1edf01b 2476 {
destinyXfate 2:0e2ef1edf01b 2477 png_uint_32 final_width;
destinyXfate 2:0e2ef1edf01b 2478
destinyXfate 2:0e2ef1edf01b 2479 final_width = row_info->width * png_pass_inc[pass];
destinyXfate 2:0e2ef1edf01b 2480
destinyXfate 2:0e2ef1edf01b 2481 switch (row_info->pixel_depth)
destinyXfate 2:0e2ef1edf01b 2482 {
destinyXfate 2:0e2ef1edf01b 2483 case 1:
destinyXfate 2:0e2ef1edf01b 2484 {
destinyXfate 2:0e2ef1edf01b 2485 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
destinyXfate 2:0e2ef1edf01b 2486 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
destinyXfate 2:0e2ef1edf01b 2487 int sshift, dshift;
destinyXfate 2:0e2ef1edf01b 2488 int s_start, s_end, s_inc;
destinyXfate 2:0e2ef1edf01b 2489 int jstop = png_pass_inc[pass];
destinyXfate 2:0e2ef1edf01b 2490 png_byte v;
destinyXfate 2:0e2ef1edf01b 2491 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2492 int j;
destinyXfate 2:0e2ef1edf01b 2493
destinyXfate 2:0e2ef1edf01b 2494 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2495 if (transformations & PNG_PACKSWAP)
destinyXfate 2:0e2ef1edf01b 2496 {
destinyXfate 2:0e2ef1edf01b 2497 sshift = (int)((row_info->width + 7) & 0x07);
destinyXfate 2:0e2ef1edf01b 2498 dshift = (int)((final_width + 7) & 0x07);
destinyXfate 2:0e2ef1edf01b 2499 s_start = 7;
destinyXfate 2:0e2ef1edf01b 2500 s_end = 0;
destinyXfate 2:0e2ef1edf01b 2501 s_inc = -1;
destinyXfate 2:0e2ef1edf01b 2502 }
destinyXfate 2:0e2ef1edf01b 2503 else
destinyXfate 2:0e2ef1edf01b 2504 #endif
destinyXfate 2:0e2ef1edf01b 2505 {
destinyXfate 2:0e2ef1edf01b 2506 sshift = 7 - (int)((row_info->width + 7) & 0x07);
destinyXfate 2:0e2ef1edf01b 2507 dshift = 7 - (int)((final_width + 7) & 0x07);
destinyXfate 2:0e2ef1edf01b 2508 s_start = 0;
destinyXfate 2:0e2ef1edf01b 2509 s_end = 7;
destinyXfate 2:0e2ef1edf01b 2510 s_inc = 1;
destinyXfate 2:0e2ef1edf01b 2511 }
destinyXfate 2:0e2ef1edf01b 2512
destinyXfate 2:0e2ef1edf01b 2513 for (i = 0; i < row_info->width; i++)
destinyXfate 2:0e2ef1edf01b 2514 {
destinyXfate 2:0e2ef1edf01b 2515 v = (png_byte)((*sp >> sshift) & 0x01);
destinyXfate 2:0e2ef1edf01b 2516 for (j = 0; j < jstop; j++)
destinyXfate 2:0e2ef1edf01b 2517 {
destinyXfate 2:0e2ef1edf01b 2518 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2519 *dp |= (png_byte)(v << dshift);
destinyXfate 2:0e2ef1edf01b 2520 if (dshift == s_end)
destinyXfate 2:0e2ef1edf01b 2521 {
destinyXfate 2:0e2ef1edf01b 2522 dshift = s_start;
destinyXfate 2:0e2ef1edf01b 2523 dp--;
destinyXfate 2:0e2ef1edf01b 2524 }
destinyXfate 2:0e2ef1edf01b 2525 else
destinyXfate 2:0e2ef1edf01b 2526 dshift += s_inc;
destinyXfate 2:0e2ef1edf01b 2527 }
destinyXfate 2:0e2ef1edf01b 2528 if (sshift == s_end)
destinyXfate 2:0e2ef1edf01b 2529 {
destinyXfate 2:0e2ef1edf01b 2530 sshift = s_start;
destinyXfate 2:0e2ef1edf01b 2531 sp--;
destinyXfate 2:0e2ef1edf01b 2532 }
destinyXfate 2:0e2ef1edf01b 2533 else
destinyXfate 2:0e2ef1edf01b 2534 sshift += s_inc;
destinyXfate 2:0e2ef1edf01b 2535 }
destinyXfate 2:0e2ef1edf01b 2536 break;
destinyXfate 2:0e2ef1edf01b 2537 }
destinyXfate 2:0e2ef1edf01b 2538 case 2:
destinyXfate 2:0e2ef1edf01b 2539 {
destinyXfate 2:0e2ef1edf01b 2540 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
destinyXfate 2:0e2ef1edf01b 2541 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
destinyXfate 2:0e2ef1edf01b 2542 int sshift, dshift;
destinyXfate 2:0e2ef1edf01b 2543 int s_start, s_end, s_inc;
destinyXfate 2:0e2ef1edf01b 2544 int jstop = png_pass_inc[pass];
destinyXfate 2:0e2ef1edf01b 2545 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2546
destinyXfate 2:0e2ef1edf01b 2547 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2548 if (transformations & PNG_PACKSWAP)
destinyXfate 2:0e2ef1edf01b 2549 {
destinyXfate 2:0e2ef1edf01b 2550 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
destinyXfate 2:0e2ef1edf01b 2551 dshift = (int)(((final_width + 3) & 0x03) << 1);
destinyXfate 2:0e2ef1edf01b 2552 s_start = 6;
destinyXfate 2:0e2ef1edf01b 2553 s_end = 0;
destinyXfate 2:0e2ef1edf01b 2554 s_inc = -2;
destinyXfate 2:0e2ef1edf01b 2555 }
destinyXfate 2:0e2ef1edf01b 2556 else
destinyXfate 2:0e2ef1edf01b 2557 #endif
destinyXfate 2:0e2ef1edf01b 2558 {
destinyXfate 2:0e2ef1edf01b 2559 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
destinyXfate 2:0e2ef1edf01b 2560 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
destinyXfate 2:0e2ef1edf01b 2561 s_start = 0;
destinyXfate 2:0e2ef1edf01b 2562 s_end = 6;
destinyXfate 2:0e2ef1edf01b 2563 s_inc = 2;
destinyXfate 2:0e2ef1edf01b 2564 }
destinyXfate 2:0e2ef1edf01b 2565
destinyXfate 2:0e2ef1edf01b 2566 for (i = 0; i < row_info->width; i++)
destinyXfate 2:0e2ef1edf01b 2567 {
destinyXfate 2:0e2ef1edf01b 2568 png_byte v;
destinyXfate 2:0e2ef1edf01b 2569 int j;
destinyXfate 2:0e2ef1edf01b 2570
destinyXfate 2:0e2ef1edf01b 2571 v = (png_byte)((*sp >> sshift) & 0x03);
destinyXfate 2:0e2ef1edf01b 2572 for (j = 0; j < jstop; j++)
destinyXfate 2:0e2ef1edf01b 2573 {
destinyXfate 2:0e2ef1edf01b 2574 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2575 *dp |= (png_byte)(v << dshift);
destinyXfate 2:0e2ef1edf01b 2576 if (dshift == s_end)
destinyXfate 2:0e2ef1edf01b 2577 {
destinyXfate 2:0e2ef1edf01b 2578 dshift = s_start;
destinyXfate 2:0e2ef1edf01b 2579 dp--;
destinyXfate 2:0e2ef1edf01b 2580 }
destinyXfate 2:0e2ef1edf01b 2581 else
destinyXfate 2:0e2ef1edf01b 2582 dshift += s_inc;
destinyXfate 2:0e2ef1edf01b 2583 }
destinyXfate 2:0e2ef1edf01b 2584 if (sshift == s_end)
destinyXfate 2:0e2ef1edf01b 2585 {
destinyXfate 2:0e2ef1edf01b 2586 sshift = s_start;
destinyXfate 2:0e2ef1edf01b 2587 sp--;
destinyXfate 2:0e2ef1edf01b 2588 }
destinyXfate 2:0e2ef1edf01b 2589 else
destinyXfate 2:0e2ef1edf01b 2590 sshift += s_inc;
destinyXfate 2:0e2ef1edf01b 2591 }
destinyXfate 2:0e2ef1edf01b 2592 break;
destinyXfate 2:0e2ef1edf01b 2593 }
destinyXfate 2:0e2ef1edf01b 2594 case 4:
destinyXfate 2:0e2ef1edf01b 2595 {
destinyXfate 2:0e2ef1edf01b 2596 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
destinyXfate 2:0e2ef1edf01b 2597 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
destinyXfate 2:0e2ef1edf01b 2598 int sshift, dshift;
destinyXfate 2:0e2ef1edf01b 2599 int s_start, s_end, s_inc;
destinyXfate 2:0e2ef1edf01b 2600 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2601 int jstop = png_pass_inc[pass];
destinyXfate 2:0e2ef1edf01b 2602
destinyXfate 2:0e2ef1edf01b 2603 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2604 if (transformations & PNG_PACKSWAP)
destinyXfate 2:0e2ef1edf01b 2605 {
destinyXfate 2:0e2ef1edf01b 2606 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
destinyXfate 2:0e2ef1edf01b 2607 dshift = (int)(((final_width + 1) & 0x01) << 2);
destinyXfate 2:0e2ef1edf01b 2608 s_start = 4;
destinyXfate 2:0e2ef1edf01b 2609 s_end = 0;
destinyXfate 2:0e2ef1edf01b 2610 s_inc = -4;
destinyXfate 2:0e2ef1edf01b 2611 }
destinyXfate 2:0e2ef1edf01b 2612 else
destinyXfate 2:0e2ef1edf01b 2613 #endif
destinyXfate 2:0e2ef1edf01b 2614 {
destinyXfate 2:0e2ef1edf01b 2615 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
destinyXfate 2:0e2ef1edf01b 2616 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
destinyXfate 2:0e2ef1edf01b 2617 s_start = 0;
destinyXfate 2:0e2ef1edf01b 2618 s_end = 4;
destinyXfate 2:0e2ef1edf01b 2619 s_inc = 4;
destinyXfate 2:0e2ef1edf01b 2620 }
destinyXfate 2:0e2ef1edf01b 2621
destinyXfate 2:0e2ef1edf01b 2622 for (i = 0; i < row_info->width; i++)
destinyXfate 2:0e2ef1edf01b 2623 {
destinyXfate 2:0e2ef1edf01b 2624 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
destinyXfate 2:0e2ef1edf01b 2625 int j;
destinyXfate 2:0e2ef1edf01b 2626
destinyXfate 2:0e2ef1edf01b 2627 for (j = 0; j < jstop; j++)
destinyXfate 2:0e2ef1edf01b 2628 {
destinyXfate 2:0e2ef1edf01b 2629 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2630 *dp |= (png_byte)(v << dshift);
destinyXfate 2:0e2ef1edf01b 2631 if (dshift == s_end)
destinyXfate 2:0e2ef1edf01b 2632 {
destinyXfate 2:0e2ef1edf01b 2633 dshift = s_start;
destinyXfate 2:0e2ef1edf01b 2634 dp--;
destinyXfate 2:0e2ef1edf01b 2635 }
destinyXfate 2:0e2ef1edf01b 2636 else
destinyXfate 2:0e2ef1edf01b 2637 dshift += s_inc;
destinyXfate 2:0e2ef1edf01b 2638 }
destinyXfate 2:0e2ef1edf01b 2639 if (sshift == s_end)
destinyXfate 2:0e2ef1edf01b 2640 {
destinyXfate 2:0e2ef1edf01b 2641 sshift = s_start;
destinyXfate 2:0e2ef1edf01b 2642 sp--;
destinyXfate 2:0e2ef1edf01b 2643 }
destinyXfate 2:0e2ef1edf01b 2644 else
destinyXfate 2:0e2ef1edf01b 2645 sshift += s_inc;
destinyXfate 2:0e2ef1edf01b 2646 }
destinyXfate 2:0e2ef1edf01b 2647 break;
destinyXfate 2:0e2ef1edf01b 2648 }
destinyXfate 2:0e2ef1edf01b 2649 default:
destinyXfate 2:0e2ef1edf01b 2650 {
destinyXfate 2:0e2ef1edf01b 2651 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
destinyXfate 2:0e2ef1edf01b 2652 png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
destinyXfate 2:0e2ef1edf01b 2653 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
destinyXfate 2:0e2ef1edf01b 2654
destinyXfate 2:0e2ef1edf01b 2655 int jstop = png_pass_inc[pass];
destinyXfate 2:0e2ef1edf01b 2656 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2657
destinyXfate 2:0e2ef1edf01b 2658 for (i = 0; i < row_info->width; i++)
destinyXfate 2:0e2ef1edf01b 2659 {
destinyXfate 2:0e2ef1edf01b 2660 png_byte v[8];
destinyXfate 2:0e2ef1edf01b 2661 int j;
destinyXfate 2:0e2ef1edf01b 2662
destinyXfate 2:0e2ef1edf01b 2663 png_memcpy(v, sp, pixel_bytes);
destinyXfate 2:0e2ef1edf01b 2664 for (j = 0; j < jstop; j++)
destinyXfate 2:0e2ef1edf01b 2665 {
destinyXfate 2:0e2ef1edf01b 2666 png_memcpy(dp, v, pixel_bytes);
destinyXfate 2:0e2ef1edf01b 2667 dp -= pixel_bytes;
destinyXfate 2:0e2ef1edf01b 2668 }
destinyXfate 2:0e2ef1edf01b 2669 sp -= pixel_bytes;
destinyXfate 2:0e2ef1edf01b 2670 }
destinyXfate 2:0e2ef1edf01b 2671 break;
destinyXfate 2:0e2ef1edf01b 2672 }
destinyXfate 2:0e2ef1edf01b 2673 }
destinyXfate 2:0e2ef1edf01b 2674 row_info->width = final_width;
destinyXfate 2:0e2ef1edf01b 2675 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
destinyXfate 2:0e2ef1edf01b 2676 }
destinyXfate 2:0e2ef1edf01b 2677 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2678 if (&transformations == NULL) /* silence compiler warning */
destinyXfate 2:0e2ef1edf01b 2679 return;
destinyXfate 2:0e2ef1edf01b 2680 #endif
destinyXfate 2:0e2ef1edf01b 2681 }
destinyXfate 2:0e2ef1edf01b 2682 #endif /* !PNG_HAVE_MMX_READ_INTERLACE */
destinyXfate 2:0e2ef1edf01b 2683 #endif /* PNG_READ_INTERLACING_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 2684
destinyXfate 2:0e2ef1edf01b 2685 #ifndef PNG_HAVE_MMX_READ_FILTER_ROW
destinyXfate 2:0e2ef1edf01b 2686 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2687 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
destinyXfate 2:0e2ef1edf01b 2688 png_bytep prev_row, int filter)
destinyXfate 2:0e2ef1edf01b 2689 {
destinyXfate 2:0e2ef1edf01b 2690 png_debug(1, "in png_read_filter_row\n");
destinyXfate 2:0e2ef1edf01b 2691 png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
destinyXfate 2:0e2ef1edf01b 2692 switch (filter)
destinyXfate 2:0e2ef1edf01b 2693 {
destinyXfate 2:0e2ef1edf01b 2694 case PNG_FILTER_VALUE_NONE:
destinyXfate 2:0e2ef1edf01b 2695 break;
destinyXfate 2:0e2ef1edf01b 2696 case PNG_FILTER_VALUE_SUB:
destinyXfate 2:0e2ef1edf01b 2697 {
destinyXfate 2:0e2ef1edf01b 2698 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2699 png_uint_32 istop = row_info->rowbytes;
destinyXfate 2:0e2ef1edf01b 2700 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
destinyXfate 2:0e2ef1edf01b 2701 png_bytep rp = row + bpp;
destinyXfate 2:0e2ef1edf01b 2702 png_bytep lp = row;
destinyXfate 2:0e2ef1edf01b 2703
destinyXfate 2:0e2ef1edf01b 2704 for (i = bpp; i < istop; i++)
destinyXfate 2:0e2ef1edf01b 2705 {
destinyXfate 2:0e2ef1edf01b 2706 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2707 rp++;
destinyXfate 2:0e2ef1edf01b 2708 }
destinyXfate 2:0e2ef1edf01b 2709 break;
destinyXfate 2:0e2ef1edf01b 2710 }
destinyXfate 2:0e2ef1edf01b 2711 case PNG_FILTER_VALUE_UP:
destinyXfate 2:0e2ef1edf01b 2712 {
destinyXfate 2:0e2ef1edf01b 2713 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2714 png_uint_32 istop = row_info->rowbytes;
destinyXfate 2:0e2ef1edf01b 2715 png_bytep rp = row;
destinyXfate 2:0e2ef1edf01b 2716 png_bytep pp = prev_row;
destinyXfate 2:0e2ef1edf01b 2717
destinyXfate 2:0e2ef1edf01b 2718 for (i = 0; i < istop; i++)
destinyXfate 2:0e2ef1edf01b 2719 {
destinyXfate 2:0e2ef1edf01b 2720 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2721 rp++;
destinyXfate 2:0e2ef1edf01b 2722 }
destinyXfate 2:0e2ef1edf01b 2723 break;
destinyXfate 2:0e2ef1edf01b 2724 }
destinyXfate 2:0e2ef1edf01b 2725 case PNG_FILTER_VALUE_AVG:
destinyXfate 2:0e2ef1edf01b 2726 {
destinyXfate 2:0e2ef1edf01b 2727 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2728 png_bytep rp = row;
destinyXfate 2:0e2ef1edf01b 2729 png_bytep pp = prev_row;
destinyXfate 2:0e2ef1edf01b 2730 png_bytep lp = row;
destinyXfate 2:0e2ef1edf01b 2731 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
destinyXfate 2:0e2ef1edf01b 2732 png_uint_32 istop = row_info->rowbytes - bpp;
destinyXfate 2:0e2ef1edf01b 2733
destinyXfate 2:0e2ef1edf01b 2734 for (i = 0; i < bpp; i++)
destinyXfate 2:0e2ef1edf01b 2735 {
destinyXfate 2:0e2ef1edf01b 2736 *rp = (png_byte)(((int)(*rp) +
destinyXfate 2:0e2ef1edf01b 2737 ((int)(*pp++) / 2 )) & 0xff);
destinyXfate 2:0e2ef1edf01b 2738 rp++;
destinyXfate 2:0e2ef1edf01b 2739 }
destinyXfate 2:0e2ef1edf01b 2740
destinyXfate 2:0e2ef1edf01b 2741 for (i = 0; i < istop; i++)
destinyXfate 2:0e2ef1edf01b 2742 {
destinyXfate 2:0e2ef1edf01b 2743 *rp = (png_byte)(((int)(*rp) +
destinyXfate 2:0e2ef1edf01b 2744 (int)(*pp++ + *lp++) / 2 ) & 0xff);
destinyXfate 2:0e2ef1edf01b 2745 rp++;
destinyXfate 2:0e2ef1edf01b 2746 }
destinyXfate 2:0e2ef1edf01b 2747 break;
destinyXfate 2:0e2ef1edf01b 2748 }
destinyXfate 2:0e2ef1edf01b 2749 case PNG_FILTER_VALUE_PAETH:
destinyXfate 2:0e2ef1edf01b 2750 {
destinyXfate 2:0e2ef1edf01b 2751 png_uint_32 i;
destinyXfate 2:0e2ef1edf01b 2752 png_bytep rp = row;
destinyXfate 2:0e2ef1edf01b 2753 png_bytep pp = prev_row;
destinyXfate 2:0e2ef1edf01b 2754 png_bytep lp = row;
destinyXfate 2:0e2ef1edf01b 2755 png_bytep cp = prev_row;
destinyXfate 2:0e2ef1edf01b 2756 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
destinyXfate 2:0e2ef1edf01b 2757 png_uint_32 istop=row_info->rowbytes - bpp;
destinyXfate 2:0e2ef1edf01b 2758
destinyXfate 2:0e2ef1edf01b 2759 for (i = 0; i < bpp; i++)
destinyXfate 2:0e2ef1edf01b 2760 {
destinyXfate 2:0e2ef1edf01b 2761 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
destinyXfate 2:0e2ef1edf01b 2762 rp++;
destinyXfate 2:0e2ef1edf01b 2763 }
destinyXfate 2:0e2ef1edf01b 2764
destinyXfate 2:0e2ef1edf01b 2765 for (i = 0; i < istop; i++) /* use leftover rp,pp */
destinyXfate 2:0e2ef1edf01b 2766 {
destinyXfate 2:0e2ef1edf01b 2767 int a, b, c, pa, pb, pc, p;
destinyXfate 2:0e2ef1edf01b 2768
destinyXfate 2:0e2ef1edf01b 2769 a = *lp++;
destinyXfate 2:0e2ef1edf01b 2770 b = *pp++;
destinyXfate 2:0e2ef1edf01b 2771 c = *cp++;
destinyXfate 2:0e2ef1edf01b 2772
destinyXfate 2:0e2ef1edf01b 2773 p = b - c;
destinyXfate 2:0e2ef1edf01b 2774 pc = a - c;
destinyXfate 2:0e2ef1edf01b 2775
destinyXfate 2:0e2ef1edf01b 2776 #ifdef PNG_USE_ABS
destinyXfate 2:0e2ef1edf01b 2777 pa = abs(p);
destinyXfate 2:0e2ef1edf01b 2778 pb = abs(pc);
destinyXfate 2:0e2ef1edf01b 2779 pc = abs(p + pc);
destinyXfate 2:0e2ef1edf01b 2780 #else
destinyXfate 2:0e2ef1edf01b 2781 pa = p < 0 ? -p : p;
destinyXfate 2:0e2ef1edf01b 2782 pb = pc < 0 ? -pc : pc;
destinyXfate 2:0e2ef1edf01b 2783 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
destinyXfate 2:0e2ef1edf01b 2784 #endif
destinyXfate 2:0e2ef1edf01b 2785
destinyXfate 2:0e2ef1edf01b 2786 /*
destinyXfate 2:0e2ef1edf01b 2787 if (pa <= pb && pa <= pc)
destinyXfate 2:0e2ef1edf01b 2788 p = a;
destinyXfate 2:0e2ef1edf01b 2789 else if (pb <= pc)
destinyXfate 2:0e2ef1edf01b 2790 p = b;
destinyXfate 2:0e2ef1edf01b 2791 else
destinyXfate 2:0e2ef1edf01b 2792 p = c;
destinyXfate 2:0e2ef1edf01b 2793 */
destinyXfate 2:0e2ef1edf01b 2794
destinyXfate 2:0e2ef1edf01b 2795 p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
destinyXfate 2:0e2ef1edf01b 2796
destinyXfate 2:0e2ef1edf01b 2797 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
destinyXfate 2:0e2ef1edf01b 2798 rp++;
destinyXfate 2:0e2ef1edf01b 2799 }
destinyXfate 2:0e2ef1edf01b 2800 break;
destinyXfate 2:0e2ef1edf01b 2801 }
destinyXfate 2:0e2ef1edf01b 2802 default:
destinyXfate 2:0e2ef1edf01b 2803 png_warning(png_ptr, "Ignoring bad adaptive filter type");
destinyXfate 2:0e2ef1edf01b 2804 *row=0;
destinyXfate 2:0e2ef1edf01b 2805 break;
destinyXfate 2:0e2ef1edf01b 2806 }
destinyXfate 2:0e2ef1edf01b 2807 }
destinyXfate 2:0e2ef1edf01b 2808 #endif /* !PNG_HAVE_MMX_READ_FILTER_ROW */
destinyXfate 2:0e2ef1edf01b 2809
destinyXfate 2:0e2ef1edf01b 2810 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2811 png_read_finish_row(png_structp png_ptr)
destinyXfate 2:0e2ef1edf01b 2812 {
destinyXfate 2:0e2ef1edf01b 2813 #ifdef PNG_USE_LOCAL_ARRAYS
destinyXfate 2:0e2ef1edf01b 2814 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
destinyXfate 2:0e2ef1edf01b 2815
destinyXfate 2:0e2ef1edf01b 2816 /* start of interlace block */
destinyXfate 2:0e2ef1edf01b 2817 const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
destinyXfate 2:0e2ef1edf01b 2818
destinyXfate 2:0e2ef1edf01b 2819 /* offset to next interlace block */
destinyXfate 2:0e2ef1edf01b 2820 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
destinyXfate 2:0e2ef1edf01b 2821
destinyXfate 2:0e2ef1edf01b 2822 /* start of interlace block in the y direction */
destinyXfate 2:0e2ef1edf01b 2823 const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
destinyXfate 2:0e2ef1edf01b 2824
destinyXfate 2:0e2ef1edf01b 2825 /* offset to next interlace block in the y direction */
destinyXfate 2:0e2ef1edf01b 2826 const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
destinyXfate 2:0e2ef1edf01b 2827 #endif
destinyXfate 2:0e2ef1edf01b 2828
destinyXfate 2:0e2ef1edf01b 2829 png_debug(1, "in png_read_finish_row\n");
destinyXfate 2:0e2ef1edf01b 2830 png_ptr->row_number++;
destinyXfate 2:0e2ef1edf01b 2831 if (png_ptr->row_number < png_ptr->num_rows)
destinyXfate 2:0e2ef1edf01b 2832 return;
destinyXfate 2:0e2ef1edf01b 2833
destinyXfate 2:0e2ef1edf01b 2834 if (png_ptr->interlaced)
destinyXfate 2:0e2ef1edf01b 2835 {
destinyXfate 2:0e2ef1edf01b 2836 png_ptr->row_number = 0;
destinyXfate 2:0e2ef1edf01b 2837 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
destinyXfate 2:0e2ef1edf01b 2838 do
destinyXfate 2:0e2ef1edf01b 2839 {
destinyXfate 2:0e2ef1edf01b 2840 png_ptr->pass++;
destinyXfate 2:0e2ef1edf01b 2841 if (png_ptr->pass >= 7)
destinyXfate 2:0e2ef1edf01b 2842 break;
destinyXfate 2:0e2ef1edf01b 2843 png_ptr->iwidth = (png_ptr->width +
destinyXfate 2:0e2ef1edf01b 2844 png_pass_inc[png_ptr->pass] - 1 -
destinyXfate 2:0e2ef1edf01b 2845 png_pass_start[png_ptr->pass]) /
destinyXfate 2:0e2ef1edf01b 2846 png_pass_inc[png_ptr->pass];
destinyXfate 2:0e2ef1edf01b 2847
destinyXfate 2:0e2ef1edf01b 2848 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
destinyXfate 2:0e2ef1edf01b 2849 png_ptr->iwidth) + 1;
destinyXfate 2:0e2ef1edf01b 2850
destinyXfate 2:0e2ef1edf01b 2851 if (!(png_ptr->transformations & PNG_INTERLACE))
destinyXfate 2:0e2ef1edf01b 2852 {
destinyXfate 2:0e2ef1edf01b 2853 png_ptr->num_rows = (png_ptr->height +
destinyXfate 2:0e2ef1edf01b 2854 png_pass_yinc[png_ptr->pass] - 1 -
destinyXfate 2:0e2ef1edf01b 2855 png_pass_ystart[png_ptr->pass]) /
destinyXfate 2:0e2ef1edf01b 2856 png_pass_yinc[png_ptr->pass];
destinyXfate 2:0e2ef1edf01b 2857 if (!(png_ptr->num_rows))
destinyXfate 2:0e2ef1edf01b 2858 continue;
destinyXfate 2:0e2ef1edf01b 2859 }
destinyXfate 2:0e2ef1edf01b 2860 else /* if (png_ptr->transformations & PNG_INTERLACE) */
destinyXfate 2:0e2ef1edf01b 2861 break;
destinyXfate 2:0e2ef1edf01b 2862 } while (png_ptr->iwidth == 0);
destinyXfate 2:0e2ef1edf01b 2863
destinyXfate 2:0e2ef1edf01b 2864 if (png_ptr->pass < 7)
destinyXfate 2:0e2ef1edf01b 2865 return;
destinyXfate 2:0e2ef1edf01b 2866 }
destinyXfate 2:0e2ef1edf01b 2867
destinyXfate 2:0e2ef1edf01b 2868 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
destinyXfate 2:0e2ef1edf01b 2869 {
destinyXfate 2:0e2ef1edf01b 2870 #ifdef PNG_USE_LOCAL_ARRAYS
destinyXfate 2:0e2ef1edf01b 2871 PNG_IDAT;
destinyXfate 2:0e2ef1edf01b 2872 #endif
destinyXfate 2:0e2ef1edf01b 2873 char extra;
destinyXfate 2:0e2ef1edf01b 2874 int ret;
destinyXfate 2:0e2ef1edf01b 2875
destinyXfate 2:0e2ef1edf01b 2876 png_ptr->zstream.next_out = (Byte *)&extra;
destinyXfate 2:0e2ef1edf01b 2877 png_ptr->zstream.avail_out = (uInt)1;
destinyXfate 2:0e2ef1edf01b 2878 for(;;)
destinyXfate 2:0e2ef1edf01b 2879 {
destinyXfate 2:0e2ef1edf01b 2880 if (!(png_ptr->zstream.avail_in))
destinyXfate 2:0e2ef1edf01b 2881 {
destinyXfate 2:0e2ef1edf01b 2882 while (!png_ptr->idat_size)
destinyXfate 2:0e2ef1edf01b 2883 {
destinyXfate 2:0e2ef1edf01b 2884 png_byte chunk_length[4];
destinyXfate 2:0e2ef1edf01b 2885
destinyXfate 2:0e2ef1edf01b 2886 png_crc_finish(png_ptr, 0);
destinyXfate 2:0e2ef1edf01b 2887
destinyXfate 2:0e2ef1edf01b 2888 png_read_data(png_ptr, chunk_length, 4);
destinyXfate 2:0e2ef1edf01b 2889 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
destinyXfate 2:0e2ef1edf01b 2890 png_reset_crc(png_ptr);
destinyXfate 2:0e2ef1edf01b 2891 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
destinyXfate 2:0e2ef1edf01b 2892 if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
destinyXfate 2:0e2ef1edf01b 2893 png_error(png_ptr, "Not enough image data");
destinyXfate 2:0e2ef1edf01b 2894
destinyXfate 2:0e2ef1edf01b 2895 }
destinyXfate 2:0e2ef1edf01b 2896 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
destinyXfate 2:0e2ef1edf01b 2897 png_ptr->zstream.next_in = png_ptr->zbuf;
destinyXfate 2:0e2ef1edf01b 2898 if (png_ptr->zbuf_size > png_ptr->idat_size)
destinyXfate 2:0e2ef1edf01b 2899 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
destinyXfate 2:0e2ef1edf01b 2900 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
destinyXfate 2:0e2ef1edf01b 2901 png_ptr->idat_size -= png_ptr->zstream.avail_in;
destinyXfate 2:0e2ef1edf01b 2902 }
destinyXfate 2:0e2ef1edf01b 2903 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
destinyXfate 2:0e2ef1edf01b 2904 if (ret == Z_STREAM_END)
destinyXfate 2:0e2ef1edf01b 2905 {
destinyXfate 2:0e2ef1edf01b 2906 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
destinyXfate 2:0e2ef1edf01b 2907 png_ptr->idat_size)
destinyXfate 2:0e2ef1edf01b 2908 png_warning(png_ptr, "Extra compressed data");
destinyXfate 2:0e2ef1edf01b 2909 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 2910 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
destinyXfate 2:0e2ef1edf01b 2911 break;
destinyXfate 2:0e2ef1edf01b 2912 }
destinyXfate 2:0e2ef1edf01b 2913 if (ret != Z_OK)
destinyXfate 2:0e2ef1edf01b 2914 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
destinyXfate 2:0e2ef1edf01b 2915 "Decompression Error");
destinyXfate 2:0e2ef1edf01b 2916
destinyXfate 2:0e2ef1edf01b 2917 if (!(png_ptr->zstream.avail_out))
destinyXfate 2:0e2ef1edf01b 2918 {
destinyXfate 2:0e2ef1edf01b 2919 png_warning(png_ptr, "Extra compressed data.");
destinyXfate 2:0e2ef1edf01b 2920 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 2921 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
destinyXfate 2:0e2ef1edf01b 2922 break;
destinyXfate 2:0e2ef1edf01b 2923 }
destinyXfate 2:0e2ef1edf01b 2924
destinyXfate 2:0e2ef1edf01b 2925 }
destinyXfate 2:0e2ef1edf01b 2926 png_ptr->zstream.avail_out = 0;
destinyXfate 2:0e2ef1edf01b 2927 }
destinyXfate 2:0e2ef1edf01b 2928
destinyXfate 2:0e2ef1edf01b 2929 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
destinyXfate 2:0e2ef1edf01b 2930 png_warning(png_ptr, "Extra compression data");
destinyXfate 2:0e2ef1edf01b 2931
destinyXfate 2:0e2ef1edf01b 2932 inflateReset(&png_ptr->zstream);
destinyXfate 2:0e2ef1edf01b 2933
destinyXfate 2:0e2ef1edf01b 2934 png_ptr->mode |= PNG_AFTER_IDAT;
destinyXfate 2:0e2ef1edf01b 2935 }
destinyXfate 2:0e2ef1edf01b 2936
destinyXfate 2:0e2ef1edf01b 2937 void /* PRIVATE */
destinyXfate 2:0e2ef1edf01b 2938 png_read_start_row(png_structp png_ptr)
destinyXfate 2:0e2ef1edf01b 2939 {
destinyXfate 2:0e2ef1edf01b 2940 #ifdef PNG_USE_LOCAL_ARRAYS
destinyXfate 2:0e2ef1edf01b 2941 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
destinyXfate 2:0e2ef1edf01b 2942
destinyXfate 2:0e2ef1edf01b 2943 /* start of interlace block */
destinyXfate 2:0e2ef1edf01b 2944 const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
destinyXfate 2:0e2ef1edf01b 2945
destinyXfate 2:0e2ef1edf01b 2946 /* offset to next interlace block */
destinyXfate 2:0e2ef1edf01b 2947 const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
destinyXfate 2:0e2ef1edf01b 2948
destinyXfate 2:0e2ef1edf01b 2949 /* start of interlace block in the y direction */
destinyXfate 2:0e2ef1edf01b 2950 const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
destinyXfate 2:0e2ef1edf01b 2951
destinyXfate 2:0e2ef1edf01b 2952 /* offset to next interlace block in the y direction */
destinyXfate 2:0e2ef1edf01b 2953 const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
destinyXfate 2:0e2ef1edf01b 2954 #endif
destinyXfate 2:0e2ef1edf01b 2955
destinyXfate 2:0e2ef1edf01b 2956 int max_pixel_depth;
destinyXfate 2:0e2ef1edf01b 2957 png_uint_32 row_bytes;
destinyXfate 2:0e2ef1edf01b 2958
destinyXfate 2:0e2ef1edf01b 2959 png_debug(1, "in png_read_start_row\n");
destinyXfate 2:0e2ef1edf01b 2960 png_ptr->zstream.avail_in = 0;
destinyXfate 2:0e2ef1edf01b 2961 png_init_read_transformations(png_ptr);
destinyXfate 2:0e2ef1edf01b 2962 if (png_ptr->interlaced)
destinyXfate 2:0e2ef1edf01b 2963 {
destinyXfate 2:0e2ef1edf01b 2964 if (!(png_ptr->transformations & PNG_INTERLACE))
destinyXfate 2:0e2ef1edf01b 2965 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
destinyXfate 2:0e2ef1edf01b 2966 png_pass_ystart[0]) / png_pass_yinc[0];
destinyXfate 2:0e2ef1edf01b 2967 else
destinyXfate 2:0e2ef1edf01b 2968 png_ptr->num_rows = png_ptr->height;
destinyXfate 2:0e2ef1edf01b 2969
destinyXfate 2:0e2ef1edf01b 2970 png_ptr->iwidth = (png_ptr->width +
destinyXfate 2:0e2ef1edf01b 2971 png_pass_inc[png_ptr->pass] - 1 -
destinyXfate 2:0e2ef1edf01b 2972 png_pass_start[png_ptr->pass]) /
destinyXfate 2:0e2ef1edf01b 2973 png_pass_inc[png_ptr->pass];
destinyXfate 2:0e2ef1edf01b 2974
destinyXfate 2:0e2ef1edf01b 2975 row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
destinyXfate 2:0e2ef1edf01b 2976
destinyXfate 2:0e2ef1edf01b 2977 png_ptr->irowbytes = (png_size_t)row_bytes;
destinyXfate 2:0e2ef1edf01b 2978 if((png_uint_32)png_ptr->irowbytes != row_bytes)
destinyXfate 2:0e2ef1edf01b 2979 png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
destinyXfate 2:0e2ef1edf01b 2980 }
destinyXfate 2:0e2ef1edf01b 2981 else
destinyXfate 2:0e2ef1edf01b 2982 {
destinyXfate 2:0e2ef1edf01b 2983 png_ptr->num_rows = png_ptr->height;
destinyXfate 2:0e2ef1edf01b 2984 png_ptr->iwidth = png_ptr->width;
destinyXfate 2:0e2ef1edf01b 2985 png_ptr->irowbytes = png_ptr->rowbytes + 1;
destinyXfate 2:0e2ef1edf01b 2986 }
destinyXfate 2:0e2ef1edf01b 2987 max_pixel_depth = png_ptr->pixel_depth;
destinyXfate 2:0e2ef1edf01b 2988
destinyXfate 2:0e2ef1edf01b 2989 #if defined(PNG_READ_PACK_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2990 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
destinyXfate 2:0e2ef1edf01b 2991 max_pixel_depth = 8;
destinyXfate 2:0e2ef1edf01b 2992 #endif
destinyXfate 2:0e2ef1edf01b 2993
destinyXfate 2:0e2ef1edf01b 2994 #if defined(PNG_READ_EXPAND_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 2995 if (png_ptr->transformations & PNG_EXPAND)
destinyXfate 2:0e2ef1edf01b 2996 {
destinyXfate 2:0e2ef1edf01b 2997 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 2998 {
destinyXfate 2:0e2ef1edf01b 2999 if (png_ptr->num_trans)
destinyXfate 2:0e2ef1edf01b 3000 max_pixel_depth = 32;
destinyXfate 2:0e2ef1edf01b 3001 else
destinyXfate 2:0e2ef1edf01b 3002 max_pixel_depth = 24;
destinyXfate 2:0e2ef1edf01b 3003 }
destinyXfate 2:0e2ef1edf01b 3004 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
destinyXfate 2:0e2ef1edf01b 3005 {
destinyXfate 2:0e2ef1edf01b 3006 if (max_pixel_depth < 8)
destinyXfate 2:0e2ef1edf01b 3007 max_pixel_depth = 8;
destinyXfate 2:0e2ef1edf01b 3008 if (png_ptr->num_trans)
destinyXfate 2:0e2ef1edf01b 3009 max_pixel_depth *= 2;
destinyXfate 2:0e2ef1edf01b 3010 }
destinyXfate 2:0e2ef1edf01b 3011 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
destinyXfate 2:0e2ef1edf01b 3012 {
destinyXfate 2:0e2ef1edf01b 3013 if (png_ptr->num_trans)
destinyXfate 2:0e2ef1edf01b 3014 {
destinyXfate 2:0e2ef1edf01b 3015 max_pixel_depth *= 4;
destinyXfate 2:0e2ef1edf01b 3016 max_pixel_depth /= 3;
destinyXfate 2:0e2ef1edf01b 3017 }
destinyXfate 2:0e2ef1edf01b 3018 }
destinyXfate 2:0e2ef1edf01b 3019 }
destinyXfate 2:0e2ef1edf01b 3020 #endif
destinyXfate 2:0e2ef1edf01b 3021
destinyXfate 2:0e2ef1edf01b 3022 #if defined(PNG_READ_FILLER_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 3023 if (png_ptr->transformations & (PNG_FILLER))
destinyXfate 2:0e2ef1edf01b 3024 {
destinyXfate 2:0e2ef1edf01b 3025 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
destinyXfate 2:0e2ef1edf01b 3026 max_pixel_depth = 32;
destinyXfate 2:0e2ef1edf01b 3027 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
destinyXfate 2:0e2ef1edf01b 3028 {
destinyXfate 2:0e2ef1edf01b 3029 if (max_pixel_depth <= 8)
destinyXfate 2:0e2ef1edf01b 3030 max_pixel_depth = 16;
destinyXfate 2:0e2ef1edf01b 3031 else
destinyXfate 2:0e2ef1edf01b 3032 max_pixel_depth = 32;
destinyXfate 2:0e2ef1edf01b 3033 }
destinyXfate 2:0e2ef1edf01b 3034 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
destinyXfate 2:0e2ef1edf01b 3035 {
destinyXfate 2:0e2ef1edf01b 3036 if (max_pixel_depth <= 32)
destinyXfate 2:0e2ef1edf01b 3037 max_pixel_depth = 32;
destinyXfate 2:0e2ef1edf01b 3038 else
destinyXfate 2:0e2ef1edf01b 3039 max_pixel_depth = 64;
destinyXfate 2:0e2ef1edf01b 3040 }
destinyXfate 2:0e2ef1edf01b 3041 }
destinyXfate 2:0e2ef1edf01b 3042 #endif
destinyXfate 2:0e2ef1edf01b 3043
destinyXfate 2:0e2ef1edf01b 3044 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 3045 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
destinyXfate 2:0e2ef1edf01b 3046 {
destinyXfate 2:0e2ef1edf01b 3047 if (
destinyXfate 2:0e2ef1edf01b 3048 #if defined(PNG_READ_EXPAND_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 3049 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
destinyXfate 2:0e2ef1edf01b 3050 #endif
destinyXfate 2:0e2ef1edf01b 3051 #if defined(PNG_READ_FILLER_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 3052 (png_ptr->transformations & (PNG_FILLER)) ||
destinyXfate 2:0e2ef1edf01b 3053 #endif
destinyXfate 2:0e2ef1edf01b 3054 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
destinyXfate 2:0e2ef1edf01b 3055 {
destinyXfate 2:0e2ef1edf01b 3056 if (max_pixel_depth <= 16)
destinyXfate 2:0e2ef1edf01b 3057 max_pixel_depth = 32;
destinyXfate 2:0e2ef1edf01b 3058 else
destinyXfate 2:0e2ef1edf01b 3059 max_pixel_depth = 64;
destinyXfate 2:0e2ef1edf01b 3060 }
destinyXfate 2:0e2ef1edf01b 3061 else
destinyXfate 2:0e2ef1edf01b 3062 {
destinyXfate 2:0e2ef1edf01b 3063 if (max_pixel_depth <= 8)
destinyXfate 2:0e2ef1edf01b 3064 {
destinyXfate 2:0e2ef1edf01b 3065 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
destinyXfate 2:0e2ef1edf01b 3066 max_pixel_depth = 32;
destinyXfate 2:0e2ef1edf01b 3067 else
destinyXfate 2:0e2ef1edf01b 3068 max_pixel_depth = 24;
destinyXfate 2:0e2ef1edf01b 3069 }
destinyXfate 2:0e2ef1edf01b 3070 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
destinyXfate 2:0e2ef1edf01b 3071 max_pixel_depth = 64;
destinyXfate 2:0e2ef1edf01b 3072 else
destinyXfate 2:0e2ef1edf01b 3073 max_pixel_depth = 48;
destinyXfate 2:0e2ef1edf01b 3074 }
destinyXfate 2:0e2ef1edf01b 3075 }
destinyXfate 2:0e2ef1edf01b 3076 #endif
destinyXfate 2:0e2ef1edf01b 3077
destinyXfate 2:0e2ef1edf01b 3078 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
destinyXfate 2:0e2ef1edf01b 3079 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
destinyXfate 2:0e2ef1edf01b 3080 if(png_ptr->transformations & PNG_USER_TRANSFORM)
destinyXfate 2:0e2ef1edf01b 3081 {
destinyXfate 2:0e2ef1edf01b 3082 int user_pixel_depth=png_ptr->user_transform_depth*
destinyXfate 2:0e2ef1edf01b 3083 png_ptr->user_transform_channels;
destinyXfate 2:0e2ef1edf01b 3084 if(user_pixel_depth > max_pixel_depth)
destinyXfate 2:0e2ef1edf01b 3085 max_pixel_depth=user_pixel_depth;
destinyXfate 2:0e2ef1edf01b 3086 }
destinyXfate 2:0e2ef1edf01b 3087 #endif
destinyXfate 2:0e2ef1edf01b 3088
destinyXfate 2:0e2ef1edf01b 3089 /* align the width on the next larger 8 pixels. Mainly used
destinyXfate 2:0e2ef1edf01b 3090 for interlacing */
destinyXfate 2:0e2ef1edf01b 3091 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
destinyXfate 2:0e2ef1edf01b 3092 /* calculate the maximum bytes needed, adding a byte and a pixel
destinyXfate 2:0e2ef1edf01b 3093 for safety's sake */
destinyXfate 2:0e2ef1edf01b 3094 row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
destinyXfate 2:0e2ef1edf01b 3095 1 + ((max_pixel_depth + 7) >> 3);
destinyXfate 2:0e2ef1edf01b 3096 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 3097 if (row_bytes > (png_uint_32)65536L)
destinyXfate 2:0e2ef1edf01b 3098 png_error(png_ptr, "This image requires a row greater than 64KB");
destinyXfate 2:0e2ef1edf01b 3099 #endif
destinyXfate 2:0e2ef1edf01b 3100 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
destinyXfate 2:0e2ef1edf01b 3101 png_ptr->row_buf = png_ptr->big_row_buf+32;
destinyXfate 2:0e2ef1edf01b 3102 #if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
destinyXfate 2:0e2ef1edf01b 3103 png_ptr->row_buf_size = row_bytes;
destinyXfate 2:0e2ef1edf01b 3104 #endif
destinyXfate 2:0e2ef1edf01b 3105
destinyXfate 2:0e2ef1edf01b 3106 #ifdef PNG_MAX_MALLOC_64K
destinyXfate 2:0e2ef1edf01b 3107 if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
destinyXfate 2:0e2ef1edf01b 3108 png_error(png_ptr, "This image requires a row greater than 64KB");
destinyXfate 2:0e2ef1edf01b 3109 #endif
destinyXfate 2:0e2ef1edf01b 3110 if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
destinyXfate 2:0e2ef1edf01b 3111 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
destinyXfate 2:0e2ef1edf01b 3112 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
destinyXfate 2:0e2ef1edf01b 3113 png_ptr->rowbytes + 1));
destinyXfate 2:0e2ef1edf01b 3114
destinyXfate 2:0e2ef1edf01b 3115 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
destinyXfate 2:0e2ef1edf01b 3116
destinyXfate 2:0e2ef1edf01b 3117 png_debug1(3, "width = %lu,\n", png_ptr->width);
destinyXfate 2:0e2ef1edf01b 3118 png_debug1(3, "height = %lu,\n", png_ptr->height);
destinyXfate 2:0e2ef1edf01b 3119 png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
destinyXfate 2:0e2ef1edf01b 3120 png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
destinyXfate 2:0e2ef1edf01b 3121 png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
destinyXfate 2:0e2ef1edf01b 3122 png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
destinyXfate 2:0e2ef1edf01b 3123
destinyXfate 2:0e2ef1edf01b 3124 png_ptr->flags |= PNG_FLAG_ROW_INIT;
destinyXfate 2:0e2ef1edf01b 3125 }
destinyXfate 2:0e2ef1edf01b 3126 #endif /* PNG_READ_SUPPORTED */
destinyXfate 2:0e2ef1edf01b 3127