FFmpeg
gif.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000 Fabrice Bellard
3  * Copyright (c) 2002 Francois Revol
4  * Copyright (c) 2006 Baptiste Coudurier
5  * Copyright (c) 2018 Bjorn Roche
6  * Copyright (c) 2018 Paul B Mahol
7  *
8  * first version by Francois Revol <revol@free.fr>
9  *
10  * This file is part of FFmpeg.
11  *
12  * FFmpeg is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * FFmpeg is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with FFmpeg; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25  */
26 
27 /**
28  * @file
29  * GIF encoder
30  * @see http://www.w3.org/Graphics/GIF/spec-gif89a.txt
31  */
32 
34 #include "libavutil/mem.h"
35 #include "libavutil/opt.h"
36 #include "avcodec.h"
37 #include "bytestream.h"
38 #include "codec_internal.h"
39 #include "encode.h"
40 #include "lzw.h"
41 #include "gif.h"
42 
43 #define DEFAULT_TRANSPARENCY_INDEX 0x1f
44 
45 typedef struct GIFContext {
46  const AVClass *class;
48  uint8_t *buf;
49  uint8_t *shrunk_buf;
50  int buf_size;
52  int flags;
53  int image;
55  uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8
58  uint8_t *tmpl; ///< temporary line buffer
59 } GIFContext;
60 
61 enum {
62  GF_OFFSETTING = 1<<0,
63  GF_TRANSDIFF = 1<<1,
64 };
65 
66 static void shrink_palette(const uint32_t *src, uint8_t *map,
67  uint32_t *dst, size_t *palette_count)
68 {
69  size_t colors_seen = 0;
70 
71  for (size_t i = 0; i < AVPALETTE_COUNT; i++) {
72  int seen = 0;
73  for (size_t c = 0; c < colors_seen; c++) {
74  if (src[i] == dst[c]) {
75  seen = 1;
76  break;
77  }
78  }
79  if (!seen) {
80  dst[colors_seen] = src[i];
81  map[i] = colors_seen;
82  colors_seen++;
83  }
84  }
85 
86  *palette_count = colors_seen;
87 }
88 
89 static void remap_frame_to_palette(const uint8_t *src, int src_linesize,
90  uint8_t *dst, int dst_linesize,
91  int w, int h, uint8_t *map)
92 {
93  for (int i = 0; i < h; i++)
94  for (int j = 0; j < w; j++)
95  dst[i * dst_linesize + j] = map[src[i * src_linesize + j]];
96 }
97 
99  const uint8_t *buf, const int linesize)
100 {
101  GIFContext *s = avctx->priv_data;
102  int trans = s->transparent_index;
103 
104  if (trans < 0)
105  return 0;
106 
107  for (int y = 0; y < avctx->height; y++) {
108  for (int x = 0; x < avctx->width; x++) {
109  if (buf[x] == trans) {
110  return 1;
111  }
112  }
113  buf += linesize;
114  }
115 
116  return 0;
117 }
118 
119 static int get_palette_transparency_index(const uint32_t *palette)
120 {
121  int transparent_color_index = -1;
122  unsigned i, smallest_alpha = 0xff;
123 
124  if (!palette)
125  return -1;
126 
127  for (i = 0; i < AVPALETTE_COUNT; i++) {
128  const uint32_t v = palette[i];
129  if (v >> 24 < smallest_alpha) {
130  smallest_alpha = v >> 24;
131  transparent_color_index = i;
132  }
133  }
134  return smallest_alpha < 128 ? transparent_color_index : -1;
135 }
136 
137 static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
138 {
139  int histogram[AVPALETTE_COUNT] = {0};
140  int x, y, i;
141 
142  for (y = 0; y < h; y++) {
143  for (x = 0; x < w; x++)
144  histogram[buf[x]]++;
145  buf += linesize;
146  }
147  for (i = 0; i < FF_ARRAY_ELEMS(histogram); i++)
148  if (!histogram[i])
149  return i;
150  return -1;
151 }
152 
154  const uint8_t *buf, const int linesize,
155  int *width, int *height,
156  int *x_start, int *y_start)
157 {
158  GIFContext *s = avctx->priv_data;
159  int trans = s->transparent_index;
160 
161  /* Crop image */
162  if ((s->flags & GF_OFFSETTING) && trans >= 0) {
163  const int w = avctx->width;
164  const int h = avctx->height;
165  int x_end = w - 1,
166  y_end = h - 1;
167 
168  // crop top
169  while (*y_start < y_end) {
170  int is_trans = 1;
171  for (int i = 0; i < w; i++) {
172  if (buf[linesize * *y_start + i] != trans) {
173  is_trans = 0;
174  break;
175  }
176  }
177 
178  if (!is_trans)
179  break;
180  (*y_start)++;
181  }
182 
183  // crop bottom
184  while (y_end > *y_start) {
185  int is_trans = 1;
186  for (int i = 0; i < w; i++) {
187  if (buf[linesize * y_end + i] != trans) {
188  is_trans = 0;
189  break;
190  }
191  }
192  if (!is_trans)
193  break;
194  y_end--;
195  }
196 
197  // crop left
198  while (*x_start < x_end) {
199  int is_trans = 1;
200  for (int i = *y_start; i < y_end; i++) {
201  if (buf[linesize * i + *x_start] != trans) {
202  is_trans = 0;
203  break;
204  }
205  }
206  if (!is_trans)
207  break;
208  (*x_start)++;
209  }
210 
211  // crop right
212  while (x_end > *x_start) {
213  int is_trans = 1;
214  for (int i = *y_start; i < y_end; i++) {
215  if (buf[linesize * i + x_end] != trans) {
216  is_trans = 0;
217  break;
218  }
219  }
220  if (!is_trans)
221  break;
222  x_end--;
223  }
224 
225  *height = y_end + 1 - *y_start;
226  *width = x_end + 1 - *x_start;
227  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
228  *width, *height, *x_start, *y_start, avctx->width, avctx->height);
229  }
230 }
231 
232 static void gif_crop_opaque(AVCodecContext *avctx,
233  const uint32_t *palette,
234  const uint8_t *buf, const int linesize,
235  int *width, int *height, int *x_start, int *y_start)
236 {
237  GIFContext *s = avctx->priv_data;
238 
239  /* Crop image */
240  if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
241  const uint8_t *ref = s->last_frame->data[0];
242  const int ref_linesize = s->last_frame->linesize[0];
243  int x_end = avctx->width - 1,
244  y_end = avctx->height - 1;
245 
246  /* skip common lines */
247  while (*y_start < y_end) {
248  if (memcmp(ref + *y_start*ref_linesize, buf + *y_start*linesize, *width))
249  break;
250  (*y_start)++;
251  }
252  while (y_end > *y_start) {
253  if (memcmp(ref + y_end*ref_linesize, buf + y_end*linesize, *width))
254  break;
255  y_end--;
256  }
257  *height = y_end + 1 - *y_start;
258 
259  /* skip common columns */
260  while (*x_start < x_end) {
261  int same_column = 1;
262  for (int y = *y_start; y <= y_end; y++) {
263  if (ref[y*ref_linesize + *x_start] != buf[y*linesize + *x_start]) {
264  same_column = 0;
265  break;
266  }
267  }
268  if (!same_column)
269  break;
270  (*x_start)++;
271  }
272  while (x_end > *x_start) {
273  int same_column = 1;
274  for (int y = *y_start; y <= y_end; y++) {
275  if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) {
276  same_column = 0;
277  break;
278  }
279  }
280  if (!same_column)
281  break;
282  x_end--;
283  }
284  *width = x_end + 1 - *x_start;
285 
286  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
287  *width, *height, *x_start, *y_start, avctx->width, avctx->height);
288  }
289 }
290 
292  uint8_t **bytestream, uint8_t *end,
293  const uint32_t *palette,
294  const uint8_t *buf, const int linesize,
295  AVPacket *pkt)
296 {
297  GIFContext *s = avctx->priv_data;
298  int disposal, len = 0, height = avctx->height, width = avctx->width, x, y;
299  int x_start = 0, y_start = 0, trans = s->transparent_index;
300  int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette;
301  const uint8_t *ptr;
302  uint32_t shrunk_palette[AVPALETTE_COUNT];
303  uint8_t map[AVPALETTE_COUNT] = { 0 };
304  size_t shrunk_palette_count = 0;
305 
306  /*
307  * We memset to 0xff instead of 0x00 so that the transparency detection
308  * doesn't pick anything after the palette entries as the transparency
309  * index, and because GIF89a requires us to always write a power-of-2
310  * number of palette entries.
311  */
312  memset(shrunk_palette, 0xff, AVPALETTE_SIZE);
313 
314  if (!s->image && is_image_translucent(avctx, buf, linesize)) {
315  gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start);
316  honor_transparency = 0;
317  disposal = GCE_DISPOSAL_BACKGROUND;
318  } else {
319  gif_crop_opaque(avctx, palette, buf, linesize, &width, &height, &x_start, &y_start);
320  disposal = GCE_DISPOSAL_INPLACE;
321  }
322 
323  if (s->image || !avctx->frame_num) { /* GIF header */
324  const uint32_t *global_palette = palette ? palette : s->palette;
325  const AVRational sar = avctx->sample_aspect_ratio;
326  int64_t aspect = 0;
327 
328  if (sar.num > 0 && sar.den > 0) {
329  aspect = sar.num * 64LL / sar.den - 15;
330  if (aspect < 0 || aspect > 255)
331  aspect = 0;
332  }
333 
334  bytestream_put_buffer(bytestream, gif89a_sig, sizeof(gif89a_sig));
335  bytestream_put_le16(bytestream, avctx->width);
336  bytestream_put_le16(bytestream, avctx->height);
337 
338  bcid = get_palette_transparency_index(global_palette);
339 
340  bytestream_put_byte(bytestream, ((uint8_t) s->use_global_palette << 7) | 0x70 | (s->use_global_palette ? 7 : 0)); /* flags: global clut, 256 entries */
341  bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); /* background color index */
342  bytestream_put_byte(bytestream, aspect);
343  if (s->use_global_palette) {
344  for (int i = 0; i < 256; i++) {
345  const uint32_t v = global_palette[i] & 0xffffff;
346  bytestream_put_be24(bytestream, v);
347  }
348  }
349  }
350 
351  if (honor_transparency && trans < 0) {
352  trans = pick_palette_entry(buf + y_start*linesize + x_start,
353  linesize, width, height);
354  if (trans < 0) // TODO, patch welcome
355  av_log(avctx, AV_LOG_DEBUG, "No available color, can not use transparency\n");
356  }
357 
358  if (trans < 0)
359  honor_transparency = 0;
360 
361  if (palette || !s->use_global_palette) {
362  const uint32_t *pal = palette ? palette : s->palette;
363  shrink_palette(pal, map, shrunk_palette, &shrunk_palette_count);
364  }
365 
366  bcid = honor_transparency || disposal == GCE_DISPOSAL_BACKGROUND ? trans : get_palette_transparency_index(palette);
367 
368  /* graphic control extension */
369  bytestream_put_byte(bytestream, GIF_EXTENSION_INTRODUCER);
370  bytestream_put_byte(bytestream, GIF_GCE_EXT_LABEL);
371  bytestream_put_byte(bytestream, 0x04); /* block size */
372  bytestream_put_byte(bytestream, disposal<<2 | (bcid >= 0));
373  bytestream_put_le16(bytestream, 5); // default delay
374  bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : (shrunk_palette_count ? map[bcid] : bcid));
375  bytestream_put_byte(bytestream, 0x00);
376 
377  /* image block */
378  bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR);
379  bytestream_put_le16(bytestream, x_start);
380  bytestream_put_le16(bytestream, y_start);
381  bytestream_put_le16(bytestream, width);
382  bytestream_put_le16(bytestream, height);
383 
384  if (palette || !s->use_global_palette) {
385  unsigned pow2_count = av_log2(shrunk_palette_count - 1);
386  unsigned i;
387 
388  bytestream_put_byte(bytestream, 1<<7 | pow2_count); /* flags */
389  for (i = 0; i < 1 << (pow2_count + 1); i++) {
390  const uint32_t v = shrunk_palette[i];
391  bytestream_put_be24(bytestream, v);
392  }
393  } else {
394  bytestream_put_byte(bytestream, 0x00); /* flags */
395  }
396 
397  bytestream_put_byte(bytestream, 0x08);
398 
399  ff_lzw_encode_init(s->lzw, s->buf, s->buf_size,
400  12, FF_LZW_GIF, 1);
401 
402  if (shrunk_palette_count) {
403  if (!s->shrunk_buf) {
404  s->shrunk_buf = av_malloc(avctx->height * linesize);
405  if (!s->shrunk_buf) {
406  av_log(avctx, AV_LOG_ERROR, "Could not allocated remapped frame buffer.\n");
407  return AVERROR(ENOMEM);
408  }
409  }
410  remap_frame_to_palette(buf, linesize, s->shrunk_buf, linesize, avctx->width, avctx->height, map);
411  ptr = s->shrunk_buf + y_start*linesize + x_start;
412  } else {
413  ptr = buf + y_start*linesize + x_start;
414  }
415  if (honor_transparency) {
416  const int ref_linesize = s->last_frame->linesize[0];
417  const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start;
418 
419  for (y = 0; y < height; y++) {
420  memcpy(s->tmpl, ptr, width);
421  for (x = 0; x < width; x++)
422  if (ref[x] == ptr[x])
423  s->tmpl[x] = trans;
424  len += ff_lzw_encode(s->lzw, s->tmpl, width);
425  ptr += linesize;
426  ref += ref_linesize;
427  }
428  } else {
429  for (y = 0; y < height; y++) {
430  len += ff_lzw_encode(s->lzw, ptr, width);
431  ptr += linesize;
432  }
433  }
434  len += ff_lzw_encode_flush(s->lzw);
435 
436  ptr = s->buf;
437  while (len > 0) {
438  int size = FFMIN(255, len);
439  bytestream_put_byte(bytestream, size);
440  if (end - *bytestream < size)
441  return -1;
442  bytestream_put_buffer(bytestream, ptr, size);
443  ptr += size;
444  len -= size;
445  }
446  bytestream_put_byte(bytestream, 0x00); /* end of image block */
447  return 0;
448 }
449 
451 {
452  GIFContext *s = avctx->priv_data;
453 
454  if (avctx->width > 65535 || avctx->height > 65535) {
455  av_log(avctx, AV_LOG_ERROR, "GIF does not support resolutions above 65535x65535\n");
456  return AVERROR(EINVAL);
457  }
458 
459  s->transparent_index = -1;
460 
462  s->buf_size = avctx->width*avctx->height*2 + 1000;
463  s->buf = av_malloc(s->buf_size);
464  s->tmpl = av_malloc(avctx->width);
465  if (!s->tmpl || !s->buf || !s->lzw)
466  return AVERROR(ENOMEM);
467 
468  if (avpriv_set_systematic_pal2(s->palette, avctx->pix_fmt) < 0)
470 
471  return 0;
472 }
473 
475  const AVFrame *pict, int *got_packet)
476 {
477  GIFContext *s = avctx->priv_data;
478  uint8_t *outbuf_ptr, *end;
479  const uint32_t *palette = NULL;
480  int ret;
481 
482  if ((ret = ff_alloc_packet(avctx, pkt, avctx->width*avctx->height*7/5 + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
483  return ret;
484  outbuf_ptr = pkt->data;
485  end = pkt->data + pkt->size;
486 
487  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
488  palette = (uint32_t*)pict->data[1];
489 
490  if (!s->palette_loaded) {
491  memcpy(s->palette, palette, AVPALETTE_SIZE);
492  s->transparent_index = get_palette_transparency_index(palette);
493  s->palette_loaded = 1;
494  } else if (!memcmp(s->palette, palette, AVPALETTE_SIZE)) {
495  palette = NULL;
496  }
497  }
498 
499  gif_image_write_image(avctx, &outbuf_ptr, end, palette,
500  pict->data[0], pict->linesize[0], pkt);
501  if (!s->last_frame && !s->image) {
502  s->last_frame = av_frame_alloc();
503  if (!s->last_frame)
504  return AVERROR(ENOMEM);
505  }
506 
507  if (!s->image) {
508  ret = av_frame_replace(s->last_frame, pict);
509  if (ret < 0)
510  return ret;
511  }
512 
513  pkt->size = outbuf_ptr - pkt->data;
514  if (s->image || !avctx->frame_num)
516  *got_packet = 1;
517 
518  return 0;
519 }
520 
522 {
523  GIFContext *s = avctx->priv_data;
524 
525  av_freep(&s->lzw);
526  av_freep(&s->buf);
527  av_freep(&s->shrunk_buf);
528  s->buf_size = 0;
529  av_frame_free(&s->last_frame);
530  av_freep(&s->tmpl);
531  return 0;
532 }
533 
534 #define OFFSET(x) offsetof(GIFContext, x)
535 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
536 static const AVOption gif_options[] = {
537  { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, .unit = "flags" },
538  { "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, .unit = "flags" },
539  { "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, .unit = "flags" },
540  { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
541  { "global_palette", "write a palette to the global gif header where feasible", OFFSET(use_global_palette), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
542  { NULL }
543 };
544 
545 static const AVClass gif_class = {
546  .class_name = "GIF encoder",
547  .item_name = av_default_item_name,
548  .option = gif_options,
549  .version = LIBAVUTIL_VERSION_INT,
550 };
551 
553  .p.name = "gif",
554  CODEC_LONG_NAME("GIF (Graphics Interchange Format)"),
555  .p.type = AVMEDIA_TYPE_VIDEO,
556  .p.id = AV_CODEC_ID_GIF,
558  .priv_data_size = sizeof(GIFContext),
561  .close = gif_encode_close,
562  .p.pix_fmts = (const enum AVPixelFormat[]){
565  },
566  .p.priv_class = &gif_class,
567  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
568 };
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
GIFContext::buf
uint8_t * buf
Definition: gif.c:48
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:43
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
is_image_translucent
static int is_image_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize)
Definition: gif.c:98
int64_t
long long int64_t
Definition: coverity.c:34
FLAGS
#define FLAGS
Definition: gif.c:535
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
w
uint8_t w
Definition: llviddspenc.c:38
AVPacket::data
uint8_t * data
Definition: packet.h:539
AVOption
AVOption.
Definition: opt.h:429
remap_frame_to_palette
static void remap_frame_to_palette(const uint8_t *src, int src_linesize, uint8_t *dst, int dst_linesize, int w, int h, uint8_t *map)
Definition: gif.c:89
encode.h
ff_lzw_encode_init
void ff_lzw_encode_init(struct LZWEncodeState *s, uint8_t *outbuf, int outsize, int maxbits, enum FF_LZW_MODES mode, int little_endian)
Initialize LZW encoder.
Definition: lzwenc.c:206
FFCodec
Definition: codec_internal.h:127
GIF_GCE_EXT_LABEL
#define GIF_GCE_EXT_LABEL
Definition: gif.h:45
gif_encode_close
static int gif_encode_close(AVCodecContext *avctx)
Definition: gif.c:521
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:594
FF_INPUT_BUFFER_MIN_SIZE
#define FF_INPUT_BUFFER_MIN_SIZE
Used by some encoders as upper bound for the length of headers.
Definition: encode.h:33
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
gif_crop_translucent
static void gif_crop_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize, int *width, int *height, int *x_start, int *y_start)
Definition: gif.c:153
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
ff_gif_encoder
const FFCodec ff_gif_encoder
Definition: gif.c:552
GF_OFFSETTING
@ GF_OFFSETTING
Definition: gif.c:62
gif_image_write_image
static int gif_image_write_image(AVCodecContext *avctx, uint8_t **bytestream, uint8_t *end, const uint32_t *palette, const uint8_t *buf, const int linesize, AVPacket *pkt)
Definition: gif.c:291
GIFContext::palette
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
Definition: gif.c:55
GIFContext::transparent_index
int transparent_index
Definition: gif.c:57
DEFAULT_TRANSPARENCY_INDEX
#define DEFAULT_TRANSPARENCY_INDEX
Definition: gif.c:43
shrink_palette
static void shrink_palette(const uint32_t *src, uint8_t *map, uint32_t *dst, size_t *palette_count)
Definition: gif.c:66
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:320
AVRational::num
int num
Numerator.
Definition: rational.h:59
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:150
gif89a_sig
static const uint8_t gif89a_sig[6]
Definition: gif.h:35
AV_PIX_FMT_BGR8
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:90
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition: codec.h:159
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
GIF_IMAGE_SEPARATOR
#define GIF_IMAGE_SEPARATOR
Definition: gif.h:44
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
LZWState
Definition: lzw.c:46
avpriv_set_systematic_pal2
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:178
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:296
if
if(ret)
Definition: filter_design.txt:179
GF_TRANSDIFF
@ GF_TRANSDIFF
Definition: gif.c:63
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
GIFContext::tmpl
uint8_t * tmpl
temporary line buffer
Definition: gif.c:58
GIFContext::flags
int flags
Definition: gif.c:52
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
GIFContext::image
int image
Definition: gif.c:53
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)3R 3G 2B(lsb)
Definition: pixfmt.h:93
GIFContext::shrunk_buf
uint8_t * shrunk_buf
Definition: gif.c:49
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
FF_LZW_GIF
@ FF_LZW_GIF
Definition: lzw.h:38
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVPALETTE_COUNT
#define AVPALETTE_COUNT
Definition: pixfmt.h:33
AV_PIX_FMT_BGR4_BYTE
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:92
OFFSET
#define OFFSET(x)
Definition: gif.c:534
GIFContext::use_global_palette
int use_global_palette
Definition: gif.c:54
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:540
get_palette_transparency_index
static int get_palette_transparency_index(const uint32_t *palette)
Definition: gif.c:119
height
#define height
Definition: dsp.h:85
codec_internal.h
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
lzw.h
LZW decoding routines.
gif.h
size
int size
Definition: twinvq_data.h:10344
gif_encode_init
static av_cold int gif_encode_init(AVCodecContext *avctx)
Definition: gif.c:450
GIFContext
Definition: gif.c:45
GIFContext::buf_size
int buf_size
Definition: gif.c:50
GIFContext::palette_loaded
int palette_loaded
Definition: gif.c:56
imgutils_internal.h
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:545
AV_CODEC_ID_GIF
@ AV_CODEC_ID_GIF
Definition: codec_id.h:149
bytestream_put_buffer
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:372
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
GIF_EXTENSION_INTRODUCER
#define GIF_EXTENSION_INTRODUCER
Definition: gif.h:43
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
ff_lzw_encode_flush
int ff_lzw_encode_flush(struct LZWEncodeState *s)
Write end code and flush bitstream.
Definition: lzwenc.c:263
gif_class
static const AVClass gif_class
Definition: gif.c:545
len
int len
Definition: vorbis_enc_data.h:426
AV_PIX_FMT_RGB4_BYTE
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:95
AVCodecContext::height
int height
Definition: avcodec.h:624
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:663
avcodec.h
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
AVCodecContext::frame_num
int64_t frame_num
Frame counter, set by libavcodec.
Definition: avcodec.h:2041
ret
ret
Definition: filter_design.txt:187
GIFContext::last_frame
AVFrame * last_frame
Definition: gif.c:51
GCE_DISPOSAL_BACKGROUND
#define GCE_DISPOSAL_BACKGROUND
Definition: gif.h:39
AVClass::class_name
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:80
gif_options
static const AVOption gif_options[]
Definition: gif.c:536
gif_crop_opaque
static void gif_crop_opaque(AVCodecContext *avctx, const uint32_t *palette, const uint8_t *buf, const int linesize, int *width, int *height, int *x_start, int *y_start)
Definition: gif.c:232
av_frame_replace
int av_frame_replace(AVFrame *dst, const AVFrame *src)
Ensure the destination frame refers to the same data described by the source frame,...
Definition: frame.c:487
AVCodecContext
main external API structure.
Definition: avcodec.h:451
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
GIFContext::lzw
LZWState * lzw
Definition: gif.c:47
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
ff_lzw_encode_state_size
const int ff_lzw_encode_state_size
Definition: lzwenc.c:68
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:624
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
bytestream.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:434
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
gif_encode_frame
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: gif.c:474
GCE_DISPOSAL_INPLACE
#define GCE_DISPOSAL_INPLACE
Definition: gif.h:38
h
h
Definition: vp9dsp_template.c:2070
pick_palette_entry
static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
Definition: gif.c:137
width
#define width
Definition: dsp.h:85
ff_lzw_encode
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
Definition: lzwenc.c:230
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:62
src
#define src
Definition: vp8dsp.c:248