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 #include "libavutil/stereo3d.h"
35 
36 #include <zlib.h>
37 
38 #define IOBUF_SIZE 4096
39 
40 typedef struct APNGFctlChunk {
41  uint32_t sequence_number;
42  uint32_t width, height;
43  uint32_t x_offset, y_offset;
44  uint16_t delay_num, delay_den;
47 
48 typedef struct PNGEncContext {
49  AVClass *class;
51 
55 
57 
58  z_stream zstream;
60  int dpi; ///< Physical pixel density, in dots per inch, if set
61  int dpm; ///< Physical pixel density, in dots per meter, if set
62 
64  int bit_depth;
67 
68  // APNG
69  uint32_t palette_checksum; // Used to ensure a single unique palette
70  uint32_t sequence_number;
71 
78 
79 static void png_get_interlaced_row(uint8_t *dst, int row_size,
80  int bits_per_pixel, int pass,
81  const uint8_t *src, int width)
82 {
83  int x, mask, dst_x, j, b, bpp;
84  uint8_t *d;
85  const uint8_t *s;
86  static const int masks[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
87 
88  mask = masks[pass];
89  switch (bits_per_pixel) {
90  case 1:
91  memset(dst, 0, row_size);
92  dst_x = 0;
93  for (x = 0; x < width; x++) {
94  j = (x & 7);
95  if ((mask << j) & 0x80) {
96  b = (src[x >> 3] >> (7 - j)) & 1;
97  dst[dst_x >> 3] |= b << (7 - (dst_x & 7));
98  dst_x++;
99  }
100  }
101  break;
102  default:
103  bpp = bits_per_pixel >> 3;
104  d = dst;
105  s = src;
106  for (x = 0; x < width; x++) {
107  j = x & 7;
108  if ((mask << j) & 0x80) {
109  memcpy(d, s, bpp);
110  d += bpp;
111  }
112  s += bpp;
113  }
114  break;
115  }
116 }
117 
119  int w, int bpp)
120 {
121  int i;
122  for (i = 0; i < w; i++) {
123  int a, b, c, p, pa, pb, pc;
124 
125  a = src[i - bpp];
126  b = top[i];
127  c = top[i - bpp];
128 
129  p = b - c;
130  pc = a - c;
131 
132  pa = abs(p);
133  pb = abs(pc);
134  pc = abs(p + pc);
135 
136  if (pa <= pb && pa <= pc)
137  p = a;
138  else if (pb <= pc)
139  p = b;
140  else
141  p = c;
142  dst[i] = src[i] - p;
143  }
144 }
145 
146 static void sub_left_prediction(PNGEncContext *c, uint8_t *dst, const uint8_t *src, int bpp, int size)
147 {
148  const uint8_t *src1 = src + bpp;
149  const uint8_t *src2 = src;
150  int x, unaligned_w;
151 
152  memcpy(dst, src, bpp);
153  dst += bpp;
154  size -= bpp;
155  unaligned_w = FFMIN(32 - bpp, size);
156  for (x = 0; x < unaligned_w; x++)
157  *dst++ = *src1++ - *src2++;
158  size -= unaligned_w;
159  c->hdsp.diff_bytes(dst, src1, src2, size);
160 }
161 
162 static void png_filter_row(PNGEncContext *c, uint8_t *dst, int filter_type,
163  uint8_t *src, uint8_t *top, int size, int bpp)
164 {
165  int i;
166 
167  switch (filter_type) {
169  memcpy(dst, src, size);
170  break;
172  sub_left_prediction(c, dst, src, bpp, size);
173  break;
174  case PNG_FILTER_VALUE_UP:
175  c->hdsp.diff_bytes(dst, src, top, size);
176  break;
178  for (i = 0; i < bpp; i++)
179  dst[i] = src[i] - (top[i] >> 1);
180  for (; i < size; i++)
181  dst[i] = src[i] - ((src[i - bpp] + top[i]) >> 1);
182  break;
184  for (i = 0; i < bpp; i++)
185  dst[i] = src[i] - top[i];
186  sub_png_paeth_prediction(dst + i, src + i, top + i, size - i, bpp);
187  break;
188  }
189 }
190 
192  uint8_t *src, uint8_t *top, int size, int bpp)
193 {
194  int pred = s->filter_type;
195  av_assert0(bpp || !pred);
196  if (!top && pred)
197  pred = PNG_FILTER_VALUE_SUB;
198  if (pred == PNG_FILTER_VALUE_MIXED) {
199  int i;
200  int cost, bcost = INT_MAX;
201  uint8_t *buf1 = dst, *buf2 = dst + size + 16;
202  for (pred = 0; pred < 5; pred++) {
203  png_filter_row(s, buf1 + 1, pred, src, top, size, bpp);
204  buf1[0] = pred;
205  cost = 0;
206  for (i = 0; i <= size; i++)
207  cost += abs((int8_t) buf1[i]);
208  if (cost < bcost) {
209  bcost = cost;
210  FFSWAP(uint8_t *, buf1, buf2);
211  }
212  }
213  return buf2;
214  } else {
215  png_filter_row(s, dst + 1, pred, src, top, size, bpp);
216  dst[0] = pred;
217  return dst;
218  }
219 }
220 
221 static void png_write_chunk(uint8_t **f, uint32_t tag,
222  const uint8_t *buf, int length)
223 {
224  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
225  uint32_t crc = ~0U;
226  uint8_t tagbuf[4];
227 
228  bytestream_put_be32(f, length);
229  AV_WL32(tagbuf, tag);
230  crc = av_crc(crc_table, crc, tagbuf, 4);
231  bytestream_put_be32(f, av_bswap32(tag));
232  if (length > 0) {
233  crc = av_crc(crc_table, crc, buf, length);
234  memcpy(*f, buf, length);
235  *f += length;
236  }
237  bytestream_put_be32(f, ~crc);
238 }
239 
241  const uint8_t *buf, int length)
242 {
243  PNGEncContext *s = avctx->priv_data;
244  const AVCRC *crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
245  uint32_t crc = ~0U;
246 
247  if (avctx->codec_id == AV_CODEC_ID_PNG || avctx->frame_number == 0) {
248  png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), buf, length);
249  return;
250  }
251 
252  bytestream_put_be32(&s->bytestream, length + 4);
253 
254  bytestream_put_be32(&s->bytestream, MKBETAG('f', 'd', 'A', 'T'));
255  bytestream_put_be32(&s->bytestream, s->sequence_number);
256  crc = av_crc(crc_table, crc, s->bytestream - 8, 8);
257 
258  crc = av_crc(crc_table, crc, buf, length);
259  memcpy(s->bytestream, buf, length);
260  s->bytestream += length;
261 
262  bytestream_put_be32(&s->bytestream, ~crc);
263 
264  ++s->sequence_number;
265 }
266 
267 /* XXX: do filtering */
268 static int png_write_row(AVCodecContext *avctx, const uint8_t *data, int size)
269 {
270  PNGEncContext *s = avctx->priv_data;
271  int ret;
272 
273  s->zstream.avail_in = size;
274  s->zstream.next_in = data;
275  while (s->zstream.avail_in > 0) {
276  ret = deflate(&s->zstream, Z_NO_FLUSH);
277  if (ret != Z_OK)
278  return -1;
279  if (s->zstream.avail_out == 0) {
280  if (s->bytestream_end - s->bytestream > IOBUF_SIZE + 100)
281  png_write_image_data(avctx, s->buf, IOBUF_SIZE);
282  s->zstream.avail_out = IOBUF_SIZE;
283  s->zstream.next_out = s->buf;
284  }
285  }
286  return 0;
287 }
288 
289 #define AV_WB32_PNG(buf, n) AV_WB32(buf, lrint((n) * 100000))
290 static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf)
291 {
292  double rx, ry, gx, gy, bx, by, wx = 0.3127, wy = 0.3290;
293  switch (prim) {
294  case AVCOL_PRI_BT709:
295  rx = 0.640; ry = 0.330;
296  gx = 0.300; gy = 0.600;
297  bx = 0.150; by = 0.060;
298  break;
299  case AVCOL_PRI_BT470M:
300  rx = 0.670; ry = 0.330;
301  gx = 0.210; gy = 0.710;
302  bx = 0.140; by = 0.080;
303  wx = 0.310; wy = 0.316;
304  break;
305  case AVCOL_PRI_BT470BG:
306  rx = 0.640; ry = 0.330;
307  gx = 0.290; gy = 0.600;
308  bx = 0.150; by = 0.060;
309  break;
310  case AVCOL_PRI_SMPTE170M:
311  case AVCOL_PRI_SMPTE240M:
312  rx = 0.630; ry = 0.340;
313  gx = 0.310; gy = 0.595;
314  bx = 0.155; by = 0.070;
315  break;
316  case AVCOL_PRI_BT2020:
317  rx = 0.708; ry = 0.292;
318  gx = 0.170; gy = 0.797;
319  bx = 0.131; by = 0.046;
320  break;
321  default:
322  return 0;
323  }
324 
325  AV_WB32_PNG(buf , wx); AV_WB32_PNG(buf + 4 , wy);
326  AV_WB32_PNG(buf + 8 , rx); AV_WB32_PNG(buf + 12, ry);
327  AV_WB32_PNG(buf + 16, gx); AV_WB32_PNG(buf + 20, gy);
328  AV_WB32_PNG(buf + 24, bx); AV_WB32_PNG(buf + 28, by);
329  return 1;
330 }
331 
333 {
334  double gamma = avpriv_get_gamma_from_trc(trc);
335  if (gamma <= 1e-6)
336  return 0;
337 
338  AV_WB32_PNG(buf, 1.0 / gamma);
339  return 1;
340 }
341 
342 static int encode_headers(AVCodecContext *avctx, const AVFrame *pict)
343 {
344  AVFrameSideData *side_data;
345  PNGEncContext *s = avctx->priv_data;
346 
347  /* write png header */
348  AV_WB32(s->buf, avctx->width);
349  AV_WB32(s->buf + 4, avctx->height);
350  s->buf[8] = s->bit_depth;
351  s->buf[9] = s->color_type;
352  s->buf[10] = 0; /* compression type */
353  s->buf[11] = 0; /* filter type */
354  s->buf[12] = s->is_progressive; /* interlace type */
355  png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13);
356 
357  /* write physical information */
358  if (s->dpm) {
359  AV_WB32(s->buf, s->dpm);
360  AV_WB32(s->buf + 4, s->dpm);
361  s->buf[8] = 1; /* unit specifier is meter */
362  } else {
363  AV_WB32(s->buf, avctx->sample_aspect_ratio.num);
364  AV_WB32(s->buf + 4, avctx->sample_aspect_ratio.den);
365  s->buf[8] = 0; /* unit specifier is unknown */
366  }
367  png_write_chunk(&s->bytestream, MKTAG('p', 'H', 'Y', 's'), s->buf, 9);
368 
369  /* write stereoscopic information */
371  if (side_data) {
372  AVStereo3D *stereo3d = (AVStereo3D *)side_data->data;
373  switch (stereo3d->type) {
375  s->buf[0] = ((stereo3d->flags & AV_STEREO3D_FLAG_INVERT) == 0) ? 1 : 0;
376  png_write_chunk(&s->bytestream, MKTAG('s', 'T', 'E', 'R'), s->buf, 1);
377  break;
378  case AV_STEREO3D_2D:
379  break;
380  default:
381  av_log(avctx, AV_LOG_WARNING, "Only side-by-side stereo3d flag can be defined within sTER chunk\n");
382  break;
383  }
384  }
385 
386  /* write colorspace information */
387  if (pict->color_primaries == AVCOL_PRI_BT709 &&
389  s->buf[0] = 1; /* rendering intent, relative colorimetric by default */
390  png_write_chunk(&s->bytestream, MKTAG('s', 'R', 'G', 'B'), s->buf, 1);
391  }
392 
393  if (png_get_chrm(pict->color_primaries, s->buf))
394  png_write_chunk(&s->bytestream, MKTAG('c', 'H', 'R', 'M'), s->buf, 32);
395  if (png_get_gama(pict->color_trc, s->buf))
396  png_write_chunk(&s->bytestream, MKTAG('g', 'A', 'M', 'A'), s->buf, 4);
397 
398  /* put the palette if needed */
400  int has_alpha, alpha, i;
401  unsigned int v;
402  uint32_t *palette;
403  uint8_t *ptr, *alpha_ptr;
404 
405  palette = (uint32_t *)pict->data[1];
406  ptr = s->buf;
407  alpha_ptr = s->buf + 256 * 3;
408  has_alpha = 0;
409  for (i = 0; i < 256; i++) {
410  v = palette[i];
411  alpha = v >> 24;
412  if (alpha != 0xff)
413  has_alpha = 1;
414  *alpha_ptr++ = alpha;
415  bytestream_put_be24(&ptr, v);
416  }
418  MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3);
419  if (has_alpha) {
421  MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256);
422  }
423  }
424 
425  return 0;
426 }
427 
428 static int encode_frame(AVCodecContext *avctx, const AVFrame *pict)
429 {
430  PNGEncContext *s = avctx->priv_data;
431  const AVFrame *const p = pict;
432  int y, len, ret;
433  int row_size, pass_row_size;
434  uint8_t *ptr, *top, *crow_buf, *crow;
435  uint8_t *crow_base = NULL;
436  uint8_t *progressive_buf = NULL;
437  uint8_t *top_buf = NULL;
438 
439  row_size = (pict->width * s->bits_per_pixel + 7) >> 3;
440 
441  crow_base = av_malloc((row_size + 32) << (s->filter_type == PNG_FILTER_VALUE_MIXED));
442  if (!crow_base) {
443  ret = AVERROR(ENOMEM);
444  goto the_end;
445  }
446  // pixel data should be aligned, but there's a control byte before it
447  crow_buf = crow_base + 15;
448  if (s->is_progressive) {
449  progressive_buf = av_malloc(row_size + 1);
450  top_buf = av_malloc(row_size + 1);
451  if (!progressive_buf || !top_buf) {
452  ret = AVERROR(ENOMEM);
453  goto the_end;
454  }
455  }
456 
457  /* put each row */
458  s->zstream.avail_out = IOBUF_SIZE;
459  s->zstream.next_out = s->buf;
460  if (s->is_progressive) {
461  int pass;
462 
463  for (pass = 0; pass < NB_PASSES; pass++) {
464  /* NOTE: a pass is completely omitted if no pixels would be
465  * output */
466  pass_row_size = ff_png_pass_row_size(pass, s->bits_per_pixel, pict->width);
467  if (pass_row_size > 0) {
468  top = NULL;
469  for (y = 0; y < pict->height; y++)
470  if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) {
471  ptr = p->data[0] + y * p->linesize[0];
472  FFSWAP(uint8_t *, progressive_buf, top_buf);
473  png_get_interlaced_row(progressive_buf, pass_row_size,
474  s->bits_per_pixel, pass,
475  ptr, pict->width);
476  crow = png_choose_filter(s, crow_buf, progressive_buf,
477  top, pass_row_size, s->bits_per_pixel >> 3);
478  png_write_row(avctx, crow, pass_row_size + 1);
479  top = progressive_buf;
480  }
481  }
482  }
483  } else {
484  top = NULL;
485  for (y = 0; y < pict->height; y++) {
486  ptr = p->data[0] + y * p->linesize[0];
487  crow = png_choose_filter(s, crow_buf, ptr, top,
488  row_size, s->bits_per_pixel >> 3);
489  png_write_row(avctx, crow, row_size + 1);
490  top = ptr;
491  }
492  }
493  /* compress last bytes */
494  for (;;) {
495  ret = deflate(&s->zstream, Z_FINISH);
496  if (ret == Z_OK || ret == Z_STREAM_END) {
497  len = IOBUF_SIZE - s->zstream.avail_out;
498  if (len > 0 && s->bytestream_end - s->bytestream > len + 100) {
499  png_write_image_data(avctx, s->buf, len);
500  }
501  s->zstream.avail_out = IOBUF_SIZE;
502  s->zstream.next_out = s->buf;
503  if (ret == Z_STREAM_END)
504  break;
505  } else {
506  ret = -1;
507  goto the_end;
508  }
509  }
510 
511  ret = 0;
512 
513 the_end:
514  av_freep(&crow_base);
515  av_freep(&progressive_buf);
516  av_freep(&top_buf);
517  deflateReset(&s->zstream);
518  return ret;
519 }
520 
521 static int encode_png(AVCodecContext *avctx, AVPacket *pkt,
522  const AVFrame *pict, int *got_packet)
523 {
524  PNGEncContext *s = avctx->priv_data;
525  int ret;
526  int enc_row_size;
527  size_t max_packet_size;
528 
529  enc_row_size = deflateBound(&s->zstream, (avctx->width * s->bits_per_pixel + 7) >> 3);
530  max_packet_size =
531  AV_INPUT_BUFFER_MIN_SIZE + // headers
532  avctx->height * (
533  enc_row_size +
534  12 * (((int64_t)enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) // IDAT * ceil(enc_row_size / IOBUF_SIZE)
535  );
536  if (max_packet_size > INT_MAX)
537  return AVERROR(ENOMEM);
538  ret = ff_alloc_packet2(avctx, pkt, max_packet_size, 0);
539  if (ret < 0)
540  return ret;
541 
542  s->bytestream_start =
543  s->bytestream = pkt->data;
544  s->bytestream_end = pkt->data + pkt->size;
545 
547  s->bytestream += 8;
548 
549  ret = encode_headers(avctx, pict);
550  if (ret < 0)
551  return ret;
552 
553  ret = encode_frame(avctx, pict);
554  if (ret < 0)
555  return ret;
556 
557  png_write_chunk(&s->bytestream, MKTAG('I', 'E', 'N', 'D'), NULL, 0);
558 
559  pkt->size = s->bytestream - s->bytestream_start;
560  pkt->flags |= AV_PKT_FLAG_KEY;
561  *got_packet = 1;
562 
563  return 0;
564 }
565 
566 static int apng_do_inverse_blend(AVFrame *output, const AVFrame *input,
567  APNGFctlChunk *fctl_chunk, uint8_t bpp)
568 {
569  // output: background, input: foreground
570  // output the image such that when blended with the background, will produce the foreground
571 
572  unsigned int x, y;
573  unsigned int leftmost_x = input->width;
574  unsigned int rightmost_x = 0;
575  unsigned int topmost_y = input->height;
576  unsigned int bottommost_y = 0;
577  const uint8_t *input_data = input->data[0];
578  uint8_t *output_data = output->data[0];
579  ptrdiff_t input_linesize = input->linesize[0];
580  ptrdiff_t output_linesize = output->linesize[0];
581 
582  // Find bounding box of changes
583  for (y = 0; y < input->height; ++y) {
584  for (x = 0; x < input->width; ++x) {
585  if (!memcmp(input_data + bpp * x, output_data + bpp * x, bpp))
586  continue;
587 
588  if (x < leftmost_x)
589  leftmost_x = x;
590  if (x >= rightmost_x)
591  rightmost_x = x + 1;
592  if (y < topmost_y)
593  topmost_y = y;
594  if (y >= bottommost_y)
595  bottommost_y = y + 1;
596  }
597 
598  input_data += input_linesize;
599  output_data += output_linesize;
600  }
601 
602  if (leftmost_x == input->width && rightmost_x == 0) {
603  // Empty frame
604  // APNG does not support empty frames, so we make it a 1x1 frame
605  leftmost_x = topmost_y = 0;
606  rightmost_x = bottommost_y = 1;
607  }
608 
609  // Do actual inverse blending
610  if (fctl_chunk->blend_op == APNG_BLEND_OP_SOURCE) {
611  output_data = output->data[0];
612  for (y = topmost_y; y < bottommost_y; ++y) {
613  memcpy(output_data,
614  input->data[0] + input_linesize * y + bpp * leftmost_x,
615  bpp * (rightmost_x - leftmost_x));
616  output_data += output_linesize;
617  }
618  } else { // APNG_BLEND_OP_OVER
619  size_t transparent_palette_index;
620  uint32_t *palette;
621 
622  switch (input->format) {
623  case AV_PIX_FMT_RGBA64BE:
624  case AV_PIX_FMT_YA16BE:
625  case AV_PIX_FMT_RGBA:
626  case AV_PIX_FMT_GRAY8A:
627  break;
628 
629  case AV_PIX_FMT_PAL8:
630  palette = (uint32_t*)input->data[1];
631  for (transparent_palette_index = 0; transparent_palette_index < 256; ++transparent_palette_index)
632  if (palette[transparent_palette_index] >> 24 == 0)
633  break;
634  break;
635 
636  default:
637  // No alpha, so blending not possible
638  return -1;
639  }
640 
641  for (y = topmost_y; y < bottommost_y; ++y) {
642  uint8_t *foreground = input->data[0] + input_linesize * y + bpp * leftmost_x;
643  uint8_t *background = output->data[0] + output_linesize * y + bpp * leftmost_x;
644  output_data = output->data[0] + output_linesize * (y - topmost_y);
645  for (x = leftmost_x; x < rightmost_x; ++x, foreground += bpp, background += bpp, output_data += bpp) {
646  if (!memcmp(foreground, background, bpp)) {
647  if (input->format == AV_PIX_FMT_PAL8) {
648  if (transparent_palette_index == 256) {
649  // Need fully transparent colour, but none exists
650  return -1;
651  }
652 
653  *output_data = transparent_palette_index;
654  } else {
655  memset(output_data, 0, bpp);
656  }
657  continue;
658  }
659 
660  // Check for special alpha values, since full inverse
661  // alpha-on-alpha blending is rarely possible, and when
662  // possible, doesn't compress much better than
663  // APNG_BLEND_OP_SOURCE blending
664  switch (input->format) {
665  case AV_PIX_FMT_RGBA64BE:
666  if (((uint16_t*)foreground)[3] == 0xffff ||
667  ((uint16_t*)background)[3] == 0)
668  break;
669  return -1;
670 
671  case AV_PIX_FMT_YA16BE:
672  if (((uint16_t*)foreground)[1] == 0xffff ||
673  ((uint16_t*)background)[1] == 0)
674  break;
675  return -1;
676 
677  case AV_PIX_FMT_RGBA:
678  if (foreground[3] == 0xff || background[3] == 0)
679  break;
680  return -1;
681 
682  case AV_PIX_FMT_GRAY8A:
683  if (foreground[1] == 0xff || background[1] == 0)
684  break;
685  return -1;
686 
687  case AV_PIX_FMT_PAL8:
688  if (palette[*foreground] >> 24 == 0xff ||
689  palette[*background] >> 24 == 0)
690  break;
691  return -1;
692  }
693 
694  memmove(output_data, foreground, bpp);
695  }
696  }
697  }
698 
699  output->width = rightmost_x - leftmost_x;
700  output->height = bottommost_y - topmost_y;
701  fctl_chunk->width = output->width;
702  fctl_chunk->height = output->height;
703  fctl_chunk->x_offset = leftmost_x;
704  fctl_chunk->y_offset = topmost_y;
705 
706  return 0;
707 }
708 
709 static int apng_encode_frame(AVCodecContext *avctx, const AVFrame *pict,
710  APNGFctlChunk *best_fctl_chunk, APNGFctlChunk *best_last_fctl_chunk)
711 {
712  PNGEncContext *s = avctx->priv_data;
713  int ret;
714  unsigned int y;
715  AVFrame* diffFrame;
716  uint8_t bpp = (s->bits_per_pixel + 7) >> 3;
717  uint8_t *original_bytestream, *original_bytestream_end;
718  uint8_t *temp_bytestream = 0, *temp_bytestream_end;
719  uint32_t best_sequence_number;
720  uint8_t *best_bytestream;
721  size_t best_bytestream_size = SIZE_MAX;
722  APNGFctlChunk last_fctl_chunk = *best_last_fctl_chunk;
723  APNGFctlChunk fctl_chunk = *best_fctl_chunk;
724 
725  if (avctx->frame_number == 0) {
726  best_fctl_chunk->width = pict->width;
727  best_fctl_chunk->height = pict->height;
728  best_fctl_chunk->x_offset = 0;
729  best_fctl_chunk->y_offset = 0;
730  best_fctl_chunk->blend_op = APNG_BLEND_OP_SOURCE;
731  return encode_frame(avctx, pict);
732  }
733 
734  diffFrame = av_frame_alloc();
735  if (!diffFrame)
736  return AVERROR(ENOMEM);
737 
738  diffFrame->format = pict->format;
739  diffFrame->width = pict->width;
740  diffFrame->height = pict->height;
741  if ((ret = av_frame_get_buffer(diffFrame, 32)) < 0)
742  goto fail;
743 
744  original_bytestream = s->bytestream;
745  original_bytestream_end = s->bytestream_end;
746 
747  temp_bytestream = av_malloc(original_bytestream_end - original_bytestream);
748  temp_bytestream_end = temp_bytestream + (original_bytestream_end - original_bytestream);
749  if (!temp_bytestream) {
750  ret = AVERROR(ENOMEM);
751  goto fail;
752  }
753 
754  for (last_fctl_chunk.dispose_op = 0; last_fctl_chunk.dispose_op < 3; ++last_fctl_chunk.dispose_op) {
755  // 0: APNG_DISPOSE_OP_NONE
756  // 1: APNG_DISPOSE_OP_BACKGROUND
757  // 2: APNG_DISPOSE_OP_PREVIOUS
758 
759  for (fctl_chunk.blend_op = 0; fctl_chunk.blend_op < 2; ++fctl_chunk.blend_op) {
760  // 0: APNG_BLEND_OP_SOURCE
761  // 1: APNG_BLEND_OP_OVER
762 
763  uint32_t original_sequence_number = s->sequence_number, sequence_number;
764  uint8_t *bytestream_start = s->bytestream;
765  size_t bytestream_size;
766 
767  // Do disposal
768  if (last_fctl_chunk.dispose_op != APNG_DISPOSE_OP_PREVIOUS) {
769  diffFrame->width = pict->width;
770  diffFrame->height = pict->height;
771  ret = av_frame_copy(diffFrame, s->last_frame);
772  if (ret < 0)
773  goto fail;
774 
775  if (last_fctl_chunk.dispose_op == APNG_DISPOSE_OP_BACKGROUND) {
776  for (y = last_fctl_chunk.y_offset; y < last_fctl_chunk.y_offset + last_fctl_chunk.height; ++y) {
777  size_t row_start = diffFrame->linesize[0] * y + bpp * last_fctl_chunk.x_offset;
778  memset(diffFrame->data[0] + row_start, 0, bpp * last_fctl_chunk.width);
779  }
780  }
781  } else {
782  if (!s->prev_frame)
783  continue;
784 
785  diffFrame->width = pict->width;
786  diffFrame->height = pict->height;
787  ret = av_frame_copy(diffFrame, s->prev_frame);
788  if (ret < 0)
789  goto fail;
790  }
791 
792  // Do inverse blending
793  if (apng_do_inverse_blend(diffFrame, pict, &fctl_chunk, bpp) < 0)
794  continue;
795 
796  // Do encoding
797  ret = encode_frame(avctx, diffFrame);
798  sequence_number = s->sequence_number;
799  s->sequence_number = original_sequence_number;
800  bytestream_size = s->bytestream - bytestream_start;
801  s->bytestream = bytestream_start;
802  if (ret < 0)
803  goto fail;
804 
805  if (bytestream_size < best_bytestream_size) {
806  *best_fctl_chunk = fctl_chunk;
807  *best_last_fctl_chunk = last_fctl_chunk;
808 
809  best_sequence_number = sequence_number;
810  best_bytestream = s->bytestream;
811  best_bytestream_size = bytestream_size;
812 
813  if (best_bytestream == original_bytestream) {
814  s->bytestream = temp_bytestream;
815  s->bytestream_end = temp_bytestream_end;
816  } else {
817  s->bytestream = original_bytestream;
818  s->bytestream_end = original_bytestream_end;
819  }
820  }
821  }
822  }
823 
824  s->sequence_number = best_sequence_number;
825  s->bytestream = original_bytestream + best_bytestream_size;
826  s->bytestream_end = original_bytestream_end;
827  if (best_bytestream != original_bytestream)
828  memcpy(original_bytestream, best_bytestream, best_bytestream_size);
829 
830  ret = 0;
831 
832 fail:
833  av_freep(&temp_bytestream);
834  av_frame_free(&diffFrame);
835  return ret;
836 }
837 
839  const AVFrame *pict, int *got_packet)
840 {
841  PNGEncContext *s = avctx->priv_data;
842  int ret;
843  int enc_row_size;
844  size_t max_packet_size;
845  APNGFctlChunk fctl_chunk = {0};
846 
847  if (pict && avctx->codec_id == AV_CODEC_ID_APNG && s->color_type == PNG_COLOR_TYPE_PALETTE) {
848  uint32_t checksum = ~av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), ~0U, pict->data[1], 256 * sizeof(uint32_t));
849 
850  if (avctx->frame_number == 0) {
852  } else if (checksum != s->palette_checksum) {
853  av_log(avctx, AV_LOG_ERROR,
854  "Input contains more than one unique palette. APNG does not support multiple palettes.\n");
855  return -1;
856  }
857  }
858 
859  enc_row_size = deflateBound(&s->zstream, (avctx->width * s->bits_per_pixel + 7) >> 3);
860  max_packet_size =
861  AV_INPUT_BUFFER_MIN_SIZE + // headers
862  avctx->height * (
863  enc_row_size +
864  (4 + 12) * (((int64_t)enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) // fdAT * ceil(enc_row_size / IOBUF_SIZE)
865  );
866  if (max_packet_size > INT_MAX)
867  return AVERROR(ENOMEM);
868 
869  if (avctx->frame_number == 0) {
870  if (!pict)
871  return AVERROR(EINVAL);
872 
874  if (!avctx->extradata)
875  return AVERROR(ENOMEM);
876 
877  ret = encode_headers(avctx, pict);
878  if (ret < 0)
879  return ret;
880 
881  avctx->extradata_size = s->bytestream - avctx->extradata;
882 
883  s->last_frame_packet = av_malloc(max_packet_size);
884  if (!s->last_frame_packet)
885  return AVERROR(ENOMEM);
886  } else if (s->last_frame) {
887  ret = ff_alloc_packet2(avctx, pkt, max_packet_size, 0);
888  if (ret < 0)
889  return ret;
890 
891  memcpy(pkt->data, s->last_frame_packet, s->last_frame_packet_size);
892  pkt->size = s->last_frame_packet_size;
893  pkt->pts = pkt->dts = s->last_frame->pts;
894  }
895 
896  if (pict) {
897  s->bytestream_start =
899  s->bytestream_end = s->bytestream + max_packet_size;
900 
901  // We're encoding the frame first, so we have to do a bit of shuffling around
902  // to have the image data write to the correct place in the buffer
903  fctl_chunk.sequence_number = s->sequence_number;
904  ++s->sequence_number;
905  s->bytestream += 26 + 12;
906 
907  ret = apng_encode_frame(avctx, pict, &fctl_chunk, &s->last_frame_fctl);
908  if (ret < 0)
909  return ret;
910 
911  fctl_chunk.delay_num = 0; // delay filled in during muxing
912  fctl_chunk.delay_den = 0;
913  } else {
915  }
916 
917  if (s->last_frame) {
918  uint8_t* last_fctl_chunk_start = pkt->data;
919  uint8_t buf[26];
920 
922  AV_WB32(buf + 4, s->last_frame_fctl.width);
923  AV_WB32(buf + 8, s->last_frame_fctl.height);
924  AV_WB32(buf + 12, s->last_frame_fctl.x_offset);
925  AV_WB32(buf + 16, s->last_frame_fctl.y_offset);
926  AV_WB16(buf + 20, s->last_frame_fctl.delay_num);
927  AV_WB16(buf + 22, s->last_frame_fctl.delay_den);
928  buf[24] = s->last_frame_fctl.dispose_op;
929  buf[25] = s->last_frame_fctl.blend_op;
930  png_write_chunk(&last_fctl_chunk_start, MKTAG('f', 'c', 'T', 'L'), buf, 26);
931 
932  *got_packet = 1;
933  }
934 
935  if (pict) {
936  if (!s->last_frame) {
937  s->last_frame = av_frame_alloc();
938  if (!s->last_frame)
939  return AVERROR(ENOMEM);
941  if (!s->prev_frame) {
942  s->prev_frame = av_frame_alloc();
943  if (!s->prev_frame)
944  return AVERROR(ENOMEM);
945 
946  s->prev_frame->format = pict->format;
947  s->prev_frame->width = pict->width;
948  s->prev_frame->height = pict->height;
949  if ((ret = av_frame_get_buffer(s->prev_frame, 32)) < 0)
950  return ret;
951  }
952 
953  // Do disposal, but not blending
956  uint32_t y;
957  uint8_t bpp = (s->bits_per_pixel + 7) >> 3;
958  for (y = s->last_frame_fctl.y_offset; y < s->last_frame_fctl.y_offset + s->last_frame_fctl.height; ++y) {
959  size_t row_start = s->prev_frame->linesize[0] * y + bpp * s->last_frame_fctl.x_offset;
960  memset(s->prev_frame->data[0] + row_start, 0, bpp * s->last_frame_fctl.width);
961  }
962  }
963  }
964 
966  ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
967  if (ret < 0)
968  return ret;
969 
970  s->last_frame_fctl = fctl_chunk;
972  } else {
974  }
975 
976  return 0;
977 }
978 
980 {
981  PNGEncContext *s = avctx->priv_data;
982  int compression_level;
983 
984  switch (avctx->pix_fmt) {
985  case AV_PIX_FMT_RGBA:
986  avctx->bits_per_coded_sample = 32;
987  break;
988  case AV_PIX_FMT_RGB24:
989  avctx->bits_per_coded_sample = 24;
990  break;
991  case AV_PIX_FMT_GRAY8:
992  avctx->bits_per_coded_sample = 0x28;
993  break;
995  avctx->bits_per_coded_sample = 1;
996  break;
997  case AV_PIX_FMT_PAL8:
998  avctx->bits_per_coded_sample = 8;
999  }
1000 
1001 #if FF_API_CODED_FRAME
1004  avctx->coded_frame->key_frame = 1;
1006 #endif
1007 
1009 
1010 #if FF_API_PRIVATE_OPT
1012  if (avctx->prediction_method)
1013  s->filter_type = av_clip(avctx->prediction_method,
1017 #endif
1018 
1019  if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK)
1021 
1022  if (s->dpi && s->dpm) {
1023  av_log(avctx, AV_LOG_ERROR, "Only one of 'dpi' or 'dpm' options should be set\n");
1024  return AVERROR(EINVAL);
1025  } else if (s->dpi) {
1026  s->dpm = s->dpi * 10000 / 254;
1027  }
1028 
1030  switch (avctx->pix_fmt) {
1031  case AV_PIX_FMT_RGBA64BE:
1032  s->bit_depth = 16;
1034  break;
1035  case AV_PIX_FMT_RGB48BE:
1036  s->bit_depth = 16;
1038  break;
1039  case AV_PIX_FMT_RGBA:
1040  s->bit_depth = 8;
1042  break;
1043  case AV_PIX_FMT_RGB24:
1044  s->bit_depth = 8;
1046  break;
1047  case AV_PIX_FMT_GRAY16BE:
1048  s->bit_depth = 16;
1050  break;
1051  case AV_PIX_FMT_GRAY8:
1052  s->bit_depth = 8;
1054  break;
1055  case AV_PIX_FMT_GRAY8A:
1056  s->bit_depth = 8;
1058  break;
1059  case AV_PIX_FMT_YA16BE:
1060  s->bit_depth = 16;
1062  break;
1063  case AV_PIX_FMT_MONOBLACK:
1064  s->bit_depth = 1;
1066  break;
1067  case AV_PIX_FMT_PAL8:
1068  s->bit_depth = 8;
1070  break;
1071  default:
1072  return -1;
1073  }
1075 
1076  s->zstream.zalloc = ff_png_zalloc;
1077  s->zstream.zfree = ff_png_zfree;
1078  s->zstream.opaque = NULL;
1079  compression_level = avctx->compression_level == FF_COMPRESSION_DEFAULT
1080  ? Z_DEFAULT_COMPRESSION
1081  : av_clip(avctx->compression_level, 0, 9);
1082  if (deflateInit2(&s->zstream, compression_level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY) != Z_OK)
1083  return -1;
1084 
1085  return 0;
1086 }
1087 
1089 {
1090  PNGEncContext *s = avctx->priv_data;
1091 
1092  deflateEnd(&s->zstream);
1096  return 0;
1097 }
1098 
1099 #define OFFSET(x) offsetof(PNGEncContext, x)
1100 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1101 static const AVOption options[] = {
1102  {"dpi", "Set image resolution (in dots per inch)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE},
1103  {"dpm", "Set image resolution (in dots per meter)", OFFSET(dpm), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0x10000, VE},
1104  { "pred", "Prediction method", OFFSET(filter_type), AV_OPT_TYPE_INT, { .i64 = PNG_FILTER_VALUE_NONE }, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED, VE, "pred" },
1105  { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_NONE }, INT_MIN, INT_MAX, VE, "pred" },
1106  { "sub", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_SUB }, INT_MIN, INT_MAX, VE, "pred" },
1107  { "up", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_UP }, INT_MIN, INT_MAX, VE, "pred" },
1108  { "avg", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_AVG }, INT_MIN, INT_MAX, VE, "pred" },
1109  { "paeth", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_PAETH }, INT_MIN, INT_MAX, VE, "pred" },
1110  { "mixed", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PNG_FILTER_VALUE_MIXED }, INT_MIN, INT_MAX, VE, "pred" },
1111  { NULL},
1112 };
1113 
1114 static const AVClass pngenc_class = {
1115  .class_name = "PNG encoder",
1116  .item_name = av_default_item_name,
1117  .option = options,
1118  .version = LIBAVUTIL_VERSION_INT,
1119 };
1120 
1121 static const AVClass apngenc_class = {
1122  .class_name = "APNG encoder",
1123  .item_name = av_default_item_name,
1124  .option = options,
1125  .version = LIBAVUTIL_VERSION_INT,
1126 };
1127 
1129  .name = "png",
1130  .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
1131  .type = AVMEDIA_TYPE_VIDEO,
1132  .id = AV_CODEC_ID_PNG,
1133  .priv_data_size = sizeof(PNGEncContext),
1134  .init = png_enc_init,
1135  .close = png_enc_close,
1136  .encode2 = encode_png,
1138  .pix_fmts = (const enum AVPixelFormat[]) {
1145  },
1146  .priv_class = &pngenc_class,
1147 };
1148 
1150  .name = "apng",
1151  .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"),
1152  .type = AVMEDIA_TYPE_VIDEO,
1153  .id = AV_CODEC_ID_APNG,
1154  .priv_data_size = sizeof(PNGEncContext),
1155  .init = png_enc_init,
1156  .close = png_enc_close,
1157  .encode2 = encode_apng,
1158  .capabilities = CODEC_CAP_DELAY,
1159  .pix_fmts = (const enum AVPixelFormat[]) {
1166  },
1167  .priv_class = &apngenc_class,
1168 };
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:162
#define PNG_FILTER_VALUE_AVG
Definition: png.h:41
#define NULL
Definition: coverity.c:32
APNGFctlChunk last_frame_fctl
Definition: pngenc.c:74
const char * s
Definition: avisynth_c.h:768
#define FF_COMPRESSION_DEFAULT
Definition: avcodec.h:1764
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
BYTE int const BYTE int int row_size
Definition: avisynth_c.h:813
AVOption.
Definition: opt.h:245
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition: avcodec.h:874
static uint8_t * png_choose_filter(PNGEncContext *s, uint8_t *dst, uint8_t *src, uint8_t *top, int size, int bpp)
Definition: pngenc.c:191
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:64
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static const AVClass apngenc_class
Definition: pngenc.c:1121
uint8_t * bytestream
Definition: pngenc.c:52
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1602
const char * b
Definition: vf_curves.c:113
uint32_t x_offset
Definition: pngenc.c:43
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:2087
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1904
static int encode_png(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: pngenc.c:521
int color_type
Definition: pngenc.c:65
void(* diff_bytes)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, intptr_t w)
Definition: huffyuvencdsp.h:25
static AVPacket pkt
#define PNG_COLOR_TYPE_RGB
Definition: png.h:33
static const AVClass pngenc_class
Definition: pngenc.c:1114
int bit_depth
Definition: pngenc.c:64
#define PNG_COLOR_TYPE_GRAY_ALPHA
Definition: png.h:35
Views are next to each other.
Definition: stereo3d.h:45
AVCodec.
Definition: avcodec.h:3600
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:32
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:410
#define OFFSET(x)
Definition: pngenc.c:1099
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:1052
size_t last_frame_packet_size
Definition: pngenc.c:76
int filter_type
Definition: pngenc.c:56
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:661
#define PNG_FILTER_VALUE_PAETH
Definition: png.h:42
uint32_t y_offset
Definition: pngenc.c:43
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:28
int bits_per_pixel
Definition: pngenc.c:66
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:145
#define PNG_COLOR_TYPE_RGB_ALPHA
Definition: png.h:34
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:73
AVOptions.
Stereo 3D type: this structure describes how two videos are packed within a single video surface...
Definition: stereo3d.h:123
HuffYUVEncDSPContext hdsp
Definition: pngenc.c:50
static void sub_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
Definition: pngenc.c:118
static void deflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord)
Definition: vf_neighbor.c:114
static int apng_encode_frame(AVCodecContext *avctx, const AVFrame *pict, APNGFctlChunk *best_fctl_chunk, APNGFctlChunk *best_last_fctl_chunk)
Definition: pngenc.c:709
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:217
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:383
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:268
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1791
uint32_t sequence_number
Definition: pngenc.c:41
uint8_t blend_op
Definition: pngenc.c:45
Public header for CRC hash function implementation.
Structure to hold side data for an AVFrame.
Definition: frame.h:143
static void input_data(MLPEncodeContext *ctx, void *samples)
Wrapper function for inputting data in two different bit-depths.
Definition: mlpenc.c:1275
uint8_t * data
Definition: avcodec.h:1601
uint32_t tag
Definition: movenc.c:1382
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:3070
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:389
#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:741
#define av_log(a,...)
#define PNG_FILTER_VALUE_MIXED
Definition: png.h:43
int is_progressive
Definition: pngenc.c:63
AVCodec ff_apng_encoder
Definition: pngenc.c:1149
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1633
#define U(x)
Definition: vp56_arith.h:37
uint32_t palette_checksum
Definition: pngenc.c:69
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:394
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:99
int width
width and height of the video frame
Definition: frame.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint32_t sequence_number
Definition: pngenc.c:70
int flags
Additional information about the frame packing.
Definition: stereo3d.h:132
16 bits gray, 16 bits alpha (big-endian)
Definition: pixfmt.h:226
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:79
uint32_t width
Definition: pngenc.c:42
static const uint16_t mask[17]
Definition: lzw.c:38
z_stream zstream
Definition: pngenc.c:58
#define CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:1176
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:158
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
int dpm
Physical pixel density, in dots per meter, if set.
Definition: pngenc.c:61
int ff_png_get_nb_channels(int color_type)
Definition: png.c:49
#define AV_WB32_PNG(buf, n)
Definition: pngenc.c:289
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1771
#define PNGSIG
Definition: png.h:52
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
Definition: pixfmt.h:391
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:342
GLsizei GLsizei * length
Definition: opengl_enc.c:115
const char * name
Name of the codec implementation.
Definition: avcodec.h:3607
#define NB_PASSES
Definition: png.h:50
#define fail()
Definition: checkasm.h:83
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1022
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:94
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:719
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1607
#define pass
Definition: fft_template.c:532
uint8_t * bytestream_start
Definition: pngenc.c:53
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:258
static int output_data(MLPDecodeContext *m, unsigned int substr, AVFrame *frame, int *got_frame_ptr)
Write the audio data into the output buffer.
Definition: mlpdec.c:1030
alias for AV_PIX_FMT_YA8
Definition: pixfmt.h:157
#define FFMIN(a, b)
Definition: common.h:96
#define PNG_FILTER_VALUE_SUB
Definition: png.h:39
#define width
static void png_write_chunk(uint8_t **f, uint32_t tag, const uint8_t *buf, int length)
Definition: pngenc.c:221
#define PNG_COLOR_TYPE_GRAY
Definition: png.h:31
int width
picture width / height.
Definition: avcodec.h:1863
uint16_t delay_num
Definition: pngenc.c:44
static const AVOption options[]
Definition: pngenc.c:1101
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:396
uint32_t height
Definition: pngenc.c:42
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:357
uint8_t * last_frame_packet
Definition: pngenc.c:75
static volatile int checksum
Definition: adler32.c:28
#define src
Definition: vp9dsp.c:530
static int encode_apng(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: pngenc.c:838
#define AV_STEREO3D_FLAG_INVERT
Inverted views, Right/Bottom represents the left view.
Definition: stereo3d.h:114
static const float pred[4]
Definition: siprdata.h:259
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
static int png_get_gama(enum AVColorTransferCharacteristic trc, uint8_t *buf)
Definition: pngenc.c:332
#define IOBUF_SIZE
Definition: pngenc.c:38
#define src1
Definition: h264pred.c:139
enum AVStereo3DType type
How views are packed within the video.
Definition: stereo3d.h:127
#define av_bswap32
Definition: bswap.h:33
AVCodec ff_png_encoder
Definition: pngenc.c:1128
Libavcodec external API header.
functionally identical to above
Definition: pixfmt.h:398
enum AVCodecID codec_id
Definition: avcodec.h:1693
int compression_level
Definition: avcodec.h:1763
attribute_deprecated int prediction_method
Definition: avcodec.h:2067
#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:215
static void png_write_image_data(AVCodecContext *avctx, const uint8_t *buf, int length)
Definition: pngenc.c:240
main external API structure.
Definition: avcodec.h:1676
uint8_t * data
Definition: frame.h:145
void * buf
Definition: avisynth_c.h:690
const uint8_t ff_png_pass_ymask[NB_PASSES]
Definition: png.c:25
int extradata_size
Definition: avcodec.h:1792
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:98
int dpi
Physical pixel density, in dots per inch, if set.
Definition: pngenc.c:60
#define VE
Definition: pngenc.c:1100
static av_cold int png_enc_init(AVCodecContext *avctx)
Definition: pngenc.c:979
uint8_t * bytestream_end
Definition: pngenc.c:54
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:1722
static int encode_frame(AVCodecContext *avctx, const AVFrame *pict)
Definition: pngenc.c:428
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
uint8_t dispose_op
Definition: pngenc.c:45
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:275
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:493
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition: crc.c:343
uint8_t buf[IOBUF_SIZE]
Definition: pngenc.c:59
int palette
Definition: v4l.c:61
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:72
static int png_write_row(AVCodecContext *avctx, const uint8_t *data, int size)
Definition: pngenc.c:268
Y , 8bpp.
Definition: pixfmt.h:70
IEC 61966-2-1 (sRGB or sYCC)
Definition: pixfmt.h:424
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:80
common internal api header.
#define PNG_FILTER_VALUE_NONE
Definition: png.h:38
Video is not stereoscopic (and metadata has to be there).
Definition: stereo3d.h:35
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:110
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:3098
int den
Denominator.
Definition: rational.h:60
void ff_png_zfree(void *opaque, void *ptr)
Definition: png.c:44
#define MKBETAG(a, b, c, d)
Definition: common.h:343
void * priv_data
Definition: avcodec.h:1718
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:81
int len
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:253
APNG common header.
static int png_get_chrm(enum AVColorPrimaries prim, uint8_t *buf)
Definition: pngenc.c:290
enum AVColorPrimaries color_primaries
Definition: frame.h:424
int ff_png_pass_row_size(int pass, int bits_per_pixel, int width)
Definition: png.c:62
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1600
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:397
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2469
ITU-R BT2020.
Definition: pixfmt.h:400
int height
Definition: frame.h:236
#define av_freep(p)
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:426
uint16_t delay_den
Definition: pngenc.c:44
static int apng_do_inverse_blend(AVFrame *output, const AVFrame *input, APNGFctlChunk *fctl_chunk, uint8_t bpp)
Definition: pngenc.c:566
AVFrame * last_frame
Definition: pngenc.c:73
static av_cold int png_enc_close(AVCodecContext *avctx)
Definition: pngenc.c:1088
#define FFSWAP(type, a, b)
Definition: common.h:99
#define MKTAG(a, b, c, d)
Definition: common.h:342
void * ff_png_zalloc(void *opaque, unsigned int items, unsigned int size)
Definition: png.c:39
Stereoscopic 3d metadata.
Definition: frame.h:62
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1578
uint32_t AVCRC
Definition: crc.h:47
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1594
for(j=16;j >0;--j)
AVFrame * prev_frame
Definition: pngenc.c:72
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
#define FF_MIN_BUFFER_SIZE
Definition: avcodec.h:752
static void sub_left_prediction(PNGEncContext *c, uint8_t *dst, const uint8_t *src, int bpp, int size)
Definition: pngenc.c:146