You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

888 lines
27KB

  1. /*
  2. * PNG image format
  3. * Copyright (c) 2003 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avformat.h"
  20. /* TODO:
  21. * - add 2, 4 and 16 bit depth support
  22. * - use filters when generating a png (better compression)
  23. */
  24. #ifdef CONFIG_ZLIB
  25. #include <zlib.h>
  26. //#define DEBUG
  27. #define PNG_COLOR_MASK_PALETTE 1
  28. #define PNG_COLOR_MASK_COLOR 2
  29. #define PNG_COLOR_MASK_ALPHA 4
  30. #define PNG_COLOR_TYPE_GRAY 0
  31. #define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
  32. #define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
  33. #define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
  34. #define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
  35. #define PNG_FILTER_VALUE_NONE 0
  36. #define PNG_FILTER_VALUE_SUB 1
  37. #define PNG_FILTER_VALUE_UP 2
  38. #define PNG_FILTER_VALUE_AVG 3
  39. #define PNG_FILTER_VALUE_PAETH 4
  40. #define PNG_IHDR 0x0001
  41. #define PNG_IDAT 0x0002
  42. #define PNG_ALLIMAGE 0x0004
  43. #define PNG_PLTE 0x0008
  44. #define NB_PASSES 7
  45. #define IOBUF_SIZE 4096
  46. typedef struct PNGDecodeState {
  47. int state;
  48. int width, height;
  49. int bit_depth;
  50. int color_type;
  51. int compression_type;
  52. int interlace_type;
  53. int filter_type;
  54. int channels;
  55. int bits_per_pixel;
  56. int bpp;
  57. uint8_t *image_buf;
  58. int image_linesize;
  59. uint32_t palette[256];
  60. uint8_t *crow_buf;
  61. uint8_t *last_row;
  62. uint8_t *tmp_row;
  63. int pass;
  64. int crow_size; /* compressed row size (include filter type) */
  65. int row_size; /* decompressed row size */
  66. int pass_row_size; /* decompress row size of the current pass */
  67. int y;
  68. z_stream zstream;
  69. } PNGDecodeState;
  70. static const uint8_t pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
  71. /* Mask to determine which y pixels are valid in a pass */
  72. static const uint8_t png_pass_ymask[NB_PASSES] = {
  73. 0x80, 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55,
  74. };
  75. /* Mask to determine which y pixels can be written in a pass */
  76. static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
  77. 0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
  78. };
  79. /* minimum x value */
  80. static const uint8_t png_pass_xmin[NB_PASSES] = {
  81. 0, 4, 0, 2, 0, 1, 0
  82. };
  83. /* x shift to get row width */
  84. static const uint8_t png_pass_xshift[NB_PASSES] = {
  85. 3, 3, 2, 2, 1, 1, 0
  86. };
  87. /* Mask to determine which pixels are valid in a pass */
  88. static const uint8_t png_pass_mask[NB_PASSES] = {
  89. 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff
  90. };
  91. /* Mask to determine which pixels to overwrite while displaying */
  92. static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
  93. 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
  94. };
  95. static int png_probe(AVProbeData *pd)
  96. {
  97. if (pd->buf_size >= 8 &&
  98. memcmp(pd->buf, pngsig, 8) == 0)
  99. return AVPROBE_SCORE_MAX;
  100. else
  101. return 0;
  102. }
  103. static void *png_zalloc(void *opaque, unsigned int items, unsigned int size)
  104. {
  105. return av_malloc(items * size);
  106. }
  107. static void png_zfree(void *opaque, void *ptr)
  108. {
  109. av_free(ptr);
  110. }
  111. static int png_get_nb_channels(int color_type)
  112. {
  113. int channels;
  114. channels = 1;
  115. if ((color_type & (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)) ==
  116. PNG_COLOR_MASK_COLOR)
  117. channels = 3;
  118. if (color_type & PNG_COLOR_MASK_ALPHA)
  119. channels++;
  120. return channels;
  121. }
  122. /* compute the row size of an interleaved pass */
  123. static int png_pass_row_size(int pass, int bits_per_pixel, int width)
  124. {
  125. int shift, xmin, pass_width;
  126. xmin = png_pass_xmin[pass];
  127. if (width <= xmin)
  128. return 0;
  129. shift = png_pass_xshift[pass];
  130. pass_width = (width - xmin + (1 << shift) - 1) >> shift;
  131. return (pass_width * bits_per_pixel + 7) >> 3;
  132. }
  133. /* NOTE: we try to construct a good looking image at each pass. width
  134. is the original image width. We also do pixel format convertion at
  135. this stage */
  136. static void png_put_interlaced_row(uint8_t *dst, int width,
  137. int bits_per_pixel, int pass,
  138. int color_type, const uint8_t *src)
  139. {
  140. int x, mask, dsp_mask, j, src_x, b, bpp;
  141. uint8_t *d;
  142. const uint8_t *s;
  143. mask = png_pass_mask[pass];
  144. dsp_mask = png_pass_dsp_mask[pass];
  145. switch(bits_per_pixel) {
  146. case 1:
  147. /* we must intialize the line to zero before writing to it */
  148. if (pass == 0)
  149. memset(dst, 0, (width + 7) >> 3);
  150. src_x = 0;
  151. for(x = 0; x < width; x++) {
  152. j = (x & 7);
  153. if ((dsp_mask << j) & 0x80) {
  154. b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
  155. dst[x >> 3] |= b << (7 - j);
  156. }
  157. if ((mask << j) & 0x80)
  158. src_x++;
  159. }
  160. break;
  161. default:
  162. bpp = bits_per_pixel >> 3;
  163. d = dst;
  164. s = src;
  165. if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
  166. for(x = 0; x < width; x++) {
  167. j = x & 7;
  168. if ((dsp_mask << j) & 0x80) {
  169. *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
  170. }
  171. d += bpp;
  172. if ((mask << j) & 0x80)
  173. s += bpp;
  174. }
  175. } else {
  176. for(x = 0; x < width; x++) {
  177. j = x & 7;
  178. if ((dsp_mask << j) & 0x80) {
  179. memcpy(d, s, bpp);
  180. }
  181. d += bpp;
  182. if ((mask << j) & 0x80)
  183. s += bpp;
  184. }
  185. }
  186. break;
  187. }
  188. }
  189. static void png_get_interlaced_row(uint8_t *dst, int row_size,
  190. int bits_per_pixel, int pass,
  191. const uint8_t *src, int width)
  192. {
  193. int x, mask, dst_x, j, b, bpp;
  194. uint8_t *d;
  195. const uint8_t *s;
  196. mask = png_pass_mask[pass];
  197. switch(bits_per_pixel) {
  198. case 1:
  199. memset(dst, 0, row_size);
  200. dst_x = 0;
  201. for(x = 0; x < width; x++) {
  202. j = (x & 7);
  203. if ((mask << j) & 0x80) {
  204. b = (src[x >> 3] >> (7 - j)) & 1;
  205. dst[dst_x >> 3] |= b << (7 - (dst_x & 7));
  206. dst_x++;
  207. }
  208. }
  209. break;
  210. default:
  211. bpp = bits_per_pixel >> 3;
  212. d = dst;
  213. s = src;
  214. for(x = 0; x < width; x++) {
  215. j = x & 7;
  216. if ((mask << j) & 0x80) {
  217. memcpy(d, s, bpp);
  218. d += bpp;
  219. }
  220. s += bpp;
  221. }
  222. break;
  223. }
  224. }
  225. /* XXX: optimize */
  226. /* NOTE: 'dst' can be equal to 'last' */
  227. static void png_filter_row(uint8_t *dst, int filter_type,
  228. uint8_t *src, uint8_t *last, int size, int bpp)
  229. {
  230. int i, p;
  231. switch(filter_type) {
  232. case PNG_FILTER_VALUE_NONE:
  233. memcpy(dst, src, size);
  234. break;
  235. case PNG_FILTER_VALUE_SUB:
  236. for(i = 0; i < bpp; i++) {
  237. dst[i] = src[i];
  238. }
  239. for(i = bpp; i < size; i++) {
  240. p = dst[i - bpp];
  241. dst[i] = p + src[i];
  242. }
  243. break;
  244. case PNG_FILTER_VALUE_UP:
  245. for(i = 0; i < size; i++) {
  246. p = last[i];
  247. dst[i] = p + src[i];
  248. }
  249. break;
  250. case PNG_FILTER_VALUE_AVG:
  251. for(i = 0; i < bpp; i++) {
  252. p = (last[i] >> 1);
  253. dst[i] = p + src[i];
  254. }
  255. for(i = bpp; i < size; i++) {
  256. p = ((dst[i - bpp] + last[i]) >> 1);
  257. dst[i] = p + src[i];
  258. }
  259. break;
  260. case PNG_FILTER_VALUE_PAETH:
  261. for(i = 0; i < bpp; i++) {
  262. p = last[i];
  263. dst[i] = p + src[i];
  264. }
  265. for(i = bpp; i < size; i++) {
  266. int a, b, c, pa, pb, pc;
  267. a = dst[i - bpp];
  268. b = last[i];
  269. c = last[i - bpp];
  270. p = b - c;
  271. pc = a - c;
  272. pa = abs(p);
  273. pb = abs(pc);
  274. pc = abs(p + pc);
  275. if (pa <= pb && pa <= pc)
  276. p = a;
  277. else if (pb <= pc)
  278. p = b;
  279. else
  280. p = c;
  281. dst[i] = p + src[i];
  282. }
  283. break;
  284. }
  285. }
  286. static void convert_from_rgba32(uint8_t *dst, const uint8_t *src, int width)
  287. {
  288. uint8_t *d;
  289. int j;
  290. unsigned int v;
  291. d = dst;
  292. for(j = 0; j < width; j++) {
  293. v = ((uint32_t *)src)[j];
  294. d[0] = v >> 16;
  295. d[1] = v >> 8;
  296. d[2] = v;
  297. d[3] = v >> 24;
  298. d += 4;
  299. }
  300. }
  301. static void convert_to_rgba32(uint8_t *dst, const uint8_t *src, int width)
  302. {
  303. int j;
  304. unsigned int r, g, b, a;
  305. for(j = 0;j < width; j++) {
  306. r = src[0];
  307. g = src[1];
  308. b = src[2];
  309. a = src[3];
  310. *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
  311. dst += 4;
  312. src += 4;
  313. }
  314. }
  315. /* process exactly one decompressed row */
  316. static void png_handle_row(PNGDecodeState *s)
  317. {
  318. uint8_t *ptr, *last_row;
  319. int got_line;
  320. if (!s->interlace_type) {
  321. ptr = s->image_buf + s->image_linesize * s->y;
  322. /* need to swap bytes correctly for RGB_ALPHA */
  323. if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
  324. png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
  325. s->last_row, s->row_size, s->bpp);
  326. memcpy(s->last_row, s->tmp_row, s->row_size);
  327. convert_to_rgba32(ptr, s->tmp_row, s->width);
  328. } else {
  329. /* in normal case, we avoid one copy */
  330. if (s->y == 0)
  331. last_row = s->last_row;
  332. else
  333. last_row = ptr - s->image_linesize;
  334. png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1,
  335. last_row, s->row_size, s->bpp);
  336. }
  337. s->y++;
  338. if (s->y == s->height) {
  339. s->state |= PNG_ALLIMAGE;
  340. }
  341. } else {
  342. got_line = 0;
  343. for(;;) {
  344. ptr = s->image_buf + s->image_linesize * s->y;
  345. if ((png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
  346. /* if we already read one row, it is time to stop to
  347. wait for the next one */
  348. if (got_line)
  349. break;
  350. png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
  351. s->last_row, s->pass_row_size, s->bpp);
  352. memcpy(s->last_row, s->tmp_row, s->pass_row_size);
  353. got_line = 1;
  354. }
  355. if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
  356. /* NOTE: rgba32 is handled directly in png_put_interlaced_row */
  357. png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
  358. s->color_type, s->last_row);
  359. }
  360. s->y++;
  361. if (s->y == s->height) {
  362. for(;;) {
  363. if (s->pass == NB_PASSES - 1) {
  364. s->state |= PNG_ALLIMAGE;
  365. goto the_end;
  366. } else {
  367. s->pass++;
  368. s->y = 0;
  369. s->pass_row_size = png_pass_row_size(s->pass,
  370. s->bits_per_pixel,
  371. s->width);
  372. s->crow_size = s->pass_row_size + 1;
  373. if (s->pass_row_size != 0)
  374. break;
  375. /* skip pass if empty row */
  376. }
  377. }
  378. }
  379. }
  380. the_end: ;
  381. }
  382. }
  383. static int png_decode_idat(PNGDecodeState *s, ByteIOContext *f, int length)
  384. {
  385. uint8_t buf[IOBUF_SIZE];
  386. int buf_size;
  387. int ret;
  388. while (length > 0) {
  389. /* read the buffer */
  390. buf_size = IOBUF_SIZE;
  391. if (buf_size > length)
  392. buf_size = length;
  393. ret = get_buffer(f, buf, buf_size);
  394. if (ret != buf_size)
  395. return -1;
  396. s->zstream.avail_in = buf_size;
  397. s->zstream.next_in = buf;
  398. /* decode one line if possible */
  399. while (s->zstream.avail_in > 0) {
  400. ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
  401. if (ret != Z_OK && ret != Z_STREAM_END) {
  402. return -1;
  403. }
  404. if (s->zstream.avail_out == 0) {
  405. if (!(s->state & PNG_ALLIMAGE)) {
  406. png_handle_row(s);
  407. }
  408. s->zstream.avail_out = s->crow_size;
  409. s->zstream.next_out = s->crow_buf;
  410. }
  411. }
  412. length -= buf_size;
  413. }
  414. return 0;
  415. }
  416. static int png_read(ByteIOContext *f,
  417. int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque)
  418. {
  419. AVImageInfo info1, *info = &info1;
  420. PNGDecodeState s1, *s = &s1;
  421. uint32_t tag, length;
  422. int ret, crc;
  423. uint8_t buf[8];
  424. /* check signature */
  425. ret = get_buffer(f, buf, 8);
  426. if (ret != 8)
  427. return -1;
  428. if (memcmp(buf, pngsig, 8) != 0)
  429. return -1;
  430. memset(s, 0, sizeof(PNGDecodeState));
  431. /* init the zlib */
  432. s->zstream.zalloc = png_zalloc;
  433. s->zstream.zfree = png_zfree;
  434. s->zstream.opaque = NULL;
  435. ret = inflateInit(&s->zstream);
  436. if (ret != Z_OK)
  437. return -1;
  438. for(;;) {
  439. if (url_feof(f))
  440. goto fail;
  441. length = get_be32(f);
  442. if (length > 0x7fffffff)
  443. goto fail;
  444. tag = get_le32(f);
  445. #ifdef DEBUG
  446. printf("png: tag=%c%c%c%c length=%u\n",
  447. (tag & 0xff),
  448. ((tag >> 8) & 0xff),
  449. ((tag >> 16) & 0xff),
  450. ((tag >> 24) & 0xff), length);
  451. #endif
  452. switch(tag) {
  453. case MKTAG('I', 'H', 'D', 'R'):
  454. if (length != 13)
  455. goto fail;
  456. s->width = get_be32(f);
  457. s->height = get_be32(f);
  458. s->bit_depth = get_byte(f);
  459. s->color_type = get_byte(f);
  460. s->compression_type = get_byte(f);
  461. s->filter_type = get_byte(f);
  462. s->interlace_type = get_byte(f);
  463. crc = get_be32(f);
  464. s->state |= PNG_IHDR;
  465. #ifdef DEBUG
  466. printf("width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
  467. s->width, s->height, s->bit_depth, s->color_type,
  468. s->compression_type, s->filter_type, s->interlace_type);
  469. #endif
  470. break;
  471. case MKTAG('I', 'D', 'A', 'T'):
  472. if (!(s->state & PNG_IHDR))
  473. goto fail;
  474. if (!(s->state & PNG_IDAT)) {
  475. /* init image info */
  476. info->width = s->width;
  477. info->height = s->height;
  478. info->interleaved = (s->interlace_type != 0);
  479. s->channels = png_get_nb_channels(s->color_type);
  480. s->bits_per_pixel = s->bit_depth * s->channels;
  481. s->bpp = (s->bits_per_pixel + 7) >> 3;
  482. s->row_size = (info->width * s->bits_per_pixel + 7) >> 3;
  483. if (s->bit_depth == 8 &&
  484. s->color_type == PNG_COLOR_TYPE_RGB) {
  485. info->pix_fmt = PIX_FMT_RGB24;
  486. } else if (s->bit_depth == 8 &&
  487. s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
  488. info->pix_fmt = PIX_FMT_RGBA32;
  489. } else if (s->bit_depth == 8 &&
  490. s->color_type == PNG_COLOR_TYPE_GRAY) {
  491. info->pix_fmt = PIX_FMT_GRAY8;
  492. } else if (s->bit_depth == 1 &&
  493. s->color_type == PNG_COLOR_TYPE_GRAY) {
  494. info->pix_fmt = PIX_FMT_MONOBLACK;
  495. } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
  496. info->pix_fmt = PIX_FMT_PAL8;
  497. } else {
  498. goto fail;
  499. }
  500. ret = alloc_cb(opaque, info);
  501. if (ret)
  502. goto the_end;
  503. /* compute the compressed row size */
  504. if (!s->interlace_type) {
  505. s->crow_size = s->row_size + 1;
  506. } else {
  507. s->pass = 0;
  508. s->pass_row_size = png_pass_row_size(s->pass,
  509. s->bits_per_pixel,
  510. s->width);
  511. s->crow_size = s->pass_row_size + 1;
  512. }
  513. #ifdef DEBUG
  514. printf("row_size=%d crow_size =%d\n",
  515. s->row_size, s->crow_size);
  516. #endif
  517. s->image_buf = info->pict.data[0];
  518. s->image_linesize = info->pict.linesize[0];
  519. /* copy the palette if needed */
  520. if (s->color_type == PNG_COLOR_TYPE_PALETTE)
  521. memcpy(info->pict.data[1], s->palette, 256 * sizeof(uint32_t));
  522. /* empty row is used if differencing to the first row */
  523. s->last_row = av_mallocz(s->row_size);
  524. if (!s->last_row)
  525. goto fail;
  526. if (s->interlace_type ||
  527. s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
  528. s->tmp_row = av_malloc(s->row_size);
  529. if (!s->tmp_row)
  530. goto fail;
  531. }
  532. /* compressed row */
  533. s->crow_buf = av_malloc(s->row_size + 1);
  534. if (!s->crow_buf)
  535. goto fail;
  536. s->zstream.avail_out = s->crow_size;
  537. s->zstream.next_out = s->crow_buf;
  538. }
  539. s->state |= PNG_IDAT;
  540. if (png_decode_idat(s, f, length) < 0)
  541. goto fail;
  542. /* skip crc */
  543. crc = get_be32(f);
  544. break;
  545. case MKTAG('P', 'L', 'T', 'E'):
  546. {
  547. int n, i, r, g, b;
  548. if ((length % 3) != 0 || length > 256 * 3)
  549. goto skip_tag;
  550. /* read the palette */
  551. n = length / 3;
  552. for(i=0;i<n;i++) {
  553. r = get_byte(f);
  554. g = get_byte(f);
  555. b = get_byte(f);
  556. s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
  557. }
  558. for(;i<256;i++) {
  559. s->palette[i] = (0xff << 24);
  560. }
  561. s->state |= PNG_PLTE;
  562. crc = get_be32(f);
  563. }
  564. break;
  565. case MKTAG('t', 'R', 'N', 'S'):
  566. {
  567. int v, i;
  568. /* read the transparency. XXX: Only palette mode supported */
  569. if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
  570. length > 256 ||
  571. !(s->state & PNG_PLTE))
  572. goto skip_tag;
  573. for(i=0;i<length;i++) {
  574. v = get_byte(f);
  575. s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
  576. }
  577. crc = get_be32(f);
  578. }
  579. break;
  580. case MKTAG('I', 'E', 'N', 'D'):
  581. if (!(s->state & PNG_ALLIMAGE))
  582. goto fail;
  583. crc = get_be32(f);
  584. goto exit_loop;
  585. default:
  586. /* skip tag */
  587. skip_tag:
  588. url_fskip(f, length + 4);
  589. break;
  590. }
  591. }
  592. exit_loop:
  593. ret = 0;
  594. the_end:
  595. inflateEnd(&s->zstream);
  596. av_free(s->crow_buf);
  597. av_free(s->last_row);
  598. av_free(s->tmp_row);
  599. return ret;
  600. fail:
  601. ret = -1;
  602. goto the_end;
  603. }
  604. static void png_write_chunk(ByteIOContext *f, uint32_t tag,
  605. const uint8_t *buf, int length)
  606. {
  607. uint32_t crc;
  608. uint8_t tagbuf[4];
  609. put_be32(f, length);
  610. crc = crc32(0, Z_NULL, 0);
  611. tagbuf[0] = tag;
  612. tagbuf[1] = tag >> 8;
  613. tagbuf[2] = tag >> 16;
  614. tagbuf[3] = tag >> 24;
  615. crc = crc32(crc, tagbuf, 4);
  616. put_le32(f, tag);
  617. if (length > 0) {
  618. crc = crc32(crc, buf, length);
  619. put_buffer(f, buf, length);
  620. }
  621. put_be32(f, crc);
  622. }
  623. /* XXX: use avcodec generic function ? */
  624. static void to_be32(uint8_t *p, uint32_t v)
  625. {
  626. p[0] = v >> 24;
  627. p[1] = v >> 16;
  628. p[2] = v >> 8;
  629. p[3] = v;
  630. }
  631. typedef struct PNGEncodeState {
  632. ByteIOContext *f;
  633. z_stream zstream;
  634. uint8_t buf[IOBUF_SIZE];
  635. } PNGEncodeState;
  636. /* XXX: do filtering */
  637. static int png_write_row(PNGEncodeState *s, const uint8_t *data, int size)
  638. {
  639. int ret;
  640. s->zstream.avail_in = size;
  641. s->zstream.next_in = (uint8_t *)data;
  642. while (s->zstream.avail_in > 0) {
  643. ret = deflate(&s->zstream, Z_NO_FLUSH);
  644. if (ret != Z_OK)
  645. return -1;
  646. if (s->zstream.avail_out == 0) {
  647. png_write_chunk(s->f, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE);
  648. s->zstream.avail_out = IOBUF_SIZE;
  649. s->zstream.next_out = s->buf;
  650. }
  651. }
  652. return 0;
  653. }
  654. static int png_write(ByteIOContext *f, AVImageInfo *info)
  655. {
  656. PNGEncodeState s1, *s = &s1;
  657. int bit_depth, color_type, y, len, row_size, ret, is_progressive;
  658. int bits_per_pixel, pass_row_size;
  659. uint8_t *ptr;
  660. uint8_t *crow_buf = NULL;
  661. uint8_t *tmp_buf = NULL;
  662. s->f = f;
  663. is_progressive = info->interleaved;
  664. switch(info->pix_fmt) {
  665. case PIX_FMT_RGBA32:
  666. bit_depth = 8;
  667. color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  668. break;
  669. case PIX_FMT_RGB24:
  670. bit_depth = 8;
  671. color_type = PNG_COLOR_TYPE_RGB;
  672. break;
  673. case PIX_FMT_GRAY8:
  674. bit_depth = 8;
  675. color_type = PNG_COLOR_TYPE_GRAY;
  676. break;
  677. case PIX_FMT_MONOBLACK:
  678. bit_depth = 1;
  679. color_type = PNG_COLOR_TYPE_GRAY;
  680. break;
  681. case PIX_FMT_PAL8:
  682. bit_depth = 8;
  683. color_type = PNG_COLOR_TYPE_PALETTE;
  684. break;
  685. default:
  686. return -1;
  687. }
  688. bits_per_pixel = png_get_nb_channels(color_type) * bit_depth;
  689. row_size = (info->width * bits_per_pixel + 7) >> 3;
  690. s->zstream.zalloc = png_zalloc;
  691. s->zstream.zfree = png_zfree;
  692. s->zstream.opaque = NULL;
  693. ret = deflateInit2(&s->zstream, Z_DEFAULT_COMPRESSION,
  694. Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
  695. if (ret != Z_OK)
  696. return -1;
  697. crow_buf = av_malloc(row_size + 1);
  698. if (!crow_buf)
  699. goto fail;
  700. if (is_progressive) {
  701. tmp_buf = av_malloc(row_size + 1);
  702. if (!tmp_buf)
  703. goto fail;
  704. }
  705. /* write png header */
  706. put_buffer(f, pngsig, 8);
  707. to_be32(s->buf, info->width);
  708. to_be32(s->buf + 4, info->height);
  709. s->buf[8] = bit_depth;
  710. s->buf[9] = color_type;
  711. s->buf[10] = 0; /* compression type */
  712. s->buf[11] = 0; /* filter type */
  713. s->buf[12] = is_progressive; /* interlace type */
  714. png_write_chunk(f, MKTAG('I', 'H', 'D', 'R'), s->buf, 13);
  715. /* put the palette if needed */
  716. if (color_type == PNG_COLOR_TYPE_PALETTE) {
  717. int has_alpha, alpha, i;
  718. unsigned int v;
  719. uint32_t *palette;
  720. uint8_t *alpha_ptr;
  721. palette = (uint32_t *)info->pict.data[1];
  722. ptr = s->buf;
  723. alpha_ptr = s->buf + 256 * 3;
  724. has_alpha = 0;
  725. for(i = 0; i < 256; i++) {
  726. v = palette[i];
  727. alpha = v >> 24;
  728. if (alpha != 0xff)
  729. has_alpha = 1;
  730. *alpha_ptr++ = alpha;
  731. ptr[0] = v >> 16;
  732. ptr[1] = v >> 8;
  733. ptr[2] = v;
  734. ptr += 3;
  735. }
  736. png_write_chunk(f, MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3);
  737. if (has_alpha) {
  738. png_write_chunk(f, MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256);
  739. }
  740. }
  741. /* now put each row */
  742. s->zstream.avail_out = IOBUF_SIZE;
  743. s->zstream.next_out = s->buf;
  744. if (is_progressive) {
  745. uint8_t *ptr1;
  746. int pass;
  747. for(pass = 0; pass < NB_PASSES; pass++) {
  748. /* NOTE: a pass is completely omited if no pixels would be
  749. output */
  750. pass_row_size = png_pass_row_size(pass, bits_per_pixel, info->width);
  751. if (pass_row_size > 0) {
  752. for(y = 0; y < info->height; y++) {
  753. if ((png_pass_ymask[pass] << (y & 7)) & 0x80) {
  754. ptr = info->pict.data[0] + y * info->pict.linesize[0];
  755. if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
  756. convert_from_rgba32(tmp_buf, ptr, info->width);
  757. ptr1 = tmp_buf;
  758. } else {
  759. ptr1 = ptr;
  760. }
  761. png_get_interlaced_row(crow_buf + 1, pass_row_size,
  762. bits_per_pixel, pass,
  763. ptr1, info->width);
  764. crow_buf[0] = PNG_FILTER_VALUE_NONE;
  765. png_write_row(s, crow_buf, pass_row_size + 1);
  766. }
  767. }
  768. }
  769. }
  770. } else {
  771. for(y = 0; y < info->height; y++) {
  772. ptr = info->pict.data[0] + y * info->pict.linesize[0];
  773. if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  774. convert_from_rgba32(crow_buf + 1, ptr, info->width);
  775. else
  776. memcpy(crow_buf + 1, ptr, row_size);
  777. crow_buf[0] = PNG_FILTER_VALUE_NONE;
  778. png_write_row(s, crow_buf, row_size + 1);
  779. }
  780. }
  781. /* compress last bytes */
  782. for(;;) {
  783. ret = deflate(&s->zstream, Z_FINISH);
  784. if (ret == Z_OK || ret == Z_STREAM_END) {
  785. len = IOBUF_SIZE - s->zstream.avail_out;
  786. if (len > 0) {
  787. png_write_chunk(f, MKTAG('I', 'D', 'A', 'T'), s->buf, len);
  788. }
  789. s->zstream.avail_out = IOBUF_SIZE;
  790. s->zstream.next_out = s->buf;
  791. if (ret == Z_STREAM_END)
  792. break;
  793. } else {
  794. goto fail;
  795. }
  796. }
  797. png_write_chunk(f, MKTAG('I', 'E', 'N', 'D'), NULL, 0);
  798. put_flush_packet(f);
  799. ret = 0;
  800. the_end:
  801. av_free(crow_buf);
  802. av_free(tmp_buf);
  803. deflateEnd(&s->zstream);
  804. return ret;
  805. fail:
  806. ret = -1;
  807. goto the_end;
  808. }
  809. AVImageFormat png_image_format = {
  810. "png",
  811. "png",
  812. png_probe,
  813. png_read,
  814. (1 << PIX_FMT_RGBA32) | (1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) |
  815. (1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
  816. png_write,
  817. AVIMAGE_INTERLEAVED,
  818. };
  819. #endif