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 
33 #include "libavutil/opt.h"
34 #include "avcodec.h"
35 #include "bytestream.h"
36 #include "codec_internal.h"
37 #include "encode.h"
38 #include "lzw.h"
39 #include "gif.h"
40 
41 #define DEFAULT_TRANSPARENCY_INDEX 0x1f
42 
43 typedef struct GIFContext {
44  const AVClass *class;
46  uint8_t *buf;
47  uint8_t *shrunk_buf;
48  int buf_size;
50  int flags;
51  int image;
53  uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8
56  uint8_t *tmpl; ///< temporary line buffer
57 } GIFContext;
58 
59 enum {
60  GF_OFFSETTING = 1<<0,
61  GF_TRANSDIFF = 1<<1,
62 };
63 
64 static void shrink_palette(const uint32_t *src, uint8_t *map,
65  uint32_t *dst, size_t *palette_count)
66 {
67  size_t colors_seen = 0;
68 
69  for (size_t i = 0; i < AVPALETTE_COUNT; i++) {
70  int seen = 0;
71  for (size_t c = 0; c < colors_seen; c++) {
72  if (src[i] == dst[c]) {
73  seen = 1;
74  break;
75  }
76  }
77  if (!seen) {
78  dst[colors_seen] = src[i];
79  map[i] = colors_seen;
80  colors_seen++;
81  }
82  }
83 
84  *palette_count = colors_seen;
85 }
86 
87 static void remap_frame_to_palette(const uint8_t *src, int src_linesize,
88  uint8_t *dst, int dst_linesize,
89  int w, int h, uint8_t *map)
90 {
91  for (int i = 0; i < h; i++)
92  for (int j = 0; j < w; j++)
93  dst[i * dst_linesize + j] = map[src[i * src_linesize + j]];
94 }
95 
97  const uint8_t *buf, const int linesize)
98 {
99  GIFContext *s = avctx->priv_data;
100  int trans = s->transparent_index;
101 
102  if (trans < 0)
103  return 0;
104 
105  for (int y = 0; y < avctx->height; y++) {
106  for (int x = 0; x < avctx->width; x++) {
107  if (buf[x] == trans) {
108  return 1;
109  }
110  }
111  buf += linesize;
112  }
113 
114  return 0;
115 }
116 
117 static int get_palette_transparency_index(const uint32_t *palette)
118 {
119  int transparent_color_index = -1;
120  unsigned i, smallest_alpha = 0xff;
121 
122  if (!palette)
123  return -1;
124 
125  for (i = 0; i < AVPALETTE_COUNT; i++) {
126  const uint32_t v = palette[i];
127  if (v >> 24 < smallest_alpha) {
128  smallest_alpha = v >> 24;
129  transparent_color_index = i;
130  }
131  }
132  return smallest_alpha < 128 ? transparent_color_index : -1;
133 }
134 
135 static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
136 {
137  int histogram[AVPALETTE_COUNT] = {0};
138  int x, y, i;
139 
140  for (y = 0; y < h; y++) {
141  for (x = 0; x < w; x++)
142  histogram[buf[x]]++;
143  buf += linesize;
144  }
145  for (i = 0; i < FF_ARRAY_ELEMS(histogram); i++)
146  if (!histogram[i])
147  return i;
148  return -1;
149 }
150 
152  const uint8_t *buf, const int linesize,
153  int *width, int *height,
154  int *x_start, int *y_start)
155 {
156  GIFContext *s = avctx->priv_data;
157  int trans = s->transparent_index;
158 
159  /* Crop image */
160  if ((s->flags & GF_OFFSETTING) && trans >= 0) {
161  const int w = avctx->width;
162  const int h = avctx->height;
163  int x_end = w - 1,
164  y_end = h - 1;
165 
166  // crop top
167  while (*y_start < y_end) {
168  int is_trans = 1;
169  for (int i = 0; i < w; i++) {
170  if (buf[linesize * *y_start + i] != trans) {
171  is_trans = 0;
172  break;
173  }
174  }
175 
176  if (!is_trans)
177  break;
178  (*y_start)++;
179  }
180 
181  // crop bottom
182  while (y_end > *y_start) {
183  int is_trans = 1;
184  for (int i = 0; i < w; i++) {
185  if (buf[linesize * y_end + i] != trans) {
186  is_trans = 0;
187  break;
188  }
189  }
190  if (!is_trans)
191  break;
192  y_end--;
193  }
194 
195  // crop left
196  while (*x_start < x_end) {
197  int is_trans = 1;
198  for (int i = *y_start; i < y_end; i++) {
199  if (buf[linesize * i + *x_start] != trans) {
200  is_trans = 0;
201  break;
202  }
203  }
204  if (!is_trans)
205  break;
206  (*x_start)++;
207  }
208 
209  // crop right
210  while (x_end > *x_start) {
211  int is_trans = 1;
212  for (int i = *y_start; i < y_end; i++) {
213  if (buf[linesize * i + x_end] != trans) {
214  is_trans = 0;
215  break;
216  }
217  }
218  if (!is_trans)
219  break;
220  x_end--;
221  }
222 
223  *height = y_end + 1 - *y_start;
224  *width = x_end + 1 - *x_start;
225  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
226  *width, *height, *x_start, *y_start, avctx->width, avctx->height);
227  }
228 }
229 
230 static void gif_crop_opaque(AVCodecContext *avctx,
231  const uint32_t *palette,
232  const uint8_t *buf, const int linesize,
233  int *width, int *height, int *x_start, int *y_start)
234 {
235  GIFContext *s = avctx->priv_data;
236 
237  /* Crop image */
238  if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
239  const uint8_t *ref = s->last_frame->data[0];
240  const int ref_linesize = s->last_frame->linesize[0];
241  int x_end = avctx->width - 1,
242  y_end = avctx->height - 1;
243 
244  /* skip common lines */
245  while (*y_start < y_end) {
246  if (memcmp(ref + *y_start*ref_linesize, buf + *y_start*linesize, *width))
247  break;
248  (*y_start)++;
249  }
250  while (y_end > *y_start) {
251  if (memcmp(ref + y_end*ref_linesize, buf + y_end*linesize, *width))
252  break;
253  y_end--;
254  }
255  *height = y_end + 1 - *y_start;
256 
257  /* skip common columns */
258  while (*x_start < x_end) {
259  int same_column = 1;
260  for (int y = *y_start; y <= y_end; y++) {
261  if (ref[y*ref_linesize + *x_start] != buf[y*linesize + *x_start]) {
262  same_column = 0;
263  break;
264  }
265  }
266  if (!same_column)
267  break;
268  (*x_start)++;
269  }
270  while (x_end > *x_start) {
271  int same_column = 1;
272  for (int y = *y_start; y <= y_end; y++) {
273  if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) {
274  same_column = 0;
275  break;
276  }
277  }
278  if (!same_column)
279  break;
280  x_end--;
281  }
282  *width = x_end + 1 - *x_start;
283 
284  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
285  *width, *height, *x_start, *y_start, avctx->width, avctx->height);
286  }
287 }
288 
290  uint8_t **bytestream, uint8_t *end,
291  const uint32_t *palette,
292  const uint8_t *buf, const int linesize,
293  AVPacket *pkt)
294 {
295  GIFContext *s = avctx->priv_data;
296  int disposal, len = 0, height = avctx->height, width = avctx->width, x, y;
297  int x_start = 0, y_start = 0, trans = s->transparent_index;
298  int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette;
299  const uint8_t *ptr;
300  uint32_t shrunk_palette[AVPALETTE_COUNT];
301  uint8_t map[AVPALETTE_COUNT] = { 0 };
302  size_t shrunk_palette_count = 0;
303 
304  /*
305  * We memset to 0xff instead of 0x00 so that the transparency detection
306  * doesn't pick anything after the palette entries as the transparency
307  * index, and because GIF89a requires us to always write a power-of-2
308  * number of palette entries.
309  */
310  memset(shrunk_palette, 0xff, AVPALETTE_SIZE);
311 
312  if (!s->image && is_image_translucent(avctx, buf, linesize)) {
313  gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start);
314  honor_transparency = 0;
315  disposal = GCE_DISPOSAL_BACKGROUND;
316  } else {
317  gif_crop_opaque(avctx, palette, buf, linesize, &width, &height, &x_start, &y_start);
318  disposal = GCE_DISPOSAL_INPLACE;
319  }
320 
321  if (s->image || !avctx->frame_num) { /* GIF header */
322  const uint32_t *global_palette = palette ? palette : s->palette;
323  const AVRational sar = avctx->sample_aspect_ratio;
324  int64_t aspect = 0;
325 
326  if (sar.num > 0 && sar.den > 0) {
327  aspect = sar.num * 64LL / sar.den - 15;
328  if (aspect < 0 || aspect > 255)
329  aspect = 0;
330  }
331 
332  bytestream_put_buffer(bytestream, gif89a_sig, sizeof(gif89a_sig));
333  bytestream_put_le16(bytestream, avctx->width);
334  bytestream_put_le16(bytestream, avctx->height);
335 
336  bcid = get_palette_transparency_index(global_palette);
337 
338  bytestream_put_byte(bytestream, ((uint8_t) s->use_global_palette << 7) | 0x70 | (s->use_global_palette ? 7 : 0)); /* flags: global clut, 256 entries */
339  bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); /* background color index */
340  bytestream_put_byte(bytestream, aspect);
341  if (s->use_global_palette) {
342  for (int i = 0; i < 256; i++) {
343  const uint32_t v = global_palette[i] & 0xffffff;
344  bytestream_put_be24(bytestream, v);
345  }
346  }
347  }
348 
349  if (honor_transparency && trans < 0) {
350  trans = pick_palette_entry(buf + y_start*linesize + x_start,
351  linesize, width, height);
352  if (trans < 0) // TODO, patch welcome
353  av_log(avctx, AV_LOG_DEBUG, "No available color, can not use transparency\n");
354  }
355 
356  if (trans < 0)
357  honor_transparency = 0;
358 
359  if (palette || !s->use_global_palette) {
360  const uint32_t *pal = palette ? palette : s->palette;
361  shrink_palette(pal, map, shrunk_palette, &shrunk_palette_count);
362  }
363 
364  bcid = honor_transparency || disposal == GCE_DISPOSAL_BACKGROUND ? trans : get_palette_transparency_index(palette);
365 
366  /* graphic control extension */
367  bytestream_put_byte(bytestream, GIF_EXTENSION_INTRODUCER);
368  bytestream_put_byte(bytestream, GIF_GCE_EXT_LABEL);
369  bytestream_put_byte(bytestream, 0x04); /* block size */
370  bytestream_put_byte(bytestream, disposal<<2 | (bcid >= 0));
371  bytestream_put_le16(bytestream, 5); // default delay
372  bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : (shrunk_palette_count ? map[bcid] : bcid));
373  bytestream_put_byte(bytestream, 0x00);
374 
375  /* image block */
376  bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR);
377  bytestream_put_le16(bytestream, x_start);
378  bytestream_put_le16(bytestream, y_start);
379  bytestream_put_le16(bytestream, width);
380  bytestream_put_le16(bytestream, height);
381 
382  if (palette || !s->use_global_palette) {
383  unsigned pow2_count = av_log2(shrunk_palette_count - 1);
384  unsigned i;
385 
386  bytestream_put_byte(bytestream, 1<<7 | pow2_count); /* flags */
387  for (i = 0; i < 1 << (pow2_count + 1); i++) {
388  const uint32_t v = shrunk_palette[i];
389  bytestream_put_be24(bytestream, v);
390  }
391  } else {
392  bytestream_put_byte(bytestream, 0x00); /* flags */
393  }
394 
395  bytestream_put_byte(bytestream, 0x08);
396 
397  ff_lzw_encode_init(s->lzw, s->buf, s->buf_size,
398  12, FF_LZW_GIF, 1);
399 
400  if (shrunk_palette_count) {
401  if (!s->shrunk_buf) {
402  s->shrunk_buf = av_malloc(avctx->height * linesize);
403  if (!s->shrunk_buf) {
404  av_log(avctx, AV_LOG_ERROR, "Could not allocated remapped frame buffer.\n");
405  return AVERROR(ENOMEM);
406  }
407  }
408  remap_frame_to_palette(buf, linesize, s->shrunk_buf, linesize, avctx->width, avctx->height, map);
409  ptr = s->shrunk_buf + y_start*linesize + x_start;
410  } else {
411  ptr = buf + y_start*linesize + x_start;
412  }
413  if (honor_transparency) {
414  const int ref_linesize = s->last_frame->linesize[0];
415  const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start;
416 
417  for (y = 0; y < height; y++) {
418  memcpy(s->tmpl, ptr, width);
419  for (x = 0; x < width; x++)
420  if (ref[x] == ptr[x])
421  s->tmpl[x] = trans;
422  len += ff_lzw_encode(s->lzw, s->tmpl, width);
423  ptr += linesize;
424  ref += ref_linesize;
425  }
426  } else {
427  for (y = 0; y < height; y++) {
428  len += ff_lzw_encode(s->lzw, ptr, width);
429  ptr += linesize;
430  }
431  }
432  len += ff_lzw_encode_flush(s->lzw);
433 
434  ptr = s->buf;
435  while (len > 0) {
436  int size = FFMIN(255, len);
437  bytestream_put_byte(bytestream, size);
438  if (end - *bytestream < size)
439  return -1;
440  bytestream_put_buffer(bytestream, ptr, size);
441  ptr += size;
442  len -= size;
443  }
444  bytestream_put_byte(bytestream, 0x00); /* end of image block */
445  return 0;
446 }
447 
449 {
450  GIFContext *s = avctx->priv_data;
451 
452  if (avctx->width > 65535 || avctx->height > 65535) {
453  av_log(avctx, AV_LOG_ERROR, "GIF does not support resolutions above 65535x65535\n");
454  return AVERROR(EINVAL);
455  }
456 
457  s->transparent_index = -1;
458 
460  s->buf_size = avctx->width*avctx->height*2 + 1000;
461  s->buf = av_malloc(s->buf_size);
462  s->tmpl = av_malloc(avctx->width);
463  if (!s->tmpl || !s->buf || !s->lzw)
464  return AVERROR(ENOMEM);
465 
466  if (avpriv_set_systematic_pal2(s->palette, avctx->pix_fmt) < 0)
468 
469  return 0;
470 }
471 
473  const AVFrame *pict, int *got_packet)
474 {
475  GIFContext *s = avctx->priv_data;
476  uint8_t *outbuf_ptr, *end;
477  const uint32_t *palette = NULL;
478  int ret;
479 
480  if ((ret = ff_alloc_packet(avctx, pkt, avctx->width*avctx->height*7/5 + AV_INPUT_BUFFER_MIN_SIZE)) < 0)
481  return ret;
482  outbuf_ptr = pkt->data;
483  end = pkt->data + pkt->size;
484 
485  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
486  palette = (uint32_t*)pict->data[1];
487 
488  if (!s->palette_loaded) {
489  memcpy(s->palette, palette, AVPALETTE_SIZE);
490  s->transparent_index = get_palette_transparency_index(palette);
491  s->palette_loaded = 1;
492  } else if (!memcmp(s->palette, palette, AVPALETTE_SIZE)) {
493  palette = NULL;
494  }
495  }
496 
497  gif_image_write_image(avctx, &outbuf_ptr, end, palette,
498  pict->data[0], pict->linesize[0], pkt);
499  if (!s->last_frame && !s->image) {
500  s->last_frame = av_frame_alloc();
501  if (!s->last_frame)
502  return AVERROR(ENOMEM);
503  }
504 
505  if (!s->image) {
506  av_frame_unref(s->last_frame);
507  ret = av_frame_ref(s->last_frame, pict);
508  if (ret < 0)
509  return ret;
510  }
511 
512  pkt->size = outbuf_ptr - pkt->data;
513  if (s->image || !avctx->frame_num)
515  *got_packet = 1;
516 
517  return 0;
518 }
519 
521 {
522  GIFContext *s = avctx->priv_data;
523 
524  av_freep(&s->lzw);
525  av_freep(&s->buf);
526  av_freep(&s->shrunk_buf);
527  s->buf_size = 0;
528  av_frame_free(&s->last_frame);
529  av_freep(&s->tmpl);
530  return 0;
531 }
532 
533 #define OFFSET(x) offsetof(GIFContext, x)
534 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
535 static const AVOption gif_options[] = {
536  { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" },
537  { "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" },
538  { "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, "flags" },
539  { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
540  { "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 },
541  { NULL }
542 };
543 
544 static const AVClass gif_class = {
545  .class_name = "GIF encoder",
546  .item_name = av_default_item_name,
547  .option = gif_options,
548  .version = LIBAVUTIL_VERSION_INT,
549 };
550 
552  .p.name = "gif",
553  CODEC_LONG_NAME("GIF (Graphics Interchange Format)"),
554  .p.type = AVMEDIA_TYPE_VIDEO,
555  .p.id = AV_CODEC_ID_GIF,
557  .priv_data_size = sizeof(GIFContext),
560  .close = gif_encode_close,
561  .p.pix_fmts = (const enum AVPixelFormat[]){
564  },
565  .p.priv_class = &gif_class,
566  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
567 };
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
GIFContext::buf
uint8_t * buf
Definition: gif.c:46
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:42
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:96
FLAGS
#define FLAGS
Definition: gif.c:534
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
w
uint8_t w
Definition: llviddspenc.c:38
AVPacket::data
uint8_t * data
Definition: packet.h:374
AVOption
AVOption.
Definition: opt.h:251
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:87
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:520
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:429
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:351
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:151
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
ff_gif_encoder
const FFCodec ff_gif_encoder
Definition: gif.c:551
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:289
GIFContext::palette
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
Definition: gif.c:53
GIFContext::transparent_index
int transparent_index
Definition: gif.c:55
DEFAULT_TRANSPARENCY_INDEX
#define DEFAULT_TRANSPARENCY_INDEX
Definition: gif.c:41
shrink_palette
static void shrink_palette(const uint32_t *src, uint8_t *map, uint32_t *dst, size_t *palette_count)
Definition: gif.c:64
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:315
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:87
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:83
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:256
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
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:156
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:201
LZWState
Definition: lzw.c:46
AV_INPUT_BUFFER_MIN_SIZE
#define AV_INPUT_BUFFER_MIN_SIZE
Definition: avcodec.h:191
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:272
if
if(ret)
Definition: filter_design.txt:179
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
GIFContext::tmpl
uint8_t * tmpl
temporary line buffer
Definition: gif.c:56
GIFContext::flags
int flags
Definition: gif.c:50
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:51
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
GIFContext::shrunk_buf
uint8_t * shrunk_buf
Definition: gif.c:47
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
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:85
OFFSET
#define OFFSET(x)
Definition: gif.c:533
GIFContext::use_global_palette
int use_global_palette
Definition: gif.c:52
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:375
get_palette_transparency_index
static int get_palette_transparency_index(const uint32_t *palette)
Definition: gif.c:117
av_frame_ref
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:344
codec_internal.h
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:448
GIFContext
Definition: gif.c:43
GIFContext::buf_size
int buf_size
Definition: gif.c:48
height
#define height
GIFContext::palette_loaded
int palette_loaded
Definition: gif.c:54
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:380
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:269
GIF_EXTENSION_INTRODUCER
#define GIF_EXTENSION_INTRODUCER
Definition: gif.h:43
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:478
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:254
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:191
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:544
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:88
AVCodecContext::height
int height
Definition: avcodec.h:598
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:635
avcodec.h
GF_TRANSDIFF
@ GF_TRANSDIFF
Definition: gif.c:61
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
AVCodecContext::frame_num
int64_t frame_num
Frame counter, set by libavcodec.
Definition: avcodec.h:2065
ret
ret
Definition: filter_design.txt:187
GIFContext::last_frame
AVFrame * last_frame
Definition: gif.c:49
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:71
gif_options
static const AVOption gif_options[]
Definition: gif.c:535
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:230
AVCodecContext
main external API structure.
Definition: avcodec.h:426
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
GIFContext::lzw
LZWState * lzw
Definition: gif.c:45
GF_OFFSETTING
@ GF_OFFSETTING
Definition: gif.c:60
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:453
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
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:598
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:224
bytestream.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
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:375
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:472
GCE_DISPOSAL_INPLACE
#define GCE_DISPOSAL_INPLACE
Definition: gif.h:38
h
h
Definition: vp9dsp_template.c:2038
pick_palette_entry
static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
Definition: gif.c:135
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
Definition: opt.h:234
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:35