pngpread.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:30k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /* pngpread.c - read a png file in push mode
  2. libpng 1.0 beta 2 - version 0.87
  3.    For conditions of distribution and use, see copyright notice in png.h
  4. Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  5.    January 15, 1996
  6.    */
  7. #define PNG_INTERNAL
  8. #include "png.h"
  9. #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  10. void
  11. png_process_data(png_structp png_ptr, png_infop info,
  12. png_bytep buffer, png_uint_32 buffer_size)
  13. {
  14. png_push_restore_buffer(png_ptr, buffer, buffer_size);
  15. while (png_ptr->buffer_size)
  16. {
  17. png_process_some_data(png_ptr, info);
  18. }
  19. }
  20. void
  21. png_process_some_data(png_structp png_ptr, png_infop info)
  22. {
  23. switch (png_ptr->process_mode)
  24. {
  25. case PNG_READ_SIG_MODE:
  26. {
  27. png_push_read_sig(png_ptr);
  28. break;
  29. }
  30. case PNG_READ_CHUNK_MODE:
  31. {
  32. png_push_read_chunk(png_ptr, info);
  33. break;
  34. }
  35. case PNG_READ_IDAT_MODE:
  36. {
  37. png_push_read_idat(png_ptr);
  38. break;
  39. }
  40. case PNG_READ_PLTE_MODE:
  41. {
  42. png_push_read_plte(png_ptr, info);
  43. break;
  44. }
  45. #if defined(PNG_READ_tEXt_SUPPORTED)
  46. case PNG_READ_tEXt_MODE:
  47. {
  48. png_push_read_text(png_ptr, info);
  49. break;
  50. }
  51. #endif
  52. case PNG_READ_END_MODE:
  53. {
  54. png_push_read_end(png_ptr, info);
  55. break;
  56. }
  57. case PNG_SKIP_MODE:
  58. {
  59. png_push_skip(png_ptr);
  60. break;
  61. }
  62. default:
  63. {
  64. png_ptr->buffer_size = 0;
  65. break;
  66. }
  67. }
  68. }
  69. void
  70. png_push_read_sig(png_structp png_ptr)
  71. {
  72. png_byte sig[8];
  73. if (png_ptr->buffer_size < 8)
  74. {
  75. png_push_save_buffer(png_ptr);
  76. return;
  77. }
  78. png_push_fill_buffer(png_ptr, sig, 8);
  79. if (png_check_sig(sig, 8))
  80. {
  81. png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  82. }
  83. else
  84. {
  85.     png_error(png_ptr, "Not a PNG file");
  86. }
  87. }
  88. void
  89. png_push_read_chunk(png_structp png_ptr, png_infop info)
  90. {
  91. if (!png_ptr->have_chunk_header)
  92. {
  93. png_byte chunk_start[8];
  94. if (png_ptr->buffer_size < 8)
  95. {
  96. png_push_save_buffer(png_ptr);
  97. return;
  98. }
  99. png_push_fill_buffer(png_ptr, chunk_start, 8);
  100. png_ptr->push_length = png_get_uint_32(chunk_start);
  101. png_memcpy(png_ptr->push_chunk_name, (png_voidp)(chunk_start + 4), 4);
  102. png_ptr->have_chunk_header = 1;
  103. png_reset_crc(png_ptr);
  104. png_calculate_crc(png_ptr, chunk_start + 4, 4);
  105. }
  106. if (!png_memcmp(png_ptr->push_chunk_name, png_IHDR, 4))
  107. {
  108. if (png_ptr->mode != PNG_BEFORE_IHDR)
  109. png_error(png_ptr, "Out of Place IHDR");
  110. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  111. {
  112. png_push_save_buffer(png_ptr);
  113. return;
  114. }
  115. png_handle_IHDR(png_ptr, info, png_ptr->push_length);
  116. png_push_check_crc(png_ptr);
  117. png_ptr->mode = PNG_HAVE_IHDR;
  118. }
  119. else if (!png_memcmp(png_ptr->push_chunk_name, png_PLTE, 4))
  120. {
  121. if (png_ptr->mode != PNG_HAVE_IHDR)
  122. png_error(png_ptr, "Missing IHDR");
  123. #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
  124. if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  125. png_push_crc_skip(png_ptr, length);
  126. else
  127. #else
  128. {
  129. png_push_handle_PLTE(png_ptr, png_ptr->push_length);
  130. }
  131. #endif
  132. png_ptr->mode = PNG_HAVE_PLTE;
  133. }
  134. else if (!png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4))
  135. {
  136. png_ptr->idat_size = png_ptr->push_length;
  137. png_ptr->mode = PNG_HAVE_IDAT;
  138. png_ptr->process_mode = PNG_READ_IDAT_MODE;
  139. png_push_have_info(png_ptr, info);
  140. png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
  141. png_ptr->zstream->next_out = png_ptr->row_buf;
  142. return;
  143. }
  144. else if (!png_memcmp(png_ptr->push_chunk_name, png_IEND, 4))
  145. {
  146. png_error(png_ptr, "No Image in File");
  147. }
  148. #if defined(PNG_READ_gAMA_SUPPORTED)
  149. else if (!png_memcmp(png_ptr->push_chunk_name, png_gAMA, 4))
  150. {
  151. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  152. {
  153. png_push_save_buffer(png_ptr);
  154. return;
  155. }
  156. if (png_ptr->mode != PNG_HAVE_IHDR)
  157. png_error(png_ptr, "Out of Place PLTE");
  158. png_handle_gAMA(png_ptr, info, png_ptr->push_length);
  159. png_push_check_crc(png_ptr);
  160. }
  161. #endif
  162. #if defined(PNG_READ_sBIT_SUPPORTED)
  163. else if (!png_memcmp(png_ptr->push_chunk_name, png_sBIT, 4))
  164. {
  165. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  166. {
  167. png_push_save_buffer(png_ptr);
  168. return;
  169. }
  170. if (png_ptr->mode != PNG_HAVE_IHDR)
  171. png_error(png_ptr, "Out of Place sBIT");
  172. png_handle_sBIT(png_ptr, info, png_ptr->push_length);
  173. png_push_check_crc(png_ptr);
  174. }
  175. #endif
  176. #if defined(PNG_READ_cHRM_SUPPORTED)
  177. else if (!png_memcmp(png_ptr->push_chunk_name, png_cHRM, 4))
  178. {
  179. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  180. {
  181. png_push_save_buffer(png_ptr);
  182. return;
  183. }
  184. if (png_ptr->mode != PNG_HAVE_IHDR)
  185. png_error(png_ptr, "Out of Place cHRM");
  186. png_handle_cHRM(png_ptr, info, png_ptr->push_length);
  187. png_push_check_crc(png_ptr);
  188. }
  189. #endif
  190. #if defined(PNG_READ_tRNS_SUPPORTED)
  191. else if (!png_memcmp(png_ptr->push_chunk_name, png_tRNS, 4))
  192. {
  193. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  194. {
  195. png_push_save_buffer(png_ptr);
  196. return;
  197. }
  198. if (png_ptr->mode != PNG_HAVE_IHDR &&
  199. png_ptr->mode != PNG_HAVE_PLTE)
  200. png_error(png_ptr, "Out of Place tRNS");
  201. png_handle_tRNS(png_ptr, info, png_ptr->push_length);
  202. png_push_check_crc(png_ptr);
  203. }
  204. #endif
  205. #if defined(PNG_READ_bKGD_SUPPORTED)
  206. else if (!png_memcmp(png_ptr->push_chunk_name, png_bKGD, 4))
  207. {
  208. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  209. {
  210. png_push_save_buffer(png_ptr);
  211. return;
  212. }
  213. if (png_ptr->mode != PNG_HAVE_IHDR &&
  214. png_ptr->mode != PNG_HAVE_PLTE)
  215. png_error(png_ptr, "Out of Place bKGD");
  216. png_handle_bKGD(png_ptr, info, png_ptr->push_length);
  217. png_push_check_crc(png_ptr);
  218. }
  219. #endif
  220. #if defined(PNG_READ_hIST_SUPPORTED)
  221. else if (!png_memcmp(png_ptr->push_chunk_name, png_hIST, 4))
  222. {
  223. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  224. {
  225. png_push_save_buffer(png_ptr);
  226. return;
  227. }
  228. if (png_ptr->mode != PNG_HAVE_PLTE)
  229. png_error(png_ptr, "Out of Place hIST");
  230. png_handle_hIST(png_ptr, info, png_ptr->push_length);
  231. png_push_check_crc(png_ptr);
  232. }
  233. #endif
  234. #if defined(PNG_READ_pHYs_SUPPORTED)
  235. else if (!png_memcmp(png_ptr->push_chunk_name, png_pHYs, 4))
  236. {
  237. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  238. {
  239. png_push_save_buffer(png_ptr);
  240. return;
  241. }
  242. if (png_ptr->mode != PNG_HAVE_IHDR &&
  243. png_ptr->mode != PNG_HAVE_PLTE)
  244. png_error(png_ptr, "Out of Place pHYs");
  245. png_handle_pHYs(png_ptr, info, png_ptr->push_length);
  246. png_push_check_crc(png_ptr);
  247. }
  248. #endif
  249. #if defined(PNG_READ_oFFs_SUPPORTED)
  250. else if (!png_memcmp(png_ptr->push_chunk_name, png_oFFs, 4))
  251. {
  252. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  253. {
  254. png_push_save_buffer(png_ptr);
  255. return;
  256. }
  257. if (png_ptr->mode != PNG_HAVE_IHDR &&
  258. png_ptr->mode != PNG_HAVE_PLTE)
  259. png_error(png_ptr, "Out of Place oFFs");
  260. png_handle_oFFs(png_ptr, info, png_ptr->push_length);
  261. png_push_check_crc(png_ptr);
  262. }
  263. #endif
  264. #if defined(PNG_READ_tIME_SUPPORTED)
  265. else if (!png_memcmp(png_ptr->push_chunk_name, png_tIME, 4))
  266. {
  267. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  268. {
  269. png_push_save_buffer(png_ptr);
  270. return;
  271. }
  272. if (png_ptr->mode == PNG_BEFORE_IHDR ||
  273. png_ptr->mode == PNG_AFTER_IEND)
  274. png_error(png_ptr, "Out of Place tIME");
  275. png_handle_tIME(png_ptr, info, png_ptr->push_length);
  276. png_push_check_crc(png_ptr);
  277. }
  278. #endif
  279. #if defined(PNG_READ_tEXt_SUPPORTED)
  280. else if (!png_memcmp(png_ptr->push_chunk_name, png_tEXt, 4))
  281. {
  282. if (png_ptr->mode == PNG_BEFORE_IHDR ||
  283. png_ptr->mode == PNG_AFTER_IEND)
  284. png_error(png_ptr, "Out of Place tEXt");
  285. png_push_handle_tEXt(png_ptr, png_ptr->push_length);
  286. }
  287. #endif
  288. #if defined(PNG_READ_zTXt_SUPPORTED)
  289. else if (!png_memcmp(png_ptr->push_chunk_name, png_zTXt, 4))
  290. {
  291. if (png_ptr->mode == PNG_BEFORE_IHDR ||
  292. png_ptr->mode == PNG_AFTER_IEND)
  293. png_error(png_ptr, "Out of Place zTXt");
  294. png_push_handle_zTXt(png_ptr, png_ptr->push_length);
  295. }
  296. #endif
  297. else
  298. {
  299. if ((png_ptr->push_chunk_name[0] & 0x20) == 0)
  300. png_error(png_ptr, "Unknown Critical Chunk");
  301. png_push_crc_skip(png_ptr, png_ptr->push_length);
  302. }
  303. png_ptr->have_chunk_header = 0;
  304. }
  305. void
  306. png_push_check_crc(png_structp png_ptr)
  307. {
  308. png_byte crc_buf[4];
  309. png_uint_32 crc;
  310. png_push_fill_buffer(png_ptr, crc_buf, 4);
  311. crc = png_get_uint_32(crc_buf);
  312. if (((crc ^ 0xffffffffL) & 0xffffffffL) !=
  313. (png_ptr->crc & 0xffffffffL))
  314. png_error(png_ptr, "Bad CRC value");
  315. }
  316. void
  317. png_push_crc_skip(png_structp png_ptr, png_uint_32 length)
  318. {
  319. png_ptr->process_mode = PNG_SKIP_MODE;
  320. png_ptr->skip_length = length;
  321. }
  322. void
  323. png_push_skip(png_structp png_ptr)
  324. {
  325. if (png_ptr->skip_length && png_ptr->save_buffer_size)
  326. {
  327. png_uint_32 save_size;
  328. if (png_ptr->skip_length < png_ptr->save_buffer_size)
  329. save_size = png_ptr->skip_length;
  330. else
  331. save_size = png_ptr->save_buffer_size;
  332. png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  333. png_ptr->skip_length -= save_size;
  334. png_ptr->buffer_size -= save_size;
  335. png_ptr->save_buffer_size -= save_size;
  336. png_ptr->save_buffer_ptr += (png_size_t)save_size;
  337. }
  338. if (png_ptr->skip_length && png_ptr->current_buffer_size)
  339. {
  340. png_uint_32 save_size;
  341. if (png_ptr->skip_length < png_ptr->current_buffer_size)
  342. save_size = png_ptr->skip_length;
  343. else
  344. save_size = png_ptr->current_buffer_size;
  345. png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  346. png_ptr->skip_length -= save_size;
  347. png_ptr->buffer_size -= save_size;
  348. png_ptr->current_buffer_size -= save_size;
  349. png_ptr->current_buffer_ptr += (png_size_t)save_size;
  350. }
  351. if (!png_ptr->skip_length && png_ptr->buffer_size >= 4)
  352. {
  353. png_push_check_crc(png_ptr);
  354. png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  355. }
  356. }
  357. void
  358. png_push_fill_buffer(png_structp png_ptr, png_bytep buffer,
  359. png_uint_32 length)
  360. {
  361. png_bytep ptr;
  362. ptr = buffer;
  363. if (png_ptr->save_buffer_size)
  364. {
  365. png_uint_32 save_size;
  366. if (length < png_ptr->save_buffer_size)
  367. save_size = length;
  368. else
  369. save_size = png_ptr->save_buffer_size;
  370. png_memcpy(ptr, png_ptr->save_buffer_ptr, (png_size_t)save_size);
  371. length -= save_size;
  372. ptr += (png_size_t)save_size;
  373. png_ptr->buffer_size -= save_size;
  374. png_ptr->save_buffer_size -= save_size;
  375. png_ptr->save_buffer_ptr += (png_size_t)save_size;
  376. }
  377. if (length && png_ptr->current_buffer_size)
  378. {
  379. png_uint_32 save_size;
  380. if (length < png_ptr->current_buffer_size)
  381. save_size = length;
  382. else
  383. save_size = png_ptr->current_buffer_size;
  384. png_memcpy(ptr, png_ptr->current_buffer_ptr, (png_size_t)save_size);
  385. png_ptr->buffer_size -= save_size;
  386. png_ptr->current_buffer_size -= save_size;
  387. png_ptr->current_buffer_ptr += (png_size_t)save_size;
  388. }
  389. }
  390. void
  391. png_push_save_buffer(png_structp png_ptr)
  392. {
  393. if (png_ptr->save_buffer_size)
  394. {
  395. if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
  396. {
  397. int i;
  398. png_bytep sp;
  399. png_bytep dp;
  400. for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
  401. i < png_ptr->save_buffer_size;
  402. i++, sp++, dp++)
  403. {
  404.           *dp = *sp;
  405. }
  406. }
  407. }
  408. if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
  409. png_ptr->save_buffer_max)
  410. {
  411. int new_max;
  412. png_bytep old_buffer;
  413. new_max = (int)(png_ptr->save_buffer_size +
  414. png_ptr->current_buffer_size + 256);
  415. old_buffer = png_ptr->save_buffer;
  416. png_ptr->save_buffer = (png_bytep)
  417. png_large_malloc(png_ptr, new_max);
  418. png_memcpy(png_ptr->save_buffer, old_buffer,
  419. (png_size_t)png_ptr->save_buffer_size);
  420. png_large_free(png_ptr, old_buffer);
  421.   png_ptr->save_buffer_max = new_max;
  422. }
  423. if (png_ptr->current_buffer_size)
  424. {
  425. png_memcpy(png_ptr->save_buffer +
  426. (png_size_t)png_ptr->save_buffer_size,
  427. png_ptr->current_buffer_ptr,
  428. (png_size_t)png_ptr->current_buffer_size);
  429. png_ptr->save_buffer_size += png_ptr->current_buffer_size;
  430. png_ptr->current_buffer_size = 0;
  431. }
  432. png_ptr->save_buffer_ptr = png_ptr->save_buffer;
  433. png_ptr->buffer_size = 0;
  434. }
  435. void
  436. png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
  437. png_uint_32 buffer_length)
  438. {
  439. png_ptr->current_buffer = buffer;
  440. png_ptr->current_buffer_size = buffer_length;
  441. png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
  442. png_ptr->current_buffer_ptr = png_ptr->current_buffer;
  443. }
  444. void
  445. png_push_read_idat(png_structp png_ptr)
  446. {
  447. if (!png_ptr->have_chunk_header)
  448. {
  449. png_byte chunk_start[8];
  450. if (png_ptr->buffer_size < 8)
  451. {
  452. png_push_save_buffer(png_ptr);
  453. return;
  454. }
  455. png_push_fill_buffer(png_ptr, chunk_start, 8);
  456. png_ptr->push_length = png_get_uint_32(chunk_start);
  457. png_memcpy(png_ptr->push_chunk_name,
  458. (png_voidp)(chunk_start + 4), 4);
  459. png_ptr->have_chunk_header = 1;
  460. png_reset_crc(png_ptr);
  461. png_calculate_crc(png_ptr, chunk_start + 4, 4);
  462. if (png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4))
  463. {
  464. png_ptr->process_mode = PNG_READ_END_MODE;
  465. if (!png_ptr->zlib_finished)
  466. png_error(png_ptr, "Not enough compressed data");
  467. return;
  468. }
  469. png_ptr->idat_size = png_ptr->push_length;
  470. }
  471. if (png_ptr->idat_size && png_ptr->save_buffer_size)
  472. {
  473. png_uint_32 save_size;
  474. if (png_ptr->idat_size < png_ptr->save_buffer_size)
  475. save_size = png_ptr->idat_size;
  476. else
  477. save_size = png_ptr->save_buffer_size;
  478. png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
  479. png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
  480. png_ptr->idat_size -= save_size;
  481. png_ptr->buffer_size -= save_size;
  482. png_ptr->save_buffer_size -= save_size;
  483. png_ptr->save_buffer_ptr += (png_size_t)save_size;
  484. }
  485. if (png_ptr->idat_size && png_ptr->current_buffer_size)
  486. {
  487. png_uint_32 save_size;
  488. if (png_ptr->idat_size < png_ptr->current_buffer_size)
  489. save_size = png_ptr->idat_size;
  490. else
  491. save_size = png_ptr->current_buffer_size;
  492. png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
  493. png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
  494. png_ptr->idat_size -= save_size;
  495. png_ptr->buffer_size -= save_size;
  496. png_ptr->current_buffer_size -= save_size;
  497. png_ptr->current_buffer_ptr += (png_size_t)save_size;
  498. }
  499. if (!png_ptr->idat_size && png_ptr->buffer_size >= 4)
  500. {
  501. png_push_check_crc(png_ptr);
  502. png_ptr->have_chunk_header = 0;
  503. }
  504. }
  505. void
  506. png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
  507. png_uint_32 buffer_length)
  508. {
  509. int ret;
  510. if (png_ptr->zlib_finished && buffer_length)
  511.     png_error(png_ptr, "Extra compression data");
  512. png_ptr->zstream->next_in = buffer;
  513. png_ptr->zstream->avail_in = (uInt)buffer_length;
  514. do
  515. {
  516. ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
  517. if (ret == Z_STREAM_END)
  518. {
  519. if (png_ptr->zstream->avail_in)
  520. png_error(png_ptr, "Extra compressed data");
  521. if (!png_ptr->zstream->avail_out)
  522. {
  523. png_push_process_row(png_ptr);
  524. }
  525. png_ptr->mode = PNG_AT_LAST_IDAT;
  526. png_ptr->zlib_finished = 1;
  527. break;
  528. }
  529. if (ret != Z_OK)
  530. png_error(png_ptr, "Compression Error");
  531. if (!(png_ptr->zstream->avail_out))
  532. {
  533. png_push_process_row(png_ptr);
  534. png_ptr->zstream->avail_out = (uInt)png_ptr->irowbytes;
  535. png_ptr->zstream->next_out = png_ptr->row_buf;
  536. }
  537. } while (png_ptr->zstream->avail_in);
  538. }
  539. void
  540. png_push_process_row(png_structp png_ptr)
  541. {
  542. png_ptr->row_info.color_type = png_ptr->color_type;
  543.    png_ptr->row_info.width = png_ptr->iwidth;
  544.    png_ptr->row_info.channels = png_ptr->channels;
  545.    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
  546.    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
  547.    png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
  548.       (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
  549. if (png_ptr->row_buf[0])
  550.       png_read_filter_row(&(png_ptr->row_info),
  551.          png_ptr->row_buf + 1, png_ptr->prev_row + 1,
  552. (int)(png_ptr->row_buf[0]));
  553.    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1);
  554.    if (png_ptr->transformations)
  555.       png_do_read_transformations(png_ptr);
  556. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  557. /* blow up interlaced rows to full size */
  558. if (png_ptr->interlaced &&
  559. (png_ptr->transformations & PNG_INTERLACE))
  560. {
  561. if (png_ptr->pass < 6)
  562. png_do_read_interlace(&(png_ptr->row_info),
  563. png_ptr->row_buf + 1, png_ptr->pass);
  564. switch (png_ptr->pass)
  565. {
  566. case 0:
  567. {
  568. int i;
  569. for (i = 0; i < 8 && png_ptr->pass == 0; i++)
  570. {
  571. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  572. png_read_push_finish_row(png_ptr);
  573. }
  574. break;
  575. }
  576. case 1:
  577. {
  578. int i;
  579. for (i = 0; i < 8 && png_ptr->pass == 1; i++)
  580. {
  581. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  582. png_read_push_finish_row(png_ptr);
  583. }
  584. if (png_ptr->pass == 2)
  585. {
  586. for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  587. {
  588. png_push_have_row(png_ptr, NULL);
  589. png_read_push_finish_row(png_ptr);
  590. }
  591. }
  592. break;
  593. }
  594. case 2:
  595. {
  596. int i;
  597. for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  598. {
  599. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  600. png_read_push_finish_row(png_ptr);
  601. }
  602. for (i = 0; i < 4 && png_ptr->pass == 2; i++)
  603. {
  604. png_push_have_row(png_ptr, NULL);
  605. png_read_push_finish_row(png_ptr);
  606. }
  607. break;
  608. }
  609. case 3:
  610. {
  611. int i;
  612. for (i = 0; i < 4 && png_ptr->pass == 3; i++)
  613. {
  614. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  615. png_read_push_finish_row(png_ptr);
  616. }
  617. if (png_ptr->pass == 4)
  618. {
  619. for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  620. {
  621. png_push_have_row(png_ptr, NULL);
  622. png_read_push_finish_row(png_ptr);
  623. }
  624. }
  625. break;
  626. }
  627. case 4:
  628. {
  629. int i;
  630. for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  631. {
  632. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  633. png_read_push_finish_row(png_ptr);
  634. }
  635. for (i = 0; i < 2 && png_ptr->pass == 4; i++)
  636. {
  637. png_push_have_row(png_ptr, NULL);
  638. png_read_push_finish_row(png_ptr);
  639. }
  640. break;
  641. }
  642. case 5:
  643. {
  644. int i;
  645. for (i = 0; i < 2 && png_ptr->pass == 5; i++)
  646. {
  647. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  648. png_read_push_finish_row(png_ptr);
  649. }
  650. if (png_ptr->pass == 6)
  651. {
  652. png_push_have_row(png_ptr, NULL);
  653. png_read_push_finish_row(png_ptr);
  654. }
  655. break;
  656. }
  657. case 6:
  658. {
  659. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  660. png_read_push_finish_row(png_ptr);
  661. if (png_ptr->pass != 6)
  662. break;
  663. png_push_have_row(png_ptr, NULL);
  664. png_read_push_finish_row(png_ptr);
  665. }
  666. }
  667. }
  668. else
  669. #endif
  670. {
  671. png_push_have_row(png_ptr, png_ptr->row_buf + 1);
  672. png_read_push_finish_row(png_ptr);
  673. }
  674. }
  675. void
  676. png_read_push_finish_row(png_structp png_ptr)
  677. {
  678.    png_ptr->row_number++;
  679.    if (png_ptr->row_number < png_ptr->num_rows)
  680. return;
  681.    if (png_ptr->interlaced)
  682.    {
  683.       png_ptr->row_number = 0;
  684.       png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  685.       do
  686.       {
  687.          png_ptr->pass++;
  688.          if (png_ptr->pass >= 7)
  689.             break;
  690.          png_ptr->iwidth = (png_ptr->width +
  691.             png_pass_inc[png_ptr->pass] - 1 -
  692.             png_pass_start[png_ptr->pass]) /
  693.             png_pass_inc[png_ptr->pass];
  694.          png_ptr->irowbytes = ((png_ptr->iwidth *
  695.             png_ptr->pixel_depth + 7) >> 3) + 1;
  696.          if (!(png_ptr->transformations & PNG_INTERLACE))
  697. {
  698.             png_ptr->num_rows = (png_ptr->height +
  699.                png_pass_yinc[png_ptr->pass] - 1 -
  700.                png_pass_ystart[png_ptr->pass]) /
  701.                png_pass_yinc[png_ptr->pass];
  702.             if (!(png_ptr->num_rows))
  703.                continue;
  704.          }
  705.          if (png_ptr->transformations & PNG_INTERLACE)
  706.             break;
  707.       } while (png_ptr->iwidth == 0);
  708.    }
  709. }
  710. void
  711. png_push_handle_PLTE(png_structp png_ptr, png_uint_32 length)
  712. {
  713. if (length % 3)
  714. png_error(png_ptr, "Invalid Palette Chunk");
  715. png_ptr->num_palette = (png_uint_16)(length / 3);
  716. png_ptr->cur_palette = 0;
  717. png_ptr->palette = (png_colorp)png_large_malloc(png_ptr,
  718. png_ptr->num_palette * sizeof (png_color));
  719. png_ptr->process_mode = PNG_READ_PLTE_MODE;
  720. }
  721. void
  722. png_push_read_plte(png_structp png_ptr, png_infop info)
  723. {
  724. while (png_ptr->cur_palette < png_ptr->num_palette &&
  725. png_ptr->buffer_size >= 3)
  726. {
  727. png_byte buf[3];
  728. png_push_fill_buffer(png_ptr, buf, 3);
  729. png_calculate_crc(png_ptr, buf, 3);
  730. /* don't depend upon png_color being any order */
  731. png_ptr->palette[png_ptr->cur_palette].red = buf[0];
  732. png_ptr->palette[png_ptr->cur_palette].green = buf[1];
  733. png_ptr->palette[png_ptr->cur_palette].blue = buf[2];
  734. png_ptr->cur_palette++;
  735. }
  736. if (png_ptr->cur_palette == png_ptr->num_palette &&
  737. png_ptr->buffer_size >= 4)
  738. {
  739. png_push_check_crc(png_ptr);
  740. png_read_PLTE(png_ptr, info, png_ptr->palette, png_ptr->num_palette);
  741. png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  742. }
  743. else
  744. {
  745. png_push_save_buffer(png_ptr);
  746. }
  747. }
  748. #if defined(PNG_READ_tEXt_SUPPORTED)
  749. void
  750. png_push_handle_tEXt(png_structp png_ptr, png_uint_32 length)
  751. {
  752. png_ptr->current_text = (png_charp)png_large_malloc(png_ptr, length + 1);
  753. png_ptr->current_text[(png_size_t)length] = '';
  754. png_ptr->current_text_ptr = png_ptr->current_text;
  755. png_ptr->current_text_size = length;
  756. png_ptr->current_text_left = length;
  757. png_ptr->process_mode = PNG_READ_tEXt_MODE;
  758. }
  759. void
  760. png_push_read_text(png_structp png_ptr, png_infop info)
  761. {
  762. if (png_ptr->buffer_size && png_ptr->current_text_left)
  763. {
  764. png_uint_32 text_size;
  765. if (png_ptr->buffer_size < png_ptr->current_text_left)
  766. text_size = png_ptr->buffer_size;
  767. else
  768. text_size = png_ptr->current_text_left;
  769. png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  770. text_size);
  771. png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  772. text_size);
  773. png_ptr->current_text_left -= text_size;
  774. png_ptr->current_text_ptr += (png_size_t)text_size;
  775. }
  776. if (!(png_ptr->current_text_left) && png_ptr->buffer_size >= 4)
  777. {
  778. png_charp text;
  779. png_charp key;
  780. png_push_check_crc(png_ptr);
  781. key = png_ptr->current_text;
  782. png_ptr->current_text = 0;
  783. for (text = key; *text; text++)
  784. /* empty loop */ ;
  785. if (text != key + (png_size_t)png_ptr->current_text_size)
  786. text++;
  787. png_read_tEXt(png_ptr, info, key, text,
  788. png_ptr->current_text_size - (text - key));
  789. png_ptr->process_mode = PNG_READ_CHUNK_MODE;
  790. }
  791. }
  792. #endif
  793. #if defined(PNG_READ_zTXt_SUPPORTED)
  794. void
  795. png_push_handle_zTXt(png_structp png_ptr,
  796. png_uint_32 length)
  797. {
  798. png_ptr->current_text = (png_charp)png_large_malloc(png_ptr, length + 1);
  799. png_ptr->current_text[(png_size_t)length] = '';
  800. png_ptr->current_text_ptr = png_ptr->current_text;
  801. png_ptr->current_text_size = length;
  802. png_ptr->current_text_left = length;
  803. png_ptr->process_mode = PNG_READ_zTXt_MODE;
  804. }
  805. void
  806. png_push_read_ztxt(png_structp png_ptr, png_infop info)
  807. {
  808. if (png_ptr->buffer_size && png_ptr->current_text_left)
  809. {
  810. png_uint_32 text_size;
  811. if (png_ptr->buffer_size < png_ptr->current_text_left)
  812. text_size = png_ptr->buffer_size;
  813. else
  814. text_size = png_ptr->current_text_left;
  815. png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  816. text_size);
  817. png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
  818. text_size);
  819. png_ptr->current_text_left -= text_size;
  820. png_ptr->current_text_ptr += (png_size_t)text_size;
  821. }
  822. if (!(png_ptr->current_text_left) && png_ptr->buffer_size >= 4)
  823. {
  824. png_charp text;
  825. png_charp key;
  826. int ret;
  827. png_uint_32 text_size, key_size;
  828. png_push_check_crc(png_ptr);
  829. key = png_ptr->current_text;
  830. png_ptr->current_text = 0;
  831. for (text = key; *text; text++)
  832. /* empty loop */ ;
  833. /* zTXt can't have zero text */
  834. if (text == key + (png_size_t)png_ptr->current_text_size)
  835. {
  836. png_large_free(png_ptr, key);
  837. return;
  838. }
  839. text++;
  840. if (*text) /* check compression byte */
  841. {
  842. png_large_free(png_ptr, key);
  843. return;
  844. }
  845. text++;
  846. png_ptr->zstream->next_in = (png_bytep )text;
  847. png_ptr->zstream->avail_in = (uInt)(png_ptr->current_text_size -
  848. (text - key));
  849. png_ptr->zstream->next_out = png_ptr->zbuf;
  850. png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size;
  851. key_size = text - key;
  852. text_size = 0;
  853. text = NULL;
  854. ret = Z_STREAM_END;
  855. while (png_ptr->zstream->avail_in)
  856. {
  857. ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
  858. if (ret != Z_OK && ret != Z_STREAM_END)
  859. {
  860. inflateReset(png_ptr->zstream);
  861. png_ptr->zstream->avail_in = 0;
  862. png_large_free(png_ptr, key);
  863. png_large_free(png_ptr, text);
  864. return;
  865. }
  866. if (!png_ptr->zstream->avail_out || ret == Z_STREAM_END)
  867. {
  868. if (!text)
  869. {
  870. text = (png_charp)png_large_malloc(png_ptr,
  871. png_ptr->zbuf_size - png_ptr->zstream->avail_out +
  872. key_size + 1);
  873. png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
  874. (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
  875. png_memcpy(text, key, (png_size_t)key_size);
  876. text_size = key_size + (png_size_t)png_ptr->zbuf_size -
  877. png_ptr->zstream->avail_out;
  878. *(text + (png_size_t)text_size) = '';
  879. }
  880. else
  881. {
  882. png_charp tmp;
  883. tmp = text;
  884. text = png_large_malloc(png_ptr, text_size +
  885. png_ptr->zbuf_size - png_ptr->zstream->avail_out + 1);
  886. png_memcpy(text, tmp, (png_size_t)text_size);
  887. png_large_free(png_ptr, tmp);
  888. png_memcpy(text + (png_size_t)text_size, png_ptr->zbuf,
  889. (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
  890. text_size += png_ptr->zbuf_size - png_ptr->zstream->avail_out;
  891. *(text + (png_size_t)text_size) = '';
  892. }
  893. if (ret != Z_STREAM_END)
  894. {
  895. png_ptr->zstream->next_out = png_ptr->zbuf;
  896. png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  897. }
  898. }
  899. else
  900. {
  901. break;
  902. }
  903. if (ret == Z_STREAM_END)
  904. break;
  905. }
  906. inflateReset(png_ptr->zstream);
  907. png_ptr->zstream->avail_in = 0;
  908. if (ret != Z_STREAM_END)
  909. {
  910. png_large_free(png_ptr, key);
  911. png_large_free(png_ptr, text);
  912. return;
  913. }
  914. png_large_free(png_ptr, key);
  915. key = text;
  916. text += (png_size_t)key_size;
  917. text_size -= key_size;
  918. png_read_zTXt(png_ptr, info, key, text, text_size, 0);
  919. }
  920. }
  921. #endif
  922. void
  923. png_push_have_info(png_structp png_ptr, png_infop info)
  924. {
  925. if (png_ptr->info_fn)
  926. (*(png_ptr->info_fn))(png_ptr, info);
  927. }
  928. void
  929. png_push_have_end(png_structp png_ptr, png_infop info)
  930. {
  931. if (png_ptr->end_fn)
  932. (*(png_ptr->end_fn))(png_ptr, info);
  933. }
  934. void
  935. png_push_have_row(png_structp png_ptr, png_bytep row)
  936. {
  937. if (png_ptr->row_fn)
  938. (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
  939. (int)png_ptr->pass);
  940. }
  941. png_voidp
  942. png_get_progressive_ptr(png_structp png_ptr)
  943. {
  944. return png_ptr->push_ptr;
  945. }
  946. void
  947. png_push_read_end(png_structp png_ptr, png_infop info)
  948. {
  949. if (!png_ptr->have_chunk_header)
  950. {
  951. png_byte chunk_start[8];
  952. if (png_ptr->buffer_size < 8)
  953. {
  954. png_push_save_buffer(png_ptr);
  955. return;
  956. }
  957. png_push_fill_buffer(png_ptr, chunk_start, 8);
  958. png_ptr->push_length = png_get_uint_32(chunk_start);
  959. png_memcpy(png_ptr->push_chunk_name, (png_voidp)(chunk_start + 4), 4);
  960. png_ptr->have_chunk_header = 1;
  961. png_reset_crc(png_ptr);
  962. png_calculate_crc(png_ptr, chunk_start + 4, 4);
  963. }
  964. if (!png_memcmp(png_ptr->push_chunk_name, png_IHDR, 4))
  965. {
  966. png_error(png_ptr, "invalid chunk after IDAT");
  967. }
  968. else if (!png_memcmp(png_ptr->push_chunk_name, png_PLTE, 4))
  969. {
  970. png_error(png_ptr, "invalid chunk after IDAT");
  971. }
  972. else if (!png_memcmp(png_ptr->push_chunk_name, png_IDAT, 4))
  973. {
  974. if (png_ptr->push_length > 0 || png_ptr->mode != PNG_AT_LAST_IDAT)
  975. png_error(png_ptr, "too many IDAT's found");
  976. }
  977. else if (!png_memcmp(png_ptr->push_chunk_name, png_IEND, 4))
  978. {
  979. if (png_ptr->push_length)
  980.        png_error(png_ptr, "Invalid IEND chunk");
  981. png_push_check_crc(png_ptr);
  982. png_ptr->mode = PNG_AFTER_IEND;
  983. png_ptr->process_mode = PNG_READ_DONE_MODE;
  984. png_push_have_end(png_ptr, info);
  985. }
  986. #if defined(PNG_READ_gAMA_SUPPORTED)
  987. else if (!png_memcmp(png_ptr->push_chunk_name, png_gAMA, 4))
  988. {
  989. png_error(png_ptr, "invalid chunk after IDAT");
  990. }
  991. #endif
  992. #if defined(PNG_READ_sBIT_SUPPORTED)
  993. else if (!png_memcmp(png_ptr->push_chunk_name, png_sBIT, 4))
  994. {
  995. png_error(png_ptr, "invalid chunk after IDAT");
  996. }
  997. #endif
  998. #if defined(PNG_READ_cHRM_SUPPORTED)
  999. else if (!png_memcmp(png_ptr->push_chunk_name, png_cHRM, 4))
  1000. {
  1001. png_error(png_ptr, "invalid chunk after IDAT");
  1002. }
  1003. #endif
  1004. #if defined(PNG_READ_tRNS_SUPPORTED)
  1005. else if (!png_memcmp(png_ptr->push_chunk_name, png_tRNS, 4))
  1006. {
  1007. png_error(png_ptr, "invalid chunk after IDAT");
  1008. }
  1009. #endif
  1010. #if defined(PNG_READ_bKGD_SUPPORTED)
  1011. else if (!png_memcmp(png_ptr->push_chunk_name, png_bKGD, 4))
  1012. {
  1013. png_error(png_ptr, "invalid chunk after IDAT");
  1014. }
  1015. #endif
  1016. #if defined(PNG_READ_hIST_SUPPORTED)
  1017. else if (!png_memcmp(png_ptr->push_chunk_name, png_hIST, 4))
  1018. {
  1019. png_error(png_ptr, "invalid chunk after IDAT");
  1020. }
  1021. #endif
  1022. #if defined(PNG_READ_pHYs_SUPPORTED)
  1023. else if (!png_memcmp(png_ptr->push_chunk_name, png_pHYs, 4))
  1024. {
  1025. png_error(png_ptr, "invalid chunk after IDAT");
  1026. }
  1027. #endif
  1028. #if defined(PNG_READ_oFFs_SUPPORTED)
  1029. else if (!png_memcmp(png_ptr->push_chunk_name, png_oFFs, 4))
  1030. {
  1031. png_error(png_ptr, "invalid chunk after IDAT");
  1032. }
  1033. #endif
  1034. #if defined(PNG_READ_tIME_SUPPORTED)
  1035. else if (!png_memcmp(png_ptr->push_chunk_name, png_tIME, 4))
  1036. {
  1037. if (png_ptr->push_length + 4 > png_ptr->buffer_size)
  1038. {
  1039. png_push_save_buffer(png_ptr);
  1040. return;
  1041. }
  1042. if (png_ptr->mode == PNG_BEFORE_IHDR ||
  1043. png_ptr->mode == PNG_AFTER_IEND)
  1044. png_error(png_ptr, "Out of Place tIME");
  1045. png_handle_tIME(png_ptr, info, png_ptr->push_length);
  1046. png_push_check_crc(png_ptr);
  1047. }
  1048. #endif
  1049. #if defined(PNG_READ_tEXt_SUPPORTED)
  1050. else if (!png_memcmp(png_ptr->push_chunk_name, png_tEXt, 4))
  1051. {
  1052. if (png_ptr->mode == PNG_BEFORE_IHDR ||
  1053. png_ptr->mode == PNG_AFTER_IEND)
  1054. png_error(png_ptr, "Out of Place tEXt");
  1055. png_push_handle_tEXt(png_ptr, png_ptr->push_length);
  1056. }
  1057. #endif
  1058. #if defined(PNG_READ_zTXt_SUPPORTED)
  1059. else if (!png_memcmp(png_ptr->push_chunk_name, png_zTXt, 4))
  1060. {
  1061. if (png_ptr->mode == PNG_BEFORE_IHDR ||
  1062. png_ptr->mode == PNG_AFTER_IEND)
  1063. png_error(png_ptr, "Out of Place zTXt");
  1064. png_push_handle_zTXt(png_ptr, png_ptr->push_length);
  1065. }
  1066. #endif
  1067. else
  1068. {
  1069. if ((png_ptr->push_chunk_name[0] & 0x20) == 0)
  1070. png_error(png_ptr, "Unknown Critical Chunk");
  1071. png_push_crc_skip(png_ptr, png_ptr->push_length);
  1072. }
  1073. if (png_ptr->mode == PNG_AT_LAST_IDAT)
  1074. png_ptr->mode = PNG_AFTER_IDAT;
  1075. png_ptr->have_chunk_header = 0;
  1076. }
  1077. void
  1078. png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
  1079. png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
  1080. png_progressive_end_ptr end_fn)
  1081. {
  1082. png_ptr->info_fn = info_fn;
  1083. png_ptr->row_fn = row_fn;
  1084. png_ptr->push_ptr = progressive_ptr;
  1085.    png_ptr->end_fn = end_fn;
  1086. png_ptr->read_mode = PNG_READ_PUSH_MODE;
  1087. }
  1088. void
  1089. png_progressive_combine_row (png_structp png_ptr,
  1090. png_bytep old_row, png_bytep new_row)
  1091. {
  1092. if (new_row)
  1093. png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
  1094. }
  1095. #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */