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