FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pngenc.c
Go to the documentation of this file.
1 /*
2  * PNG image format
3  * Copyright (c) 2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "avcodec.h"
23 #include "internal.h"
24 #include "bytestream.h"
25 #include "huffyuvencdsp.h"
26 #include "png.h"
27 #include "apng.h"
28 
29 #include "libavutil/avassert.h"
30 #include "libavutil/crc.h"
31 #include "libavutil/libm.h"
32 #include "libavutil/opt.h"
33 #include "libavutil/color_utils.h"
34 
35 #include <zlib.h>
36 
37 #define IOBUF_SIZE 4096
38 
39 typedef struct PNGEncContext {
40  AVClass *class;
42 
46 
48 
49  z_stream zstream;
51  int dpi; ///< Physical pixel density, in dots per inch, if set
52  int dpm; ///< Physical pixel density, in dots per meter, if set
53 
55  int bit_depth;
58 
59  // APNG
60  uint32_t palette_checksum; // Used to ensure a single unique palette
61  uint32_t sequence_number;
63 
64 static void png_get_interlaced_row(uint8_t *dst, int row_size,
65  int bits_per_pixel, int pass,
66  const uint8_t *src, int width)
67 {
68  int x, mask, dst_x, j, b, bpp;
69  uint8_t *d;
70  const uint8_t *s;
71  static const int masks[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
72 
73  mask = masks[pass];
74  switch (bits_per_pixel) {
75  case 1:
76  memset(dst, 0, row_size);
77  dst_x = 0;
78  for (x = 0; x < width; x++) {
79  j = (x & 7);
80  if ((mask << j) & 0x80) {
81  b = (src[x >> 3] >> (7 - j)) & 1;
82  dst[dst_x >> 3] |= b << (7 - (dst_x & 7));
83  dst_x++;
84  }
85  }
86  break;
87  default:
88  bpp = bits_per_pixel >> 3;
89  d = dst;
90  s = src;
91  for (x = 0; x < width; x++) {
92  j = x & 7;
93  if ((mask << j) & 0x80) {
94  memcpy(d, s, bpp);
95  d += bpp;
96  }
97  s += bpp;
98  }
99  break;
100  }
101 }
102 
104  int w, int bpp)
105 {
106  int i;
107  for (i = 0; i < w; i++) {
108  int a, b, c, p, pa, pb, pc;
109 
110  a = src[i - bpp];
111  b = top[i];
112  c = top[i - bpp];
113 
114  p = b - c;
115  pc = a - c;
116 
117  pa = abs(p);
118  pb = abs(pc);
119  pc = abs(p + pc);
120 
121  if (pa <= pb && pa <= pc)
122  p = a;
123  else if (pb <= pc)
124  p = b;
125  else
126  p = c;
127  dst[i] = src[i] - p;
128  }
129 }
130 
131 static void sub_left_prediction(PNGEncContext *c, uint8_t *dst, const uint8_t *src, int bpp, int size)
132 {
133  const uint8_t *src1 = src + bpp;
134  const uint8_t *src2 = src;
135  int x, unaligned_w;
136 
137  memcpy(dst, src, bpp);
138  dst += bpp;
139  size -= bpp;
140  unaligned_w = FFMIN(32 - bpp, size);
141  for (x = 0; x < unaligned_w; x++)
142  *dst++ = *src1++ - *src2++;
143  size -= unaligned_w;
144  c->hdsp.diff_bytes(dst, src1, src2, size);
145 }
146 
147 static void png_filter_row(PNGEncContext *c, uint8_t *dst, int filter_type,
148  uint8_t *src, uint8_t *top, int size, int bpp)
149 {
150  int i;
151 
152  switch (filter_type) {
154  memcpy(dst, src, size);
155  break;
157  sub_left_prediction(c, dst, src, bpp, size);
158  break;
159  case PNG_FILTER_VALUE_UP:
160  c->hdsp.diff_bytes(dst, src, top, size);
161  break;
163  for (i = 0; i < bpp; i++)
164  dst[i] = src[i] - (top[i] >> 1);
165  for (; i < size; i++)
166  dst[i] = src[i] - ((src[i - bpp] + top[i]) >> 1);
167  break;
169  for (i = 0; i < bpp; i++)
170  dst[i] = src[i] - top[i];
171  sub_png_paeth_prediction(dst + i, src + i, top + i, size - i, bpp);
172  break;
173  }
174 }
175 
177  uint8_t *src, uint8_t *top, int size, int bpp)
178 {
179  int pred = s->filter_type;
180  av_assert0(bpp || !pred);
181  if (!top && pred)
182  pred = PNG_FILTER_VALUE_SUB;
183  if (pred == PNG_FILTER_VALUE_MIXED) {
184  int i;
185  int cost, bcost = INT_MAX;
186  uint8_t *buf1 = dst, *buf2 = dst + size + 16;
187  for (pred = 0; pred < 5; pred++) {
188  png_filter_row(s, buf1 + 1, pred, src, top, size, bpp);
189  buf1[0] = pred;
190  cost = 0;
191  for (i = 0; i <= size; i++)
192  cost += abs((int8_t) buf1[i]);
193  if (cost < bcost) {
194  bcost = cost;
195  FFSWAP(uint8_t *, buf1, buf2);
196  }
197  }
198  return buf2;
199  } else {
200  png_filter_row(s, dst + 1, pred, src, top, size, bpp);
201  dst[0] = pred;
202  return dst;
203  }
204 }
205 
206 static void png_write_chunk(uint8_t **f, uint32_t tag,
207  const uint8_t *buf, int length)
208 {
209  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
210  uint32_t crc = ~0U;
211  uint8_t tagbuf[4];
212 
213  bytestream_put_be32(f, length);
214  AV_WL32(tagbuf, tag);
215  crc = av_crc(crc_table, crc, tagbuf, 4);
216  bytestream_put_be32(f, av_bswap32(tag));
217  if (length > 0) {
218  crc = av_crc(crc_table, crc, buf, length);
219  memcpy(*f, buf, length);
220  *f += length;
221  }
222  bytestream_put_be32(f, ~crc);
223 }
224 
226  const uint8_t *buf, int length)
227 {
228  PNGEncContext *s = avctx->priv_data;
229  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
230  uint32_t crc = ~0U;
231 
232  if (avctx->codec_id == AV_CODEC_ID_PNG || avctx->frame_number == 0) {
233  png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), buf, length);
234  return;
235  }
236 
237  bytestream_put_be32(&s->bytestream, length + 4);
238 
239  bytestream_put_be32(&s->bytestream, MKBETAG('f', 'd', 'A', 'T'));
240  bytestream_put_be32(&s->bytestream, s->sequence_number);
241  crc = av_crc(crc_table, crc, s->bytestream - 8, 8);
242 
243  crc = av_crc(crc_table, crc, buf, length);
244  memcpy(s->bytestream, buf, length);
245  s->bytestream += length;
246 
247  bytestream_put_be32(&s->bytestream, ~crc);
248 
249  ++s->sequence_number;
250 }
251 
252 /* XXX: do filtering */
253 static int png_write_row(AVCodecContext *avctx, const uint8_t *data, int size)
254 {
255  PNGEncContext *s = avctx->priv_data;
256  int ret;
257 
258  s->zstream.avail_in = size;
259  s->zstream.next_in = data;
260  while (s->zstream.avail_in > 0) {
261  ret = deflate(&s->zstream, Z_NO_FLUSH);
262  if (ret != Z_OK)
263  return -1;
264  if (s->zstream.avail_out == 0) {
265  if (s->bytestream_end - s->bytestream > IOBUF_SIZE + 100)
266  png_write_image_data(avctx, s->buf, IOBUF_SIZE);
267  s->zstream.avail_out = IOBUF_SIZE;
268  s->zstream.next_out = s->buf;
269  }
270  }
271  return 0;
272 }
273 
274 #define AV_WB32_PNG(buf, n) AV_WB32(buf, lrint((n) * 100000))
275 static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf)
276 {
277  double rx, ry, gx, gy, bx, by, wx = 0.3127, wy = 0.3290;
278  switch (prim) {
279  case AVCOL_PRI_BT709:
280  rx = 0.640; ry = 0.330;
281  gx = 0.300; gy = 0.600;
282  bx = 0.150; by = 0.060;
283  break;
284  case AVCOL_PRI_BT470M:
285  rx = 0.670; ry = 0.330;
286  gx = 0.210; gy = 0.710;
287  bx = 0.140; by = 0.080;
288  wx = 0.310; wy = 0.316;
289  break;
290  case AVCOL_PRI_BT470BG:
291  rx = 0.640; ry = 0.330;
292  gx = 0.290; gy = 0.600;
293  bx = 0.150; by = 0.060;
294  break;
295  case AVCOL_PRI_SMPTE170M:
296  case AVCOL_PRI_SMPTE240M:
297  rx = 0.630; ry = 0.340;
298  gx = 0.310; gy = 0.595;
299  bx = 0.155; by = 0.070;
300  break;
301  case AVCOL_PRI_BT2020:
302  rx = 0.708; ry = 0.292;
303  gx = 0.170; gy = 0.797;
304  bx = 0.131; by = 0.046;
305  break;
306  default:
307  return 0;
308  }
309 
310  AV_WB32_PNG(buf , wx); AV_WB32_PNG(buf + 4 , wy);
311  AV_WB32_PNG(buf + 8 , rx); AV_WB32_PNG(buf + 12, ry);
312  AV_WB32_PNG(buf + 16, gx); AV_WB32_PNG(buf + 20, gy);
313  AV_WB32_PNG(buf + 24, bx); AV_WB32_PNG(buf + 28, by);
314  return 1;
315 }
316 
318 {
319  double gamma = avpriv_get_gamma_from_trc(trc);
320  if (gamma <= 1e-6)
321  return 0;
322 
323  AV_WB32_PNG(buf, 1.0 / gamma);
324  return 1;
325 }
326 
327 static int encode_headers(AVCodecContext *avctx, const AVFrame *pict)
328 {
329  PNGEncContext *s = avctx->priv_data;
330 
331  /* write png header */
332  AV_WB32(s->buf, avctx->width);
333  AV_WB32(s->buf + 4, avctx->height);
334  s->buf[8] = s->bit_depth;
335  s->buf[9] = s->color_type;
336  s->buf[10] = 0; /* compression type */
337  s->buf[11] = 0; /* filter type */
338  s->buf[12] = s->is_progressive; /* interlace type */
339  png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13);
340 
341  /* write physical information */
342  if (s->dpm) {
343  AV_WB32(s->buf, s->dpm);
344  AV_WB32(s->buf + 4, s->dpm);
345  s->buf[8] = 1; /* unit specifier is meter */
346  } else {
347  AV_WB32(s->buf, avctx->sample_aspect_ratio.num);
348  AV_WB32(s->buf + 4, avctx->sample_aspect_ratio.den);
349  s->buf[8] = 0; /* unit specifier is unknown */
350  }
351  png_write_chunk(&s->bytestream, MKTAG('p', 'H', 'Y', 's'), s->buf, 9);
352 
353  /* write colorspace information */
354  if (pict->color_primaries == AVCOL_PRI_BT709 &&
356  s->buf[0] = 1; /* rendering intent, relative colorimetric by default */
357  png_write_chunk(&s->bytestream, MKTAG('s', 'R', 'G', 'B'), s->buf, 1);
358  }
359 
360  if (png_get_chrm(pict->color_primaries, s->buf))
361  png_write_chunk(&s->bytestream, MKTAG('c', 'H', 'R', 'M'), s->buf, 32);
362  if (png_get_gama(pict->color_trc, s->buf))
363  png_write_chunk(&s->bytestream, MKTAG('g', 'A', 'M', 'A'), s->buf, 4);
364 
365  /* put the palette if needed */
367  int has_alpha, alpha, i;
368  unsigned int v;
369  uint32_t *palette;
370  uint8_t *ptr, *alpha_ptr;
371 
372  palette = (uint32_t *)pict->data[1];
373  ptr = s->buf;
374  alpha_ptr = s->buf + 256 * 3;
375  has_alpha = 0;
376  for (i = 0; i < 256; i++) {
377  v = palette[i];
378  alpha = v >> 24;
379  if (alpha != 0xff)
380  has_alpha = 1;
381  *alpha_ptr++ = alpha;
382  bytestream_put_be24(&ptr, v);
383  }
385  MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3);
386  if (has_alpha) {
388  MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256);
389  }
390  }
391 
392  return 0;
393 }
394 
395 static int encode_frame(AVCodecContext *avctx, const AVFrame *pict)
396 {
397  PNGEncContext *s = avctx->priv_data;
398  const AVFrame *const p = pict;
399  int y, len, ret;
400  int row_size, pass_row_size;
401  uint8_t *ptr, *top, *crow_buf, *crow;
402  uint8_t *crow_base = NULL;
403  uint8_t *progressive_buf = NULL;
404  uint8_t *top_buf = NULL;
405 
406  row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
407 
408  crow_base = av_malloc((row_size + 32) << (s->filter_type == PNG_FILTER_VALUE_MIXED));
409  if (!crow_base) {
410  ret = AVERROR(ENOMEM);
411  goto the_end;
412  }
413  // pixel data should be aligned, but there's a control byte before it
414  crow_buf = crow_base + 15;
415  if (s->is_progressive) {
416  progressive_buf = av_malloc(row_size + 1);
417  top_buf = av_malloc(row_size + 1);
418  if (!progressive_buf || !top_buf) {
419  ret = AVERROR(ENOMEM);
420  goto the_end;
421  }
422  }
423 
424  /* put each row */
425  s->zstream.avail_out = IOBUF_SIZE;
426  s->zstream.next_out = s->buf;
427  if (s->is_progressive) {
428  int pass;
429 
430  for (pass = 0; pass < NB_PASSES; pass++) {
431  /* NOTE: a pass is completely omitted if no pixels would be
432  * output */
433  pass_row_size = ff_png_pass_row_size(pass, s->bits_per_pixel, avctx->width);
434  if (pass_row_size > 0) {
435  top = NULL;
436  for (y = 0; y < avctx->height; y++)
437  if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) {
438  ptr = p->data[0] + y * p->linesize[0];
439  FFSWAP(uint8_t *, progressive_buf, top_buf);
440  png_get_interlaced_row(progressive_buf, pass_row_size,
441  s->bits_per_pixel, pass,
442  ptr, avctx->width);
443  crow = png_choose_filter(s, crow_buf, progressive_buf,
444  top, pass_row_size, s->bits_per_pixel >> 3);
445  png_write_row(avctx, crow, pass_row_size + 1);
446  top = progressive_buf;
447  }
448  }
449  }
450  } else {
451  top = NULL;
452  for (y = 0; y < avctx->height; y++) {
453  ptr = p->data[0] + y * p->linesize[0];
454  crow = png_choose_filter(s, crow_buf, ptr, top,
455  row_size, s->bits_per_pixel >> 3);
456  png_write_row(avctx, crow, row_size + 1);
457  top = ptr;
458  }
459  }
460  /* compress last bytes */
461  for (;;) {
462  ret = deflate(&s->zstream, Z_FINISH);
463  if (ret == Z_OK || ret == Z_STREAM_END) {
464  len = IOBUF_SIZE - s->zstream.avail_out;
465  if (len > 0 && s->bytestream_end - s->bytestream > len + 100) {
466  png_write_image_data(avctx, s->buf, len);
467  }
468  s->zstream.avail_out = IOBUF_SIZE;
469  s->zstream.next_out = s->buf;
470  if (ret == Z_STREAM_END)
471  break;
472  } else {
473  ret = -1;
474  goto the_end;
475  }
476  }
477 
478  ret = 0;
479 
480 the_end:
481  av_freep(&crow_base);
482  av_freep(&progressive_buf);
483  av_freep(&top_buf);
484  deflateReset(&s->zstream);
485  return ret;
486 }
487 
488 static int encode_png(AVCodecContext *avctx, AVPacket *pkt,
489  const AVFrame *pict, int *got_packet)
490 {
491  PNGEncContext *s = avctx->priv_data;
492  int ret;
493  int enc_row_size;
494  size_t max_packet_size;
495 
496  enc_row_size = deflateBound(&s->zstream, (avctx->width * s->bits_per_pixel + 7) >> 3);
497  max_packet_size =
498  AV_INPUT_BUFFER_MIN_SIZE + // headers
499  avctx->height * (
500  enc_row_size +
501  12 * (((int64_t)enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) // IDAT * ceil(enc_row_size / IOBUF_SIZE)
502  );
503  if (max_packet_size > INT_MAX)
504  return AVERROR(ENOMEM);
505  ret = ff_alloc_packet2(avctx, pkt, max_packet_size, 0);
506  if (ret < 0)
507  return ret;
508 
509  s->bytestream_start =
510  s->bytestream = pkt->data;
511  s->bytestream_end = pkt->data + pkt->size;
512 
514  s->bytestream += 8;
515 
516  ret = encode_headers(avctx, pict);
517  if (ret < 0)
518  return ret;
519 
520  ret = encode_frame(avctx, pict);
521  if (ret < 0)
522  return ret;
523 
524  png_write_chunk(&s->bytestream, MKTAG('I', 'E', 'N', 'D'), NULL, 0);
525 
526  pkt->size = s->bytestream - s->bytestream_start;
527  pkt->flags |= AV_PKT_FLAG_KEY;
528  *got_packet = 1;
529 
530  return 0;
531 }
532 
534  const AVFrame *pict, int *got_packet)
535 {
536  PNGEncContext *s = avctx->priv_data;
537  int ret;
538  int enc_row_size;
539  size_t max_packet_size;
540  uint8_t buf[26];
541 
543  uint32_t checksum = ~av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), ~0U, pict->data[1], 256 * sizeof(uint32_t));
544 
545  if (avctx->frame_number == 0) {
546  s->palette_checksum = checksum;
547  } else if (checksum != s->palette_checksum) {
548  av_log(avctx, AV_LOG_ERROR,
549  "Input contains more than one unique palette. APNG does not support multiple palettes.\n");
550  return -1;
551  }
552  }
553 
554  enc_row_size = deflateBound(&s->zstream, (avctx->width * s->bits_per_pixel + 7) >> 3);
555  max_packet_size =
556  AV_INPUT_BUFFER_MIN_SIZE + // headers
557  avctx->height * (
558  enc_row_size +
559  (4 + 12) * (((int64_t)enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) // fdAT * ceil(enc_row_size / IOBUF_SIZE)
560  );
561  if (max_packet_size > INT_MAX)
562  return AVERROR(ENOMEM);
563  ret = ff_alloc_packet2(avctx, pkt, max_packet_size, 0);
564  if (ret < 0)
565  return ret;
566 
567  s->bytestream_start =
568  s->bytestream = pkt->data;
569  s->bytestream_end = pkt->data + pkt->size;
570 
571  if (avctx->frame_number == 0) {
572  ret = encode_headers(avctx, pict);
573  if (ret < 0)
574  return ret;
575 
577  if (!avctx->extradata)
578  return AVERROR(ENOMEM);
579  avctx->extradata_size = s->bytestream - s->bytestream_start;
580  memcpy(avctx->extradata, s->bytestream_start, s->bytestream - s->bytestream_start);
581 
583  }
584 
585  AV_WB32(buf, s->sequence_number);
586  AV_WB32(buf + 4, avctx->width);
587  AV_WB32(buf + 8, avctx->height);
588  AV_WB32(buf + 12, 0); // x offset
589  AV_WB32(buf + 16, 0); // y offset
590  AV_WB16(buf + 20, 0); // delay numerator (filled in during muxing)
591  AV_WB16(buf + 22, 0); // delay denominator
592  buf[24] = APNG_DISPOSE_OP_BACKGROUND;
593  buf[25] = APNG_BLEND_OP_SOURCE;
594  png_write_chunk(&s->bytestream, MKTAG('f', 'c', 'T', 'L'), buf, 26);
595  ++s->sequence_number;
596 
597  ret = encode_frame(avctx, pict);
598  if (ret < 0)
599  return ret;
600 
601  pkt->size = s->bytestream - s->bytestream_start;
602  pkt->flags |= AV_PKT_FLAG_KEY;
603  *got_packet = 1;
604 
605  return 0;
606 }
607 
609 {
610  PNGEncContext *s = avctx->priv_data;
611  int compression_level;
612 
613  switch (avctx->pix_fmt) {
614  case AV_PIX_FMT_RGBA:
615  avctx->bits_per_coded_sample = 32;
616  break;
617  case AV_PIX_FMT_RGB24:
618  avctx->bits_per_coded_sample = 24;
619  break;
620  case AV_PIX_FMT_GRAY8:
621  avctx->bits_per_coded_sample = 0x28;
622  break;
624  avctx->bits_per_coded_sample = 1;
625  break;
626  case AV_PIX_FMT_PAL8:
627  avctx->bits_per_coded_sample = 8;
628  }
629 
630 #if FF_API_CODED_FRAME
633  avctx->coded_frame->key_frame = 1;
635 #endif
636 
638 
639  s->filter_type = av_clip(avctx->prediction_method,
642  if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK)
644 
645  if (s->dpi && s->dpm) {
646  av_log(avctx, AV_LOG_ERROR, "Only one of 'dpi' or 'dpm' options should be set\n");
647  return AVERROR(EINVAL);
648  } else if (s->dpi) {
649  s->dpm = s->dpi * 10000 / 254;
650  }
651 
653  switch (avctx->pix_fmt) {
654  case AV_PIX_FMT_RGBA64BE:
655  s->bit_depth = 16;
657  break;
658  case AV_PIX_FMT_RGB48BE:
659  s->bit_depth = 16;
661  break;
662  case AV_PIX_FMT_RGBA:
663  s->bit_depth = 8;
665  break;
666  case AV_PIX_FMT_RGB24:
667  s->bit_depth = 8;
669  break;
670  case AV_PIX_FMT_GRAY16BE:
671  s->bit_depth = 16;
673  break;
674  case AV_PIX_FMT_GRAY8:
675  s->bit_depth = 8;
677  break;
678  case AV_PIX_FMT_GRAY8A:
679  s->bit_depth = 8;
681  break;
682  case AV_PIX_FMT_YA16BE:
683  s->bit_depth = 16;
685  break;
687  s->bit_depth = 1;
689  break;
690  case AV_PIX_FMT_PAL8:
691  s->bit_depth = 8;
693  break;
694  default:
695  return -1;
696  }
698 
699  s->zstream.zalloc = ff_png_zalloc;
700  s->zstream.zfree = ff_png_zfree;
701  s->zstream.opaque = NULL;
702  compression_level = avctx->compression_level == FF_COMPRESSION_DEFAULT
703  ? Z_DEFAULT_COMPRESSION
704  : av_clip(avctx->compression_level, 0, 9);
705  if (deflateInit2(&s->zstream, compression_level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY) != Z_OK)
706  return -1;
707 
708  return 0;
709 }
710 
712 {
713  PNGEncContext *s = avctx->priv_data;
714 
715  deflateEnd(&s->zstream);
716  return 0;
717 }
718 
719 #define OFFSET(x) offsetof(PNGEncContext, x)
720 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
721 static const AVOption options[] = {
722  {"dpi", "Set image resolution (in dots per inch)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE},
723  {"dpm", "Set image resolution (in dots per meter)", OFFSET(dpm), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE},
724  { NULL }
725 };
726 
727 static const AVClass pngenc_class = {
728  .class_name = "PNG encoder",
729  .item_name = av_default_item_name,
730  .option = options,
731  .version = LIBAVUTIL_VERSION_INT,
732 };
733 
734 static const AVClass apngenc_class = {
735  .class_name = "APNG encoder",
736  .item_name = av_default_item_name,
737  .option = options,
738  .version = LIBAVUTIL_VERSION_INT,
739 };
740 
742  .name = "png",
743  .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
744  .type = AVMEDIA_TYPE_VIDEO,
745  .id = AV_CODEC_ID_PNG,
746  .priv_data_size = sizeof(PNGEncContext),
747  .init = png_enc_init,
748  .close = png_enc_close,
749  .encode2 = encode_png,
751  .pix_fmts = (const enum AVPixelFormat[]) {
758  },
759  .priv_class = &pngenc_class,
760 };
761 
763  .name = "apng",
764  .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"),
765  .type = AVMEDIA_TYPE_VIDEO,
766  .id = AV_CODEC_ID_APNG,
767  .priv_data_size = sizeof(PNGEncContext),
768  .init = png_enc_init,
769  .close = png_enc_close,
770  .encode2 = encode_apng,
771  .pix_fmts = (const enum AVPixelFormat[]) {
778  },
779  .priv_class = &apngenc_class,
780 };
static void png_filter_row(PNGEncContext *c, uint8_t *dst, int filter_type, uint8_t *src, uint8_t *top, int size, int bpp)
Definition: pngenc.c:147
#define PNG_FILTER_VALUE_AVG
Definition: png.h:41
#define NULL
Definition: coverity.c:32
float v
const char * s
Definition: avisynth_c.h:631
#define FF_COMPRESSION_DEFAULT
Definition: avcodec.h:1589
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
BYTE int const BYTE int int row_size
Definition: avisynth_c.h:676
AVOption.
Definition: opt.h:255
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition: avcodec.h:775
static uint8_t * png_choose_filter(PNGEncContext *s, uint8_t *dst, uint8_t *src, uint8_t *top, int size, int bpp)
Definition: pngenc.c:176
#define LIBAVUTIL_VERSION_INT
Definition: version.h:62
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:65
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static const AVClass apngenc_class
Definition: pngenc.c:734
uint8_t * bytestream
Definition: pngenc.c:43
int num
numerator
Definition: rational.h:44
int size
Definition: avcodec.h:1423
const char * b
Definition: vf_curves.c:109
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
Definition: avcodec.h:1901
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1721
static int encode_png(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: pngenc.c:488
int color_type
Definition: pngenc.c:56
static AVPacket pkt
#define PNG_COLOR_TYPE_RGB
Definition: png.h:33
static const AVClass pngenc_class
Definition: pngenc.c:727
int bit_depth
Definition: pngenc.c:55
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:35
AVCodec.
Definition: avcodec.h:3473
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:32
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:482
#define OFFSET(x)
Definition: pngenc.c:719
av_cold void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c)
Definition: huffyuvencdsp.c:77
#define AV_CODEC_CAP_INTRA_ONLY
Codec is intra only.
Definition: avcodec.h:939
int filter_type
Definition: pngenc.c:47
#define PNG_FILTER_VALUE_PAETH
Definition: png.h:42
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
double avpriv_get_gamma_from_trc(enum AVColorTransferCharacteristic trc)
Determine a suitable 'gamma' value to match the supplied AVColorTransferCharacteristic.
Definition: color_utils.c:24
int bits_per_pixel
Definition: pngenc.c:57
uint8_t
#define av_cold
Definition: attributes.h:74
#define av_malloc(s)
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:34
8 bit with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:74
AVOptions.
HuffYUVEncDSPContext hdsp
Definition: pngenc.c:41
static void sub_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
Definition: pngenc.c:103
static void deflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord)
Definition: vf_neighbor.c:115
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:259
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1616
uint8_t * data
Definition: avcodec.h:1422
uint32_t tag
Definition: movenc.c:1333
ptrdiff_t size
Definition: opengl_enc.c:101
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2997
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:464
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
#define AV_INPUT_BUFFER_MIN_SIZE
minimum encoding buffer size Used to avoid some checks during header writing.
Definition: avcodec.h:642
#define av_log(a,...)
#define PNG_FILTER_VALUE_MIXED
Definition: png.h:43
int is_progressive
Definition: pngenc.c:54
AVCodec ff_apng_encoder
Definition: pngenc.c:762
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1468
#define U(x)
Definition: vp56_arith.h:37
uint32_t palette_checksum
Definition: pngenc.c:60
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:469
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:99
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint32_t sequence_number
Definition: pngenc.c:61
16bit gray, 16bit alpha (big-endian)
Definition: pixfmt.h:234
static void png_get_interlaced_row(uint8_t *dst, int row_size, int bits_per_pixel, int pass, const uint8_t *src, int width)
Definition: pngenc.c:64
static const uint16_t mask[17]
Definition: lzw.c:38
z_stream zstream
Definition: pngenc.c:49
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
void(* diff_bytes)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w)
Definition: huffyuvencdsp.h:25
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
int dpm
Physical pixel density, in dots per meter, if set.
Definition: pngenc.c:52
int ff_png_get_nb_channels(int color_type)
Definition: png.c:49
#define AV_WB32_PNG(buf, n)
Definition: pngenc.c:274
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1596
#define PNGSIG
Definition: png.h:52
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
Definition: pixfmt.h:466
simple assert() macros that are a bit more flexible than ISO C assert().
static int encode_headers(AVCodecContext *avctx, const AVFrame *pict)
Definition: pngenc.c:327
GLsizei GLsizei * length
Definition: opengl_enc.c:115
const char * name
Name of the codec implementation.
Definition: avcodec.h:3480
Libavcodec external API header.
#define NB_PASSES
Definition: png.h:50
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:919
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:95
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1428
#define pass
Definition: fft_template.c:509
uint8_t * bytestream_start
Definition: pngenc.c:44
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:242
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:146
#define FFMIN(a, b)
Definition: common.h:66
#define PNG_FILTER_VALUE_SUB
Definition: png.h:39
float y
static void png_write_chunk(uint8_t **f, uint32_t tag, const uint8_t *buf, int length)
Definition: pngenc.c:206
#define PNG_COLOR_TYPE_GRAY
Definition: png.h:31
ret
Definition: avfilter.c:974
int width
picture width / height.
Definition: avcodec.h:1680
static const AVOption options[]
Definition: pngenc.c:721
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:471
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition: crc.c:356
static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: pngenc.c:533
static const float pred[4]
Definition: siprdata.h:259
static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
Definition: pngenc.c:317
#define IOBUF_SIZE
Definition: pngenc.c:37
#define src1
Definition: h264pred.c:139
#define av_bswap32
Definition: bswap.h:33
AVCodec ff_png_encoder
Definition: pngenc.c:741
AVS_Value src
Definition: avisynth_c.h:482
functionally identical to above
Definition: pixfmt.h:473
enum AVCodecID codec_id
Definition: avcodec.h:1518
int compression_level
Definition: avcodec.h:1588
#define PNG_FILTER_VALUE_UP
Definition: png.h:40
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:199
static void png_write_image_data(AVCodecContext *avctx, const uint8_t *buf, int length)
Definition: pngenc.c:225
main external API structure.
Definition: avcodec.h:1501
void * buf
Definition: avisynth_c.h:553
const uint8_t ff_png_pass_ymask[NB_PASSES]
Definition: png.c:25
int extradata_size
Definition: avcodec.h:1617
Replacements for frequently missing libm functions.
Describe the class of an AVClass context structure.
Definition: log.h:67
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
Y , 16bpp, big-endian.
Definition: pixfmt.h:99
int dpi
Physical pixel density, in dots per inch, if set.
Definition: pngenc.c:51
#define VE
Definition: pngenc.c:720
static av_cold int png_enc_init(AVCodecContext *avctx)
Definition: pngenc.c:608
uint8_t * bytestream_end
Definition: pngenc.c:45
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: utils.c:1780
static int encode_frame(AVCodecContext *avctx, const AVFrame *pict)
Definition: pngenc.c:395
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:209
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition: crc.c:342
uint8_t buf[IOBUF_SIZE]
Definition: pngenc.c:50
int palette
Definition: v4l.c:60
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:73
static int png_write_row(AVCodecContext *avctx, const uint8_t *data, int size)
Definition: pngenc.c:253
Y , 8bpp.
Definition: pixfmt.h:71
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:496
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:79
common internal api header.
#define PNG_FILTER_VALUE_NONE
Definition: png.h:38
static double c[64]
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:111
int prediction_method
prediction method (needed for huffyuv)
Definition: avcodec.h:1882
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:3025
int den
denominator
Definition: rational.h:45
void ff_png_zfree(void *opaque, void *ptr)
Definition: png.c:44
#define MKBETAG(a, b, c, d)
Definition: common.h:316
void * priv_data
Definition: avcodec.h:1543
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:80
int len
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:237
APNG common header.
static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf)
Definition: pngenc.c:275
enum AVColorPrimaries color_primaries
Definition: frame.h:493
int ff_png_pass_row_size(int pass, int bits_per_pixel, int width)
Definition: png.c:62
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:472
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2292
ITU-R BT2020.
Definition: pixfmt.h:475
#define av_freep(p)
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:495
static av_cold int png_enc_close(AVCodecContext *avctx)
Definition: pngenc.c:711
#define FFSWAP(type, a, b)
Definition: common.h:69
#define MKTAG(a, b, c, d)
Definition: common.h:315
void * ff_png_zalloc(void *opaque, unsigned int items, unsigned int size)
Definition: png.c:39
AVPixelFormat
Pixel format.
Definition: pixfmt.h:61
This structure stores compressed data.
Definition: avcodec.h:1399
uint32_t AVCRC
Definition: crc.h:34
for(j=16;j >0;--j)
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
static void sub_left_prediction(PNGEncContext *c, uint8_t *dst, const uint8_t *src, int bpp, int size)
Definition: pngenc.c:131
static int width