vrshoot

annotate libs/libpng/pngpread.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1
nuclear@0 2 /* pngpread.c - read a png file in push mode
nuclear@0 3 *
nuclear@0 4 * Last changed in libpng 1.2.32 [September 18, 2008]
nuclear@0 5 * For conditions of distribution and use, see copyright notice in png.h
nuclear@0 6 * Copyright (c) 1998-2008 Glenn Randers-Pehrson
nuclear@0 7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
nuclear@0 8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
nuclear@0 9 */
nuclear@0 10
nuclear@0 11 #define PNG_INTERNAL
nuclear@0 12 #include "png.h"
nuclear@0 13 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
nuclear@0 14
nuclear@0 15 /* push model modes */
nuclear@0 16 #define PNG_READ_SIG_MODE 0
nuclear@0 17 #define PNG_READ_CHUNK_MODE 1
nuclear@0 18 #define PNG_READ_IDAT_MODE 2
nuclear@0 19 #define PNG_SKIP_MODE 3
nuclear@0 20 #define PNG_READ_tEXt_MODE 4
nuclear@0 21 #define PNG_READ_zTXt_MODE 5
nuclear@0 22 #define PNG_READ_DONE_MODE 6
nuclear@0 23 #define PNG_READ_iTXt_MODE 7
nuclear@0 24 #define PNG_ERROR_MODE 8
nuclear@0 25
nuclear@0 26 void PNGAPI
nuclear@0 27 png_process_data(png_structp png_ptr, png_infop info_ptr,
nuclear@0 28 png_bytep buffer, png_size_t buffer_size)
nuclear@0 29 {
nuclear@0 30 if (png_ptr == NULL || info_ptr == NULL) return;
nuclear@0 31 png_push_restore_buffer(png_ptr, buffer, buffer_size);
nuclear@0 32
nuclear@0 33 while (png_ptr->buffer_size)
nuclear@0 34 {
nuclear@0 35 png_process_some_data(png_ptr, info_ptr);
nuclear@0 36 }
nuclear@0 37 }
nuclear@0 38
nuclear@0 39 /* What we do with the incoming data depends on what we were previously
nuclear@0 40 * doing before we ran out of data...
nuclear@0 41 */
nuclear@0 42 void /* PRIVATE */
nuclear@0 43 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
nuclear@0 44 {
nuclear@0 45 if (png_ptr == NULL) return;
nuclear@0 46 switch (png_ptr->process_mode)
nuclear@0 47 {
nuclear@0 48 case PNG_READ_SIG_MODE:
nuclear@0 49 {
nuclear@0 50 png_push_read_sig(png_ptr, info_ptr);
nuclear@0 51 break;
nuclear@0 52 }
nuclear@0 53 case PNG_READ_CHUNK_MODE:
nuclear@0 54 {
nuclear@0 55 png_push_read_chunk(png_ptr, info_ptr);
nuclear@0 56 break;
nuclear@0 57 }
nuclear@0 58 case PNG_READ_IDAT_MODE:
nuclear@0 59 {
nuclear@0 60 png_push_read_IDAT(png_ptr);
nuclear@0 61 break;
nuclear@0 62 }
nuclear@0 63 #if defined(PNG_READ_tEXt_SUPPORTED)
nuclear@0 64 case PNG_READ_tEXt_MODE:
nuclear@0 65 {
nuclear@0 66 png_push_read_tEXt(png_ptr, info_ptr);
nuclear@0 67 break;
nuclear@0 68 }
nuclear@0 69 #endif
nuclear@0 70 #if defined(PNG_READ_zTXt_SUPPORTED)
nuclear@0 71 case PNG_READ_zTXt_MODE:
nuclear@0 72 {
nuclear@0 73 png_push_read_zTXt(png_ptr, info_ptr);
nuclear@0 74 break;
nuclear@0 75 }
nuclear@0 76 #endif
nuclear@0 77 #if defined(PNG_READ_iTXt_SUPPORTED)
nuclear@0 78 case PNG_READ_iTXt_MODE:
nuclear@0 79 {
nuclear@0 80 png_push_read_iTXt(png_ptr, info_ptr);
nuclear@0 81 break;
nuclear@0 82 }
nuclear@0 83 #endif
nuclear@0 84 case PNG_SKIP_MODE:
nuclear@0 85 {
nuclear@0 86 png_push_crc_finish(png_ptr);
nuclear@0 87 break;
nuclear@0 88 }
nuclear@0 89 default:
nuclear@0 90 {
nuclear@0 91 png_ptr->buffer_size = 0;
nuclear@0 92 break;
nuclear@0 93 }
nuclear@0 94 }
nuclear@0 95 }
nuclear@0 96
nuclear@0 97 /* Read any remaining signature bytes from the stream and compare them with
nuclear@0 98 * the correct PNG signature. It is possible that this routine is called
nuclear@0 99 * with bytes already read from the signature, either because they have been
nuclear@0 100 * checked by the calling application, or because of multiple calls to this
nuclear@0 101 * routine.
nuclear@0 102 */
nuclear@0 103 void /* PRIVATE */
nuclear@0 104 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
nuclear@0 105 {
nuclear@0 106 png_size_t num_checked = png_ptr->sig_bytes,
nuclear@0 107 num_to_check = 8 - num_checked;
nuclear@0 108
nuclear@0 109 if (png_ptr->buffer_size < num_to_check)
nuclear@0 110 {
nuclear@0 111 num_to_check = png_ptr->buffer_size;
nuclear@0 112 }
nuclear@0 113
nuclear@0 114 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
nuclear@0 115 num_to_check);
nuclear@0 116 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
nuclear@0 117
nuclear@0 118 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
nuclear@0 119 {
nuclear@0 120 if (num_checked < 4 &&
nuclear@0 121 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
nuclear@0 122 png_error(png_ptr, "Not a PNG file");
nuclear@0 123 else
nuclear@0 124 png_error(png_ptr, "PNG file corrupted by ASCII conversion");
nuclear@0 125 }
nuclear@0 126 else
nuclear@0 127 {
nuclear@0 128 if (png_ptr->sig_bytes >= 8)
nuclear@0 129 {
nuclear@0 130 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
nuclear@0 131 }
nuclear@0 132 }
nuclear@0 133 }
nuclear@0 134
nuclear@0 135 void /* PRIVATE */
nuclear@0 136 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
nuclear@0 137 {
nuclear@0 138 #ifdef PNG_USE_LOCAL_ARRAYS
nuclear@0 139 PNG_CONST PNG_IHDR;
nuclear@0 140 PNG_CONST PNG_IDAT;
nuclear@0 141 PNG_CONST PNG_IEND;
nuclear@0 142 PNG_CONST PNG_PLTE;
nuclear@0 143 #if defined(PNG_READ_bKGD_SUPPORTED)
nuclear@0 144 PNG_CONST PNG_bKGD;
nuclear@0 145 #endif
nuclear@0 146 #if defined(PNG_READ_cHRM_SUPPORTED)
nuclear@0 147 PNG_CONST PNG_cHRM;
nuclear@0 148 #endif
nuclear@0 149 #if defined(PNG_READ_gAMA_SUPPORTED)
nuclear@0 150 PNG_CONST PNG_gAMA;
nuclear@0 151 #endif
nuclear@0 152 #if defined(PNG_READ_hIST_SUPPORTED)
nuclear@0 153 PNG_CONST PNG_hIST;
nuclear@0 154 #endif
nuclear@0 155 #if defined(PNG_READ_iCCP_SUPPORTED)
nuclear@0 156 PNG_CONST PNG_iCCP;
nuclear@0 157 #endif
nuclear@0 158 #if defined(PNG_READ_iTXt_SUPPORTED)
nuclear@0 159 PNG_CONST PNG_iTXt;
nuclear@0 160 #endif
nuclear@0 161 #if defined(PNG_READ_oFFs_SUPPORTED)
nuclear@0 162 PNG_CONST PNG_oFFs;
nuclear@0 163 #endif
nuclear@0 164 #if defined(PNG_READ_pCAL_SUPPORTED)
nuclear@0 165 PNG_CONST PNG_pCAL;
nuclear@0 166 #endif
nuclear@0 167 #if defined(PNG_READ_pHYs_SUPPORTED)
nuclear@0 168 PNG_CONST PNG_pHYs;
nuclear@0 169 #endif
nuclear@0 170 #if defined(PNG_READ_sBIT_SUPPORTED)
nuclear@0 171 PNG_CONST PNG_sBIT;
nuclear@0 172 #endif
nuclear@0 173 #if defined(PNG_READ_sCAL_SUPPORTED)
nuclear@0 174 PNG_CONST PNG_sCAL;
nuclear@0 175 #endif
nuclear@0 176 #if defined(PNG_READ_sRGB_SUPPORTED)
nuclear@0 177 PNG_CONST PNG_sRGB;
nuclear@0 178 #endif
nuclear@0 179 #if defined(PNG_READ_sPLT_SUPPORTED)
nuclear@0 180 PNG_CONST PNG_sPLT;
nuclear@0 181 #endif
nuclear@0 182 #if defined(PNG_READ_tEXt_SUPPORTED)
nuclear@0 183 PNG_CONST PNG_tEXt;
nuclear@0 184 #endif
nuclear@0 185 #if defined(PNG_READ_tIME_SUPPORTED)
nuclear@0 186 PNG_CONST PNG_tIME;
nuclear@0 187 #endif
nuclear@0 188 #if defined(PNG_READ_tRNS_SUPPORTED)
nuclear@0 189 PNG_CONST PNG_tRNS;
nuclear@0 190 #endif
nuclear@0 191 #if defined(PNG_READ_zTXt_SUPPORTED)
nuclear@0 192 PNG_CONST PNG_zTXt;
nuclear@0 193 #endif
nuclear@0 194 #endif /* PNG_USE_LOCAL_ARRAYS */
nuclear@0 195 /* First we make sure we have enough data for the 4 byte chunk name
nuclear@0 196 * and the 4 byte chunk length before proceeding with decoding the
nuclear@0 197 * chunk data. To fully decode each of these chunks, we also make
nuclear@0 198 * sure we have enough data in the buffer for the 4 byte CRC at the
nuclear@0 199 * end of every chunk (except IDAT, which is handled separately).
nuclear@0 200 */
nuclear@0 201 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
nuclear@0 202 {
nuclear@0 203 png_byte chunk_length[4];
nuclear@0 204
nuclear@0 205 if (png_ptr->buffer_size < 8)
nuclear@0 206 {
nuclear@0 207 png_push_save_buffer(png_ptr);
nuclear@0 208 return;
nuclear@0 209 }
nuclear@0 210
nuclear@0 211 png_push_fill_buffer(png_ptr, chunk_length, 4);
nuclear@0 212 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
nuclear@0 213 png_reset_crc(png_ptr);
nuclear@0 214 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
nuclear@0 215 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
nuclear@0 216 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
nuclear@0 217 }
nuclear@0 218
nuclear@0 219 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
nuclear@0 220 if (png_ptr->mode & PNG_AFTER_IDAT)
nuclear@0 221 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
nuclear@0 222
nuclear@0 223 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
nuclear@0 224 {
nuclear@0 225 if (png_ptr->push_length != 13)
nuclear@0 226 png_error(png_ptr, "Invalid IHDR length");
nuclear@0 227 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 228 {
nuclear@0 229 png_push_save_buffer(png_ptr);
nuclear@0 230 return;
nuclear@0 231 }
nuclear@0 232 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 233 }
nuclear@0 234 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
nuclear@0 235 {
nuclear@0 236 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 237 {
nuclear@0 238 png_push_save_buffer(png_ptr);
nuclear@0 239 return;
nuclear@0 240 }
nuclear@0 241 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 242
nuclear@0 243 png_ptr->process_mode = PNG_READ_DONE_MODE;
nuclear@0 244 png_push_have_end(png_ptr, info_ptr);
nuclear@0 245 }
nuclear@0 246 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
nuclear@0 247 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
nuclear@0 248 {
nuclear@0 249 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 250 {
nuclear@0 251 png_push_save_buffer(png_ptr);
nuclear@0 252 return;
nuclear@0 253 }
nuclear@0 254 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
nuclear@0 255 png_ptr->mode |= PNG_HAVE_IDAT;
nuclear@0 256 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 257 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
nuclear@0 258 png_ptr->mode |= PNG_HAVE_PLTE;
nuclear@0 259 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
nuclear@0 260 {
nuclear@0 261 if (!(png_ptr->mode & PNG_HAVE_IHDR))
nuclear@0 262 png_error(png_ptr, "Missing IHDR before IDAT");
nuclear@0 263 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
nuclear@0 264 !(png_ptr->mode & PNG_HAVE_PLTE))
nuclear@0 265 png_error(png_ptr, "Missing PLTE before IDAT");
nuclear@0 266 }
nuclear@0 267 }
nuclear@0 268 #endif
nuclear@0 269 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
nuclear@0 270 {
nuclear@0 271 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 272 {
nuclear@0 273 png_push_save_buffer(png_ptr);
nuclear@0 274 return;
nuclear@0 275 }
nuclear@0 276 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 277 }
nuclear@0 278 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
nuclear@0 279 {
nuclear@0 280 /* If we reach an IDAT chunk, this means we have read all of the
nuclear@0 281 * header chunks, and we can start reading the image (or if this
nuclear@0 282 * is called after the image has been read - we have an error).
nuclear@0 283 */
nuclear@0 284 if (!(png_ptr->mode & PNG_HAVE_IHDR))
nuclear@0 285 png_error(png_ptr, "Missing IHDR before IDAT");
nuclear@0 286 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
nuclear@0 287 !(png_ptr->mode & PNG_HAVE_PLTE))
nuclear@0 288 png_error(png_ptr, "Missing PLTE before IDAT");
nuclear@0 289
nuclear@0 290 if (png_ptr->mode & PNG_HAVE_IDAT)
nuclear@0 291 {
nuclear@0 292 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
nuclear@0 293 if (png_ptr->push_length == 0)
nuclear@0 294 return;
nuclear@0 295
nuclear@0 296 if (png_ptr->mode & PNG_AFTER_IDAT)
nuclear@0 297 png_error(png_ptr, "Too many IDAT's found");
nuclear@0 298 }
nuclear@0 299
nuclear@0 300 png_ptr->idat_size = png_ptr->push_length;
nuclear@0 301 png_ptr->mode |= PNG_HAVE_IDAT;
nuclear@0 302 png_ptr->process_mode = PNG_READ_IDAT_MODE;
nuclear@0 303 png_push_have_info(png_ptr, info_ptr);
nuclear@0 304 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
nuclear@0 305 png_ptr->zstream.next_out = png_ptr->row_buf;
nuclear@0 306 return;
nuclear@0 307 }
nuclear@0 308 #if defined(PNG_READ_gAMA_SUPPORTED)
nuclear@0 309 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
nuclear@0 310 {
nuclear@0 311 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 312 {
nuclear@0 313 png_push_save_buffer(png_ptr);
nuclear@0 314 return;
nuclear@0 315 }
nuclear@0 316 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 317 }
nuclear@0 318 #endif
nuclear@0 319 #if defined(PNG_READ_sBIT_SUPPORTED)
nuclear@0 320 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
nuclear@0 321 {
nuclear@0 322 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 323 {
nuclear@0 324 png_push_save_buffer(png_ptr);
nuclear@0 325 return;
nuclear@0 326 }
nuclear@0 327 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 328 }
nuclear@0 329 #endif
nuclear@0 330 #if defined(PNG_READ_cHRM_SUPPORTED)
nuclear@0 331 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
nuclear@0 332 {
nuclear@0 333 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 334 {
nuclear@0 335 png_push_save_buffer(png_ptr);
nuclear@0 336 return;
nuclear@0 337 }
nuclear@0 338 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 339 }
nuclear@0 340 #endif
nuclear@0 341 #if defined(PNG_READ_sRGB_SUPPORTED)
nuclear@0 342 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
nuclear@0 343 {
nuclear@0 344 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 345 {
nuclear@0 346 png_push_save_buffer(png_ptr);
nuclear@0 347 return;
nuclear@0 348 }
nuclear@0 349 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 350 }
nuclear@0 351 #endif
nuclear@0 352 #if defined(PNG_READ_iCCP_SUPPORTED)
nuclear@0 353 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
nuclear@0 354 {
nuclear@0 355 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 356 {
nuclear@0 357 png_push_save_buffer(png_ptr);
nuclear@0 358 return;
nuclear@0 359 }
nuclear@0 360 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 361 }
nuclear@0 362 #endif
nuclear@0 363 #if defined(PNG_READ_sPLT_SUPPORTED)
nuclear@0 364 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
nuclear@0 365 {
nuclear@0 366 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 367 {
nuclear@0 368 png_push_save_buffer(png_ptr);
nuclear@0 369 return;
nuclear@0 370 }
nuclear@0 371 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 372 }
nuclear@0 373 #endif
nuclear@0 374 #if defined(PNG_READ_tRNS_SUPPORTED)
nuclear@0 375 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
nuclear@0 376 {
nuclear@0 377 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 378 {
nuclear@0 379 png_push_save_buffer(png_ptr);
nuclear@0 380 return;
nuclear@0 381 }
nuclear@0 382 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 383 }
nuclear@0 384 #endif
nuclear@0 385 #if defined(PNG_READ_bKGD_SUPPORTED)
nuclear@0 386 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
nuclear@0 387 {
nuclear@0 388 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 389 {
nuclear@0 390 png_push_save_buffer(png_ptr);
nuclear@0 391 return;
nuclear@0 392 }
nuclear@0 393 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 394 }
nuclear@0 395 #endif
nuclear@0 396 #if defined(PNG_READ_hIST_SUPPORTED)
nuclear@0 397 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
nuclear@0 398 {
nuclear@0 399 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 400 {
nuclear@0 401 png_push_save_buffer(png_ptr);
nuclear@0 402 return;
nuclear@0 403 }
nuclear@0 404 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 405 }
nuclear@0 406 #endif
nuclear@0 407 #if defined(PNG_READ_pHYs_SUPPORTED)
nuclear@0 408 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
nuclear@0 409 {
nuclear@0 410 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 411 {
nuclear@0 412 png_push_save_buffer(png_ptr);
nuclear@0 413 return;
nuclear@0 414 }
nuclear@0 415 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 416 }
nuclear@0 417 #endif
nuclear@0 418 #if defined(PNG_READ_oFFs_SUPPORTED)
nuclear@0 419 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
nuclear@0 420 {
nuclear@0 421 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 422 {
nuclear@0 423 png_push_save_buffer(png_ptr);
nuclear@0 424 return;
nuclear@0 425 }
nuclear@0 426 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 427 }
nuclear@0 428 #endif
nuclear@0 429 #if defined(PNG_READ_pCAL_SUPPORTED)
nuclear@0 430 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
nuclear@0 431 {
nuclear@0 432 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 433 {
nuclear@0 434 png_push_save_buffer(png_ptr);
nuclear@0 435 return;
nuclear@0 436 }
nuclear@0 437 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 438 }
nuclear@0 439 #endif
nuclear@0 440 #if defined(PNG_READ_sCAL_SUPPORTED)
nuclear@0 441 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
nuclear@0 442 {
nuclear@0 443 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 444 {
nuclear@0 445 png_push_save_buffer(png_ptr);
nuclear@0 446 return;
nuclear@0 447 }
nuclear@0 448 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 449 }
nuclear@0 450 #endif
nuclear@0 451 #if defined(PNG_READ_tIME_SUPPORTED)
nuclear@0 452 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
nuclear@0 453 {
nuclear@0 454 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 455 {
nuclear@0 456 png_push_save_buffer(png_ptr);
nuclear@0 457 return;
nuclear@0 458 }
nuclear@0 459 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 460 }
nuclear@0 461 #endif
nuclear@0 462 #if defined(PNG_READ_tEXt_SUPPORTED)
nuclear@0 463 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
nuclear@0 464 {
nuclear@0 465 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 466 {
nuclear@0 467 png_push_save_buffer(png_ptr);
nuclear@0 468 return;
nuclear@0 469 }
nuclear@0 470 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 471 }
nuclear@0 472 #endif
nuclear@0 473 #if defined(PNG_READ_zTXt_SUPPORTED)
nuclear@0 474 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
nuclear@0 475 {
nuclear@0 476 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 477 {
nuclear@0 478 png_push_save_buffer(png_ptr);
nuclear@0 479 return;
nuclear@0 480 }
nuclear@0 481 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 482 }
nuclear@0 483 #endif
nuclear@0 484 #if defined(PNG_READ_iTXt_SUPPORTED)
nuclear@0 485 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
nuclear@0 486 {
nuclear@0 487 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 488 {
nuclear@0 489 png_push_save_buffer(png_ptr);
nuclear@0 490 return;
nuclear@0 491 }
nuclear@0 492 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 493 }
nuclear@0 494 #endif
nuclear@0 495 else
nuclear@0 496 {
nuclear@0 497 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
nuclear@0 498 {
nuclear@0 499 png_push_save_buffer(png_ptr);
nuclear@0 500 return;
nuclear@0 501 }
nuclear@0 502 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
nuclear@0 503 }
nuclear@0 504
nuclear@0 505 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
nuclear@0 506 }
nuclear@0 507
nuclear@0 508 void /* PRIVATE */
nuclear@0 509 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
nuclear@0 510 {
nuclear@0 511 png_ptr->process_mode = PNG_SKIP_MODE;
nuclear@0 512 png_ptr->skip_length = skip;
nuclear@0 513 }
nuclear@0 514
nuclear@0 515 void /* PRIVATE */
nuclear@0 516 png_push_crc_finish(png_structp png_ptr)
nuclear@0 517 {
nuclear@0 518 if (png_ptr->skip_length && png_ptr->save_buffer_size)
nuclear@0 519 {
nuclear@0 520 png_size_t save_size;
nuclear@0 521
nuclear@0 522 if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
nuclear@0 523 save_size = (png_size_t)png_ptr->skip_length;
nuclear@0 524 else
nuclear@0 525 save_size = png_ptr->save_buffer_size;
nuclear@0 526
nuclear@0 527 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
nuclear@0 528
nuclear@0 529 png_ptr->skip_length -= save_size;
nuclear@0 530 png_ptr->buffer_size -= save_size;
nuclear@0 531 png_ptr->save_buffer_size -= save_size;
nuclear@0 532 png_ptr->save_buffer_ptr += save_size;
nuclear@0 533 }
nuclear@0 534 if (png_ptr->skip_length && png_ptr->current_buffer_size)
nuclear@0 535 {
nuclear@0 536 png_size_t save_size;
nuclear@0 537
nuclear@0 538 if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
nuclear@0 539 save_size = (png_size_t)png_ptr->skip_length;
nuclear@0 540 else
nuclear@0 541 save_size = png_ptr->current_buffer_size;
nuclear@0 542
nuclear@0 543 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
nuclear@0 544
nuclear@0 545 png_ptr->skip_length -= save_size;
nuclear@0 546 png_ptr->buffer_size -= save_size;
nuclear@0 547 png_ptr->current_buffer_size -= save_size;
nuclear@0 548 png_ptr->current_buffer_ptr += save_size;
nuclear@0 549 }
nuclear@0 550 if (!png_ptr->skip_length)
nuclear@0 551 {
nuclear@0 552 if (png_ptr->buffer_size < 4)
nuclear@0 553 {
nuclear@0 554 png_push_save_buffer(png_ptr);
nuclear@0 555 return;
nuclear@0 556 }
nuclear@0 557
nuclear@0 558 png_crc_finish(png_ptr, 0);
nuclear@0 559 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
nuclear@0 560 }
nuclear@0 561 }
nuclear@0 562
nuclear@0 563 void PNGAPI
nuclear@0 564 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
nuclear@0 565 {
nuclear@0 566 png_bytep ptr;
nuclear@0 567
nuclear@0 568 if (png_ptr == NULL) return;
nuclear@0 569 ptr = buffer;
nuclear@0 570 if (png_ptr->save_buffer_size)
nuclear@0 571 {
nuclear@0 572 png_size_t save_size;
nuclear@0 573
nuclear@0 574 if (length < png_ptr->save_buffer_size)
nuclear@0 575 save_size = length;
nuclear@0 576 else
nuclear@0 577 save_size = png_ptr->save_buffer_size;
nuclear@0 578
nuclear@0 579 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
nuclear@0 580 length -= save_size;
nuclear@0 581 ptr += save_size;
nuclear@0 582 png_ptr->buffer_size -= save_size;
nuclear@0 583 png_ptr->save_buffer_size -= save_size;
nuclear@0 584 png_ptr->save_buffer_ptr += save_size;
nuclear@0 585 }
nuclear@0 586 if (length && png_ptr->current_buffer_size)
nuclear@0 587 {
nuclear@0 588 png_size_t save_size;
nuclear@0 589
nuclear@0 590 if (length < png_ptr->current_buffer_size)
nuclear@0 591 save_size = length;
nuclear@0 592 else
nuclear@0 593 save_size = png_ptr->current_buffer_size;
nuclear@0 594
nuclear@0 595 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
nuclear@0 596 png_ptr->buffer_size -= save_size;
nuclear@0 597 png_ptr->current_buffer_size -= save_size;
nuclear@0 598 png_ptr->current_buffer_ptr += save_size;
nuclear@0 599 }
nuclear@0 600 }
nuclear@0 601
nuclear@0 602 void /* PRIVATE */
nuclear@0 603 png_push_save_buffer(png_structp png_ptr)
nuclear@0 604 {
nuclear@0 605 if (png_ptr->save_buffer_size)
nuclear@0 606 {
nuclear@0 607 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
nuclear@0 608 {
nuclear@0 609 png_size_t i, istop;
nuclear@0 610 png_bytep sp;
nuclear@0 611 png_bytep dp;
nuclear@0 612
nuclear@0 613 istop = png_ptr->save_buffer_size;
nuclear@0 614 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
nuclear@0 615 i < istop; i++, sp++, dp++)
nuclear@0 616 {
nuclear@0 617 *dp = *sp;
nuclear@0 618 }
nuclear@0 619 }
nuclear@0 620 }
nuclear@0 621 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
nuclear@0 622 png_ptr->save_buffer_max)
nuclear@0 623 {
nuclear@0 624 png_size_t new_max;
nuclear@0 625 png_bytep old_buffer;
nuclear@0 626
nuclear@0 627 if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
nuclear@0 628 (png_ptr->current_buffer_size + 256))
nuclear@0 629 {
nuclear@0 630 png_error(png_ptr, "Potential overflow of save_buffer");
nuclear@0 631 }
nuclear@0 632 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
nuclear@0 633 old_buffer = png_ptr->save_buffer;
nuclear@0 634 png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
nuclear@0 635 (png_uint_32)new_max);
nuclear@0 636 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
nuclear@0 637 png_free(png_ptr, old_buffer);
nuclear@0 638 png_ptr->save_buffer_max = new_max;
nuclear@0 639 }
nuclear@0 640 if (png_ptr->current_buffer_size)
nuclear@0 641 {
nuclear@0 642 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
nuclear@0 643 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
nuclear@0 644 png_ptr->save_buffer_size += png_ptr->current_buffer_size;
nuclear@0 645 png_ptr->current_buffer_size = 0;
nuclear@0 646 }
nuclear@0 647 png_ptr->save_buffer_ptr = png_ptr->save_buffer;
nuclear@0 648 png_ptr->buffer_size = 0;
nuclear@0 649 }
nuclear@0 650
nuclear@0 651 void /* PRIVATE */
nuclear@0 652 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
nuclear@0 653 png_size_t buffer_length)
nuclear@0 654 {
nuclear@0 655 png_ptr->current_buffer = buffer;
nuclear@0 656 png_ptr->current_buffer_size = buffer_length;
nuclear@0 657 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
nuclear@0 658 png_ptr->current_buffer_ptr = png_ptr->current_buffer;
nuclear@0 659 }
nuclear@0 660
nuclear@0 661 void /* PRIVATE */
nuclear@0 662 png_push_read_IDAT(png_structp png_ptr)
nuclear@0 663 {
nuclear@0 664 #ifdef PNG_USE_LOCAL_ARRAYS
nuclear@0 665 PNG_CONST PNG_IDAT;
nuclear@0 666 #endif
nuclear@0 667 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
nuclear@0 668 {
nuclear@0 669 png_byte chunk_length[4];
nuclear@0 670
nuclear@0 671 if (png_ptr->buffer_size < 8)
nuclear@0 672 {
nuclear@0 673 png_push_save_buffer(png_ptr);
nuclear@0 674 return;
nuclear@0 675 }
nuclear@0 676
nuclear@0 677 png_push_fill_buffer(png_ptr, chunk_length, 4);
nuclear@0 678 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
nuclear@0 679 png_reset_crc(png_ptr);
nuclear@0 680 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
nuclear@0 681 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
nuclear@0 682
nuclear@0 683 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
nuclear@0 684 {
nuclear@0 685 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
nuclear@0 686 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
nuclear@0 687 png_error(png_ptr, "Not enough compressed data");
nuclear@0 688 return;
nuclear@0 689 }
nuclear@0 690
nuclear@0 691 png_ptr->idat_size = png_ptr->push_length;
nuclear@0 692 }
nuclear@0 693 if (png_ptr->idat_size && png_ptr->save_buffer_size)
nuclear@0 694 {
nuclear@0 695 png_size_t save_size;
nuclear@0 696
nuclear@0 697 if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
nuclear@0 698 {
nuclear@0 699 save_size = (png_size_t)png_ptr->idat_size;
nuclear@0 700 /* check for overflow */
nuclear@0 701 if ((png_uint_32)save_size != png_ptr->idat_size)
nuclear@0 702 png_error(png_ptr, "save_size overflowed in pngpread");
nuclear@0 703 }
nuclear@0 704 else
nuclear@0 705 save_size = png_ptr->save_buffer_size;
nuclear@0 706
nuclear@0 707 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
nuclear@0 708 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
nuclear@0 709 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
nuclear@0 710 png_ptr->idat_size -= save_size;
nuclear@0 711 png_ptr->buffer_size -= save_size;
nuclear@0 712 png_ptr->save_buffer_size -= save_size;
nuclear@0 713 png_ptr->save_buffer_ptr += save_size;
nuclear@0 714 }
nuclear@0 715 if (png_ptr->idat_size && png_ptr->current_buffer_size)
nuclear@0 716 {
nuclear@0 717 png_size_t save_size;
nuclear@0 718
nuclear@0 719 if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
nuclear@0 720 {
nuclear@0 721 save_size = (png_size_t)png_ptr->idat_size;
nuclear@0 722 /* check for overflow */
nuclear@0 723 if ((png_uint_32)save_size != png_ptr->idat_size)
nuclear@0 724 png_error(png_ptr, "save_size overflowed in pngpread");
nuclear@0 725 }
nuclear@0 726 else
nuclear@0 727 save_size = png_ptr->current_buffer_size;
nuclear@0 728
nuclear@0 729 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
nuclear@0 730 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
nuclear@0 731 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
nuclear@0 732
nuclear@0 733 png_ptr->idat_size -= save_size;
nuclear@0 734 png_ptr->buffer_size -= save_size;
nuclear@0 735 png_ptr->current_buffer_size -= save_size;
nuclear@0 736 png_ptr->current_buffer_ptr += save_size;
nuclear@0 737 }
nuclear@0 738 if (!png_ptr->idat_size)
nuclear@0 739 {
nuclear@0 740 if (png_ptr->buffer_size < 4)
nuclear@0 741 {
nuclear@0 742 png_push_save_buffer(png_ptr);
nuclear@0 743 return;
nuclear@0 744 }
nuclear@0 745
nuclear@0 746 png_crc_finish(png_ptr, 0);
nuclear@0 747 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
nuclear@0 748 png_ptr->mode |= PNG_AFTER_IDAT;
nuclear@0 749 }
nuclear@0 750 }
nuclear@0 751
nuclear@0 752 void /* PRIVATE */
nuclear@0 753 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
nuclear@0 754 png_size_t buffer_length)
nuclear@0 755 {
nuclear@0 756 int ret;
nuclear@0 757
nuclear@0 758 if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
nuclear@0 759 png_error(png_ptr, "Extra compression data");
nuclear@0 760
nuclear@0 761 png_ptr->zstream.next_in = buffer;
nuclear@0 762 png_ptr->zstream.avail_in = (uInt)buffer_length;
nuclear@0 763 for (;;)
nuclear@0 764 {
nuclear@0 765 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
nuclear@0 766 if (ret != Z_OK)
nuclear@0 767 {
nuclear@0 768 if (ret == Z_STREAM_END)
nuclear@0 769 {
nuclear@0 770 if (png_ptr->zstream.avail_in)
nuclear@0 771 png_error(png_ptr, "Extra compressed data");
nuclear@0 772 if (!(png_ptr->zstream.avail_out))
nuclear@0 773 {
nuclear@0 774 png_push_process_row(png_ptr);
nuclear@0 775 }
nuclear@0 776
nuclear@0 777 png_ptr->mode |= PNG_AFTER_IDAT;
nuclear@0 778 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
nuclear@0 779 break;
nuclear@0 780 }
nuclear@0 781 else if (ret == Z_BUF_ERROR)
nuclear@0 782 break;
nuclear@0 783 else
nuclear@0 784 png_error(png_ptr, "Decompression Error");
nuclear@0 785 }
nuclear@0 786 if (!(png_ptr->zstream.avail_out))
nuclear@0 787 {
nuclear@0 788 if ((
nuclear@0 789 #if defined(PNG_READ_INTERLACING_SUPPORTED)
nuclear@0 790 png_ptr->interlaced && png_ptr->pass > 6) ||
nuclear@0 791 (!png_ptr->interlaced &&
nuclear@0 792 #endif
nuclear@0 793 png_ptr->row_number == png_ptr->num_rows))
nuclear@0 794 {
nuclear@0 795 if (png_ptr->zstream.avail_in)
nuclear@0 796 png_warning(png_ptr, "Too much data in IDAT chunks");
nuclear@0 797 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
nuclear@0 798 break;
nuclear@0 799 }
nuclear@0 800 png_push_process_row(png_ptr);
nuclear@0 801 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
nuclear@0 802 png_ptr->zstream.next_out = png_ptr->row_buf;
nuclear@0 803 }
nuclear@0 804 else
nuclear@0 805 break;
nuclear@0 806 }
nuclear@0 807 }
nuclear@0 808
nuclear@0 809 void /* PRIVATE */
nuclear@0 810 png_push_process_row(png_structp png_ptr)
nuclear@0 811 {
nuclear@0 812 png_ptr->row_info.color_type = png_ptr->color_type;
nuclear@0 813 png_ptr->row_info.width = png_ptr->iwidth;
nuclear@0 814 png_ptr->row_info.channels = png_ptr->channels;
nuclear@0 815 png_ptr->row_info.bit_depth = png_ptr->bit_depth;
nuclear@0 816 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
nuclear@0 817
nuclear@0 818 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
nuclear@0 819 png_ptr->row_info.width);
nuclear@0 820
nuclear@0 821 png_read_filter_row(png_ptr, &(png_ptr->row_info),
nuclear@0 822 png_ptr->row_buf + 1, png_ptr->prev_row + 1,
nuclear@0 823 (int)(png_ptr->row_buf[0]));
nuclear@0 824
nuclear@0 825 png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
nuclear@0 826 png_ptr->rowbytes + 1);
nuclear@0 827
nuclear@0 828 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
nuclear@0 829 png_do_read_transformations(png_ptr);
nuclear@0 830
nuclear@0 831 #if defined(PNG_READ_INTERLACING_SUPPORTED)
nuclear@0 832 /* blow up interlaced rows to full size */
nuclear@0 833 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
nuclear@0 834 {
nuclear@0 835 if (png_ptr->pass < 6)
nuclear@0 836 /* old interface (pre-1.0.9):
nuclear@0 837 png_do_read_interlace(&(png_ptr->row_info),
nuclear@0 838 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
nuclear@0 839 */
nuclear@0 840 png_do_read_interlace(png_ptr);
nuclear@0 841
nuclear@0 842 switch (png_ptr->pass)
nuclear@0 843 {
nuclear@0 844 case 0:
nuclear@0 845 {
nuclear@0 846 int i;
nuclear@0 847 for (i = 0; i < 8 && png_ptr->pass == 0; i++)
nuclear@0 848 {
nuclear@0 849 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 850 png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
nuclear@0 851 }
nuclear@0 852 if (png_ptr->pass == 2) /* pass 1 might be empty */
nuclear@0 853 {
nuclear@0 854 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
nuclear@0 855 {
nuclear@0 856 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 857 png_read_push_finish_row(png_ptr);
nuclear@0 858 }
nuclear@0 859 }
nuclear@0 860 if (png_ptr->pass == 4 && png_ptr->height <= 4)
nuclear@0 861 {
nuclear@0 862 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
nuclear@0 863 {
nuclear@0 864 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 865 png_read_push_finish_row(png_ptr);
nuclear@0 866 }
nuclear@0 867 }
nuclear@0 868 if (png_ptr->pass == 6 && png_ptr->height <= 4)
nuclear@0 869 {
nuclear@0 870 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 871 png_read_push_finish_row(png_ptr);
nuclear@0 872 }
nuclear@0 873 break;
nuclear@0 874 }
nuclear@0 875 case 1:
nuclear@0 876 {
nuclear@0 877 int i;
nuclear@0 878 for (i = 0; i < 8 && png_ptr->pass == 1; i++)
nuclear@0 879 {
nuclear@0 880 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 881 png_read_push_finish_row(png_ptr);
nuclear@0 882 }
nuclear@0 883 if (png_ptr->pass == 2) /* skip top 4 generated rows */
nuclear@0 884 {
nuclear@0 885 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
nuclear@0 886 {
nuclear@0 887 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 888 png_read_push_finish_row(png_ptr);
nuclear@0 889 }
nuclear@0 890 }
nuclear@0 891 break;
nuclear@0 892 }
nuclear@0 893 case 2:
nuclear@0 894 {
nuclear@0 895 int i;
nuclear@0 896 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
nuclear@0 897 {
nuclear@0 898 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 899 png_read_push_finish_row(png_ptr);
nuclear@0 900 }
nuclear@0 901 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
nuclear@0 902 {
nuclear@0 903 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 904 png_read_push_finish_row(png_ptr);
nuclear@0 905 }
nuclear@0 906 if (png_ptr->pass == 4) /* pass 3 might be empty */
nuclear@0 907 {
nuclear@0 908 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
nuclear@0 909 {
nuclear@0 910 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 911 png_read_push_finish_row(png_ptr);
nuclear@0 912 }
nuclear@0 913 }
nuclear@0 914 break;
nuclear@0 915 }
nuclear@0 916 case 3:
nuclear@0 917 {
nuclear@0 918 int i;
nuclear@0 919 for (i = 0; i < 4 && png_ptr->pass == 3; i++)
nuclear@0 920 {
nuclear@0 921 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 922 png_read_push_finish_row(png_ptr);
nuclear@0 923 }
nuclear@0 924 if (png_ptr->pass == 4) /* skip top two generated rows */
nuclear@0 925 {
nuclear@0 926 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
nuclear@0 927 {
nuclear@0 928 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 929 png_read_push_finish_row(png_ptr);
nuclear@0 930 }
nuclear@0 931 }
nuclear@0 932 break;
nuclear@0 933 }
nuclear@0 934 case 4:
nuclear@0 935 {
nuclear@0 936 int i;
nuclear@0 937 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
nuclear@0 938 {
nuclear@0 939 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 940 png_read_push_finish_row(png_ptr);
nuclear@0 941 }
nuclear@0 942 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
nuclear@0 943 {
nuclear@0 944 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 945 png_read_push_finish_row(png_ptr);
nuclear@0 946 }
nuclear@0 947 if (png_ptr->pass == 6) /* pass 5 might be empty */
nuclear@0 948 {
nuclear@0 949 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 950 png_read_push_finish_row(png_ptr);
nuclear@0 951 }
nuclear@0 952 break;
nuclear@0 953 }
nuclear@0 954 case 5:
nuclear@0 955 {
nuclear@0 956 int i;
nuclear@0 957 for (i = 0; i < 2 && png_ptr->pass == 5; i++)
nuclear@0 958 {
nuclear@0 959 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 960 png_read_push_finish_row(png_ptr);
nuclear@0 961 }
nuclear@0 962 if (png_ptr->pass == 6) /* skip top generated row */
nuclear@0 963 {
nuclear@0 964 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 965 png_read_push_finish_row(png_ptr);
nuclear@0 966 }
nuclear@0 967 break;
nuclear@0 968 }
nuclear@0 969 case 6:
nuclear@0 970 {
nuclear@0 971 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 972 png_read_push_finish_row(png_ptr);
nuclear@0 973 if (png_ptr->pass != 6)
nuclear@0 974 break;
nuclear@0 975 png_push_have_row(png_ptr, png_bytep_NULL);
nuclear@0 976 png_read_push_finish_row(png_ptr);
nuclear@0 977 }
nuclear@0 978 }
nuclear@0 979 }
nuclear@0 980 else
nuclear@0 981 #endif
nuclear@0 982 {
nuclear@0 983 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
nuclear@0 984 png_read_push_finish_row(png_ptr);
nuclear@0 985 }
nuclear@0 986 }
nuclear@0 987
nuclear@0 988 void /* PRIVATE */
nuclear@0 989 png_read_push_finish_row(png_structp png_ptr)
nuclear@0 990 {
nuclear@0 991 #ifdef PNG_USE_LOCAL_ARRAYS
nuclear@0 992 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
nuclear@0 993
nuclear@0 994 /* start of interlace block */
nuclear@0 995 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
nuclear@0 996
nuclear@0 997 /* offset to next interlace block */
nuclear@0 998 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
nuclear@0 999
nuclear@0 1000 /* start of interlace block in the y direction */
nuclear@0 1001 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
nuclear@0 1002
nuclear@0 1003 /* offset to next interlace block in the y direction */
nuclear@0 1004 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
nuclear@0 1005
nuclear@0 1006 /* Height of interlace block. This is not currently used - if you need
nuclear@0 1007 * it, uncomment it here and in png.h
nuclear@0 1008 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
nuclear@0 1009 */
nuclear@0 1010 #endif
nuclear@0 1011
nuclear@0 1012 png_ptr->row_number++;
nuclear@0 1013 if (png_ptr->row_number < png_ptr->num_rows)
nuclear@0 1014 return;
nuclear@0 1015
nuclear@0 1016 if (png_ptr->interlaced)
nuclear@0 1017 {
nuclear@0 1018 png_ptr->row_number = 0;
nuclear@0 1019 png_memset_check(png_ptr, png_ptr->prev_row, 0,
nuclear@0 1020 png_ptr->rowbytes + 1);
nuclear@0 1021 do
nuclear@0 1022 {
nuclear@0 1023 png_ptr->pass++;
nuclear@0 1024 if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
nuclear@0 1025 (png_ptr->pass == 3 && png_ptr->width < 3) ||
nuclear@0 1026 (png_ptr->pass == 5 && png_ptr->width < 2))
nuclear@0 1027 png_ptr->pass++;
nuclear@0 1028
nuclear@0 1029 if (png_ptr->pass > 7)
nuclear@0 1030 png_ptr->pass--;
nuclear@0 1031 if (png_ptr->pass >= 7)
nuclear@0 1032 break;
nuclear@0 1033
nuclear@0 1034 png_ptr->iwidth = (png_ptr->width +
nuclear@0 1035 png_pass_inc[png_ptr->pass] - 1 -
nuclear@0 1036 png_pass_start[png_ptr->pass]) /
nuclear@0 1037 png_pass_inc[png_ptr->pass];
nuclear@0 1038
nuclear@0 1039 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
nuclear@0 1040 png_ptr->iwidth) + 1;
nuclear@0 1041
nuclear@0 1042 if (png_ptr->transformations & PNG_INTERLACE)
nuclear@0 1043 break;
nuclear@0 1044
nuclear@0 1045 png_ptr->num_rows = (png_ptr->height +
nuclear@0 1046 png_pass_yinc[png_ptr->pass] - 1 -
nuclear@0 1047 png_pass_ystart[png_ptr->pass]) /
nuclear@0 1048 png_pass_yinc[png_ptr->pass];
nuclear@0 1049
nuclear@0 1050 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
nuclear@0 1051 }
nuclear@0 1052 }
nuclear@0 1053
nuclear@0 1054 #if defined(PNG_READ_tEXt_SUPPORTED)
nuclear@0 1055 void /* PRIVATE */
nuclear@0 1056 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
nuclear@0 1057 length)
nuclear@0 1058 {
nuclear@0 1059 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
nuclear@0 1060 {
nuclear@0 1061 png_error(png_ptr, "Out of place tEXt");
nuclear@0 1062 info_ptr = info_ptr; /* to quiet some compiler warnings */
nuclear@0 1063 }
nuclear@0 1064
nuclear@0 1065 #ifdef PNG_MAX_MALLOC_64K
nuclear@0 1066 png_ptr->skip_length = 0; /* This may not be necessary */
nuclear@0 1067
nuclear@0 1068 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
nuclear@0 1069 {
nuclear@0 1070 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
nuclear@0 1071 png_ptr->skip_length = length - (png_uint_32)65535L;
nuclear@0 1072 length = (png_uint_32)65535L;
nuclear@0 1073 }
nuclear@0 1074 #endif
nuclear@0 1075
nuclear@0 1076 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
nuclear@0 1077 (png_uint_32)(length + 1));
nuclear@0 1078 png_ptr->current_text[length] = '\0';
nuclear@0 1079 png_ptr->current_text_ptr = png_ptr->current_text;
nuclear@0 1080 png_ptr->current_text_size = (png_size_t)length;
nuclear@0 1081 png_ptr->current_text_left = (png_size_t)length;
nuclear@0 1082 png_ptr->process_mode = PNG_READ_tEXt_MODE;
nuclear@0 1083 }
nuclear@0 1084
nuclear@0 1085 void /* PRIVATE */
nuclear@0 1086 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
nuclear@0 1087 {
nuclear@0 1088 if (png_ptr->buffer_size && png_ptr->current_text_left)
nuclear@0 1089 {
nuclear@0 1090 png_size_t text_size;
nuclear@0 1091
nuclear@0 1092 if (png_ptr->buffer_size < png_ptr->current_text_left)
nuclear@0 1093 text_size = png_ptr->buffer_size;
nuclear@0 1094 else
nuclear@0 1095 text_size = png_ptr->current_text_left;
nuclear@0 1096 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
nuclear@0 1097 png_ptr->current_text_left -= text_size;
nuclear@0 1098 png_ptr->current_text_ptr += text_size;
nuclear@0 1099 }
nuclear@0 1100 if (!(png_ptr->current_text_left))
nuclear@0 1101 {
nuclear@0 1102 png_textp text_ptr;
nuclear@0 1103 png_charp text;
nuclear@0 1104 png_charp key;
nuclear@0 1105 int ret;
nuclear@0 1106
nuclear@0 1107 if (png_ptr->buffer_size < 4)
nuclear@0 1108 {
nuclear@0 1109 png_push_save_buffer(png_ptr);
nuclear@0 1110 return;
nuclear@0 1111 }
nuclear@0 1112
nuclear@0 1113 png_push_crc_finish(png_ptr);
nuclear@0 1114
nuclear@0 1115 #if defined(PNG_MAX_MALLOC_64K)
nuclear@0 1116 if (png_ptr->skip_length)
nuclear@0 1117 return;
nuclear@0 1118 #endif
nuclear@0 1119
nuclear@0 1120 key = png_ptr->current_text;
nuclear@0 1121
nuclear@0 1122 for (text = key; *text; text++)
nuclear@0 1123 /* empty loop */ ;
nuclear@0 1124
nuclear@0 1125 if (text < key + png_ptr->current_text_size)
nuclear@0 1126 text++;
nuclear@0 1127
nuclear@0 1128 text_ptr = (png_textp)png_malloc(png_ptr,
nuclear@0 1129 (png_uint_32)png_sizeof(png_text));
nuclear@0 1130 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
nuclear@0 1131 text_ptr->key = key;
nuclear@0 1132 #ifdef PNG_iTXt_SUPPORTED
nuclear@0 1133 text_ptr->lang = NULL;
nuclear@0 1134 text_ptr->lang_key = NULL;
nuclear@0 1135 #endif
nuclear@0 1136 text_ptr->text = text;
nuclear@0 1137
nuclear@0 1138 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
nuclear@0 1139
nuclear@0 1140 png_free(png_ptr, key);
nuclear@0 1141 png_free(png_ptr, text_ptr);
nuclear@0 1142 png_ptr->current_text = NULL;
nuclear@0 1143
nuclear@0 1144 if (ret)
nuclear@0 1145 png_warning(png_ptr, "Insufficient memory to store text chunk.");
nuclear@0 1146 }
nuclear@0 1147 }
nuclear@0 1148 #endif
nuclear@0 1149
nuclear@0 1150 #if defined(PNG_READ_zTXt_SUPPORTED)
nuclear@0 1151 void /* PRIVATE */
nuclear@0 1152 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
nuclear@0 1153 length)
nuclear@0 1154 {
nuclear@0 1155 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
nuclear@0 1156 {
nuclear@0 1157 png_error(png_ptr, "Out of place zTXt");
nuclear@0 1158 info_ptr = info_ptr; /* to quiet some compiler warnings */
nuclear@0 1159 }
nuclear@0 1160
nuclear@0 1161 #ifdef PNG_MAX_MALLOC_64K
nuclear@0 1162 /* We can't handle zTXt chunks > 64K, since we don't have enough space
nuclear@0 1163 * to be able to store the uncompressed data. Actually, the threshold
nuclear@0 1164 * is probably around 32K, but it isn't as definite as 64K is.
nuclear@0 1165 */
nuclear@0 1166 if (length > (png_uint_32)65535L)
nuclear@0 1167 {
nuclear@0 1168 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
nuclear@0 1169 png_push_crc_skip(png_ptr, length);
nuclear@0 1170 return;
nuclear@0 1171 }
nuclear@0 1172 #endif
nuclear@0 1173
nuclear@0 1174 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
nuclear@0 1175 (png_uint_32)(length + 1));
nuclear@0 1176 png_ptr->current_text[length] = '\0';
nuclear@0 1177 png_ptr->current_text_ptr = png_ptr->current_text;
nuclear@0 1178 png_ptr->current_text_size = (png_size_t)length;
nuclear@0 1179 png_ptr->current_text_left = (png_size_t)length;
nuclear@0 1180 png_ptr->process_mode = PNG_READ_zTXt_MODE;
nuclear@0 1181 }
nuclear@0 1182
nuclear@0 1183 void /* PRIVATE */
nuclear@0 1184 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
nuclear@0 1185 {
nuclear@0 1186 if (png_ptr->buffer_size && png_ptr->current_text_left)
nuclear@0 1187 {
nuclear@0 1188 png_size_t text_size;
nuclear@0 1189
nuclear@0 1190 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
nuclear@0 1191 text_size = png_ptr->buffer_size;
nuclear@0 1192 else
nuclear@0 1193 text_size = png_ptr->current_text_left;
nuclear@0 1194 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
nuclear@0 1195 png_ptr->current_text_left -= text_size;
nuclear@0 1196 png_ptr->current_text_ptr += text_size;
nuclear@0 1197 }
nuclear@0 1198 if (!(png_ptr->current_text_left))
nuclear@0 1199 {
nuclear@0 1200 png_textp text_ptr;
nuclear@0 1201 png_charp text;
nuclear@0 1202 png_charp key;
nuclear@0 1203 int ret;
nuclear@0 1204 png_size_t text_size, key_size;
nuclear@0 1205
nuclear@0 1206 if (png_ptr->buffer_size < 4)
nuclear@0 1207 {
nuclear@0 1208 png_push_save_buffer(png_ptr);
nuclear@0 1209 return;
nuclear@0 1210 }
nuclear@0 1211
nuclear@0 1212 png_push_crc_finish(png_ptr);
nuclear@0 1213
nuclear@0 1214 key = png_ptr->current_text;
nuclear@0 1215
nuclear@0 1216 for (text = key; *text; text++)
nuclear@0 1217 /* empty loop */ ;
nuclear@0 1218
nuclear@0 1219 /* zTXt can't have zero text */
nuclear@0 1220 if (text >= key + png_ptr->current_text_size)
nuclear@0 1221 {
nuclear@0 1222 png_ptr->current_text = NULL;
nuclear@0 1223 png_free(png_ptr, key);
nuclear@0 1224 return;
nuclear@0 1225 }
nuclear@0 1226
nuclear@0 1227 text++;
nuclear@0 1228
nuclear@0 1229 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
nuclear@0 1230 {
nuclear@0 1231 png_ptr->current_text = NULL;
nuclear@0 1232 png_free(png_ptr, key);
nuclear@0 1233 return;
nuclear@0 1234 }
nuclear@0 1235
nuclear@0 1236 text++;
nuclear@0 1237
nuclear@0 1238 png_ptr->zstream.next_in = (png_bytep )text;
nuclear@0 1239 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
nuclear@0 1240 (text - key));
nuclear@0 1241 png_ptr->zstream.next_out = png_ptr->zbuf;
nuclear@0 1242 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
nuclear@0 1243
nuclear@0 1244 key_size = text - key;
nuclear@0 1245 text_size = 0;
nuclear@0 1246 text = NULL;
nuclear@0 1247 ret = Z_STREAM_END;
nuclear@0 1248
nuclear@0 1249 while (png_ptr->zstream.avail_in)
nuclear@0 1250 {
nuclear@0 1251 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
nuclear@0 1252 if (ret != Z_OK && ret != Z_STREAM_END)
nuclear@0 1253 {
nuclear@0 1254 inflateReset(&png_ptr->zstream);
nuclear@0 1255 png_ptr->zstream.avail_in = 0;
nuclear@0 1256 png_ptr->current_text = NULL;
nuclear@0 1257 png_free(png_ptr, key);
nuclear@0 1258 png_free(png_ptr, text);
nuclear@0 1259 return;
nuclear@0 1260 }
nuclear@0 1261 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
nuclear@0 1262 {
nuclear@0 1263 if (text == NULL)
nuclear@0 1264 {
nuclear@0 1265 text = (png_charp)png_malloc(png_ptr,
nuclear@0 1266 (png_uint_32)(png_ptr->zbuf_size
nuclear@0 1267 - png_ptr->zstream.avail_out + key_size + 1));
nuclear@0 1268 png_memcpy(text + key_size, png_ptr->zbuf,
nuclear@0 1269 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
nuclear@0 1270 png_memcpy(text, key, key_size);
nuclear@0 1271 text_size = key_size + png_ptr->zbuf_size -
nuclear@0 1272 png_ptr->zstream.avail_out;
nuclear@0 1273 *(text + text_size) = '\0';
nuclear@0 1274 }
nuclear@0 1275 else
nuclear@0 1276 {
nuclear@0 1277 png_charp tmp;
nuclear@0 1278
nuclear@0 1279 tmp = text;
nuclear@0 1280 text = (png_charp)png_malloc(png_ptr, text_size +
nuclear@0 1281 (png_uint_32)(png_ptr->zbuf_size
nuclear@0 1282 - png_ptr->zstream.avail_out + 1));
nuclear@0 1283 png_memcpy(text, tmp, text_size);
nuclear@0 1284 png_free(png_ptr, tmp);
nuclear@0 1285 png_memcpy(text + text_size, png_ptr->zbuf,
nuclear@0 1286 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
nuclear@0 1287 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
nuclear@0 1288 *(text + text_size) = '\0';
nuclear@0 1289 }
nuclear@0 1290 if (ret != Z_STREAM_END)
nuclear@0 1291 {
nuclear@0 1292 png_ptr->zstream.next_out = png_ptr->zbuf;
nuclear@0 1293 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
nuclear@0 1294 }
nuclear@0 1295 }
nuclear@0 1296 else
nuclear@0 1297 {
nuclear@0 1298 break;
nuclear@0 1299 }
nuclear@0 1300
nuclear@0 1301 if (ret == Z_STREAM_END)
nuclear@0 1302 break;
nuclear@0 1303 }
nuclear@0 1304
nuclear@0 1305 inflateReset(&png_ptr->zstream);
nuclear@0 1306 png_ptr->zstream.avail_in = 0;
nuclear@0 1307
nuclear@0 1308 if (ret != Z_STREAM_END)
nuclear@0 1309 {
nuclear@0 1310 png_ptr->current_text = NULL;
nuclear@0 1311 png_free(png_ptr, key);
nuclear@0 1312 png_free(png_ptr, text);
nuclear@0 1313 return;
nuclear@0 1314 }
nuclear@0 1315
nuclear@0 1316 png_ptr->current_text = NULL;
nuclear@0 1317 png_free(png_ptr, key);
nuclear@0 1318 key = text;
nuclear@0 1319 text += key_size;
nuclear@0 1320
nuclear@0 1321 text_ptr = (png_textp)png_malloc(png_ptr,
nuclear@0 1322 (png_uint_32)png_sizeof(png_text));
nuclear@0 1323 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
nuclear@0 1324 text_ptr->key = key;
nuclear@0 1325 #ifdef PNG_iTXt_SUPPORTED
nuclear@0 1326 text_ptr->lang = NULL;
nuclear@0 1327 text_ptr->lang_key = NULL;
nuclear@0 1328 #endif
nuclear@0 1329 text_ptr->text = text;
nuclear@0 1330
nuclear@0 1331 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
nuclear@0 1332
nuclear@0 1333 png_free(png_ptr, key);
nuclear@0 1334 png_free(png_ptr, text_ptr);
nuclear@0 1335
nuclear@0 1336 if (ret)
nuclear@0 1337 png_warning(png_ptr, "Insufficient memory to store text chunk.");
nuclear@0 1338 }
nuclear@0 1339 }
nuclear@0 1340 #endif
nuclear@0 1341
nuclear@0 1342 #if defined(PNG_READ_iTXt_SUPPORTED)
nuclear@0 1343 void /* PRIVATE */
nuclear@0 1344 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
nuclear@0 1345 length)
nuclear@0 1346 {
nuclear@0 1347 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
nuclear@0 1348 {
nuclear@0 1349 png_error(png_ptr, "Out of place iTXt");
nuclear@0 1350 info_ptr = info_ptr; /* to quiet some compiler warnings */
nuclear@0 1351 }
nuclear@0 1352
nuclear@0 1353 #ifdef PNG_MAX_MALLOC_64K
nuclear@0 1354 png_ptr->skip_length = 0; /* This may not be necessary */
nuclear@0 1355
nuclear@0 1356 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
nuclear@0 1357 {
nuclear@0 1358 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
nuclear@0 1359 png_ptr->skip_length = length - (png_uint_32)65535L;
nuclear@0 1360 length = (png_uint_32)65535L;
nuclear@0 1361 }
nuclear@0 1362 #endif
nuclear@0 1363
nuclear@0 1364 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
nuclear@0 1365 (png_uint_32)(length + 1));
nuclear@0 1366 png_ptr->current_text[length] = '\0';
nuclear@0 1367 png_ptr->current_text_ptr = png_ptr->current_text;
nuclear@0 1368 png_ptr->current_text_size = (png_size_t)length;
nuclear@0 1369 png_ptr->current_text_left = (png_size_t)length;
nuclear@0 1370 png_ptr->process_mode = PNG_READ_iTXt_MODE;
nuclear@0 1371 }
nuclear@0 1372
nuclear@0 1373 void /* PRIVATE */
nuclear@0 1374 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
nuclear@0 1375 {
nuclear@0 1376
nuclear@0 1377 if (png_ptr->buffer_size && png_ptr->current_text_left)
nuclear@0 1378 {
nuclear@0 1379 png_size_t text_size;
nuclear@0 1380
nuclear@0 1381 if (png_ptr->buffer_size < png_ptr->current_text_left)
nuclear@0 1382 text_size = png_ptr->buffer_size;
nuclear@0 1383 else
nuclear@0 1384 text_size = png_ptr->current_text_left;
nuclear@0 1385 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
nuclear@0 1386 png_ptr->current_text_left -= text_size;
nuclear@0 1387 png_ptr->current_text_ptr += text_size;
nuclear@0 1388 }
nuclear@0 1389 if (!(png_ptr->current_text_left))
nuclear@0 1390 {
nuclear@0 1391 png_textp text_ptr;
nuclear@0 1392 png_charp key;
nuclear@0 1393 int comp_flag;
nuclear@0 1394 png_charp lang;
nuclear@0 1395 png_charp lang_key;
nuclear@0 1396 png_charp text;
nuclear@0 1397 int ret;
nuclear@0 1398
nuclear@0 1399 if (png_ptr->buffer_size < 4)
nuclear@0 1400 {
nuclear@0 1401 png_push_save_buffer(png_ptr);
nuclear@0 1402 return;
nuclear@0 1403 }
nuclear@0 1404
nuclear@0 1405 png_push_crc_finish(png_ptr);
nuclear@0 1406
nuclear@0 1407 #if defined(PNG_MAX_MALLOC_64K)
nuclear@0 1408 if (png_ptr->skip_length)
nuclear@0 1409 return;
nuclear@0 1410 #endif
nuclear@0 1411
nuclear@0 1412 key = png_ptr->current_text;
nuclear@0 1413
nuclear@0 1414 for (lang = key; *lang; lang++)
nuclear@0 1415 /* empty loop */ ;
nuclear@0 1416
nuclear@0 1417 if (lang < key + png_ptr->current_text_size - 3)
nuclear@0 1418 lang++;
nuclear@0 1419
nuclear@0 1420 comp_flag = *lang++;
nuclear@0 1421 lang++; /* skip comp_type, always zero */
nuclear@0 1422
nuclear@0 1423 for (lang_key = lang; *lang_key; lang_key++)
nuclear@0 1424 /* empty loop */ ;
nuclear@0 1425 lang_key++; /* skip NUL separator */
nuclear@0 1426
nuclear@0 1427 text=lang_key;
nuclear@0 1428 if (lang_key < key + png_ptr->current_text_size - 1)
nuclear@0 1429 {
nuclear@0 1430 for (; *text; text++)
nuclear@0 1431 /* empty loop */ ;
nuclear@0 1432 }
nuclear@0 1433
nuclear@0 1434 if (text < key + png_ptr->current_text_size)
nuclear@0 1435 text++;
nuclear@0 1436
nuclear@0 1437 text_ptr = (png_textp)png_malloc(png_ptr,
nuclear@0 1438 (png_uint_32)png_sizeof(png_text));
nuclear@0 1439 text_ptr->compression = comp_flag + 2;
nuclear@0 1440 text_ptr->key = key;
nuclear@0 1441 text_ptr->lang = lang;
nuclear@0 1442 text_ptr->lang_key = lang_key;
nuclear@0 1443 text_ptr->text = text;
nuclear@0 1444 text_ptr->text_length = 0;
nuclear@0 1445 text_ptr->itxt_length = png_strlen(text);
nuclear@0 1446
nuclear@0 1447 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
nuclear@0 1448
nuclear@0 1449 png_ptr->current_text = NULL;
nuclear@0 1450
nuclear@0 1451 png_free(png_ptr, text_ptr);
nuclear@0 1452 if (ret)
nuclear@0 1453 png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
nuclear@0 1454 }
nuclear@0 1455 }
nuclear@0 1456 #endif
nuclear@0 1457
nuclear@0 1458 /* This function is called when we haven't found a handler for this
nuclear@0 1459 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
nuclear@0 1460 * name or a critical chunk), the chunk is (currently) silently ignored.
nuclear@0 1461 */
nuclear@0 1462 void /* PRIVATE */
nuclear@0 1463 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
nuclear@0 1464 length)
nuclear@0 1465 {
nuclear@0 1466 png_uint_32 skip = 0;
nuclear@0 1467
nuclear@0 1468 if (!(png_ptr->chunk_name[0] & 0x20))
nuclear@0 1469 {
nuclear@0 1470 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
nuclear@0 1471 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
nuclear@0 1472 PNG_HANDLE_CHUNK_ALWAYS
nuclear@0 1473 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
nuclear@0 1474 && png_ptr->read_user_chunk_fn == NULL
nuclear@0 1475 #endif
nuclear@0 1476 )
nuclear@0 1477 #endif
nuclear@0 1478 png_chunk_error(png_ptr, "unknown critical chunk");
nuclear@0 1479
nuclear@0 1480 info_ptr = info_ptr; /* to quiet some compiler warnings */
nuclear@0 1481 }
nuclear@0 1482
nuclear@0 1483 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
nuclear@0 1484 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
nuclear@0 1485 {
nuclear@0 1486 #ifdef PNG_MAX_MALLOC_64K
nuclear@0 1487 if (length > (png_uint_32)65535L)
nuclear@0 1488 {
nuclear@0 1489 png_warning(png_ptr, "unknown chunk too large to fit in memory");
nuclear@0 1490 skip = length - (png_uint_32)65535L;
nuclear@0 1491 length = (png_uint_32)65535L;
nuclear@0 1492 }
nuclear@0 1493 #endif
nuclear@0 1494 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
nuclear@0 1495 (png_charp)png_ptr->chunk_name,
nuclear@0 1496 png_sizeof(png_ptr->unknown_chunk.name));
nuclear@0 1497 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
nuclear@0 1498 = '\0';
nuclear@0 1499
nuclear@0 1500 png_ptr->unknown_chunk.size = (png_size_t)length;
nuclear@0 1501 if (length == 0)
nuclear@0 1502 png_ptr->unknown_chunk.data = NULL;
nuclear@0 1503 else
nuclear@0 1504 {
nuclear@0 1505 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
nuclear@0 1506 (png_uint_32)length);
nuclear@0 1507 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
nuclear@0 1508 }
nuclear@0 1509 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
nuclear@0 1510 if (png_ptr->read_user_chunk_fn != NULL)
nuclear@0 1511 {
nuclear@0 1512 /* callback to user unknown chunk handler */
nuclear@0 1513 int ret;
nuclear@0 1514 ret = (*(png_ptr->read_user_chunk_fn))
nuclear@0 1515 (png_ptr, &png_ptr->unknown_chunk);
nuclear@0 1516 if (ret < 0)
nuclear@0 1517 png_chunk_error(png_ptr, "error in user chunk");
nuclear@0 1518 if (ret == 0)
nuclear@0 1519 {
nuclear@0 1520 if (!(png_ptr->chunk_name[0] & 0x20))
nuclear@0 1521 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
nuclear@0 1522 PNG_HANDLE_CHUNK_ALWAYS)
nuclear@0 1523 png_chunk_error(png_ptr, "unknown critical chunk");
nuclear@0 1524 png_set_unknown_chunks(png_ptr, info_ptr,
nuclear@0 1525 &png_ptr->unknown_chunk, 1);
nuclear@0 1526 }
nuclear@0 1527 }
nuclear@0 1528 else
nuclear@0 1529 #endif
nuclear@0 1530 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
nuclear@0 1531 png_free(png_ptr, png_ptr->unknown_chunk.data);
nuclear@0 1532 png_ptr->unknown_chunk.data = NULL;
nuclear@0 1533 }
nuclear@0 1534 else
nuclear@0 1535 #endif
nuclear@0 1536 skip=length;
nuclear@0 1537 png_push_crc_skip(png_ptr, skip);
nuclear@0 1538 }
nuclear@0 1539
nuclear@0 1540 void /* PRIVATE */
nuclear@0 1541 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
nuclear@0 1542 {
nuclear@0 1543 if (png_ptr->info_fn != NULL)
nuclear@0 1544 (*(png_ptr->info_fn))(png_ptr, info_ptr);
nuclear@0 1545 }
nuclear@0 1546
nuclear@0 1547 void /* PRIVATE */
nuclear@0 1548 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
nuclear@0 1549 {
nuclear@0 1550 if (png_ptr->end_fn != NULL)
nuclear@0 1551 (*(png_ptr->end_fn))(png_ptr, info_ptr);
nuclear@0 1552 }
nuclear@0 1553
nuclear@0 1554 void /* PRIVATE */
nuclear@0 1555 png_push_have_row(png_structp png_ptr, png_bytep row)
nuclear@0 1556 {
nuclear@0 1557 if (png_ptr->row_fn != NULL)
nuclear@0 1558 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
nuclear@0 1559 (int)png_ptr->pass);
nuclear@0 1560 }
nuclear@0 1561
nuclear@0 1562 void PNGAPI
nuclear@0 1563 png_progressive_combine_row (png_structp png_ptr,
nuclear@0 1564 png_bytep old_row, png_bytep new_row)
nuclear@0 1565 {
nuclear@0 1566 #ifdef PNG_USE_LOCAL_ARRAYS
nuclear@0 1567 PNG_CONST int FARDATA png_pass_dsp_mask[7] =
nuclear@0 1568 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
nuclear@0 1569 #endif
nuclear@0 1570 if (png_ptr == NULL) return;
nuclear@0 1571 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
nuclear@0 1572 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
nuclear@0 1573 }
nuclear@0 1574
nuclear@0 1575 void PNGAPI
nuclear@0 1576 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
nuclear@0 1577 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
nuclear@0 1578 png_progressive_end_ptr end_fn)
nuclear@0 1579 {
nuclear@0 1580 if (png_ptr == NULL) return;
nuclear@0 1581 png_ptr->info_fn = info_fn;
nuclear@0 1582 png_ptr->row_fn = row_fn;
nuclear@0 1583 png_ptr->end_fn = end_fn;
nuclear@0 1584
nuclear@0 1585 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
nuclear@0 1586 }
nuclear@0 1587
nuclear@0 1588 png_voidp PNGAPI
nuclear@0 1589 png_get_progressive_ptr(png_structp png_ptr)
nuclear@0 1590 {
nuclear@0 1591 if (png_ptr == NULL) return (NULL);
nuclear@0 1592 return png_ptr->io_ptr;
nuclear@0 1593 }
nuclear@0 1594 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */