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;
50  int buf_size;
52  int flags;
53  int image;
54  uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8
57  uint8_t *tmpl; ///< temporary line buffer
58 } GIFContext;
59 
60 enum {
61  GF_OFFSETTING = 1<<0,
62  GF_TRANSDIFF = 1<<1,
63 };
64 
66  const uint8_t *buf, const int linesize)
67 {
68  GIFContext *s = avctx->priv_data;
69  int trans = s->transparent_index;
70 
71  if (trans < 0)
72  return 0;
73 
74  for (int y = 0; y < avctx->height; y++) {
75  for (int x = 0; x < avctx->width; x++) {
76  if (buf[x] == trans) {
77  return 1;
78  }
79  }
80  buf += linesize;
81  }
82 
83  return 0;
84 }
85 
86 static int get_palette_transparency_index(const uint32_t *palette)
87 {
88  int transparent_color_index = -1;
89  unsigned i, smallest_alpha = 0xff;
90 
91  if (!palette)
92  return -1;
93 
94  for (i = 0; i < AVPALETTE_COUNT; i++) {
95  const uint32_t v = palette[i];
96  if (v >> 24 < smallest_alpha) {
97  smallest_alpha = v >> 24;
98  transparent_color_index = i;
99  }
100  }
101  return smallest_alpha < 128 ? transparent_color_index : -1;
102 }
103 
104 static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
105 {
106  int histogram[AVPALETTE_COUNT] = {0};
107  int x, y, i;
108 
109  for (y = 0; y < h; y++) {
110  for (x = 0; x < w; x++)
111  histogram[buf[x]]++;
112  buf += linesize;
113  }
114  for (i = 0; i < FF_ARRAY_ELEMS(histogram); i++)
115  if (!histogram[i])
116  return i;
117  return -1;
118 }
119 
121  const uint8_t *buf, const int linesize,
122  int *width, int *height,
123  int *x_start, int *y_start)
124 {
125  GIFContext *s = avctx->priv_data;
126  int trans = s->transparent_index;
127 
128  /* Crop image */
129  if ((s->flags & GF_OFFSETTING) && trans >= 0) {
130  const int w = avctx->width;
131  const int h = avctx->height;
132  int x_end = w - 1,
133  y_end = h - 1;
134 
135  // crop top
136  while (*y_start < y_end) {
137  int is_trans = 1;
138  for (int i = 0; i < w; i++) {
139  if (buf[linesize * *y_start + i] != trans) {
140  is_trans = 0;
141  break;
142  }
143  }
144 
145  if (!is_trans)
146  break;
147  (*y_start)++;
148  }
149 
150  // crop bottom
151  while (y_end > *y_start) {
152  int is_trans = 1;
153  for (int i = 0; i < w; i++) {
154  if (buf[linesize * y_end + i] != trans) {
155  is_trans = 0;
156  break;
157  }
158  }
159  if (!is_trans)
160  break;
161  y_end--;
162  }
163 
164  // crop left
165  while (*x_start < x_end) {
166  int is_trans = 1;
167  for (int i = *y_start; i < y_end; i++) {
168  if (buf[linesize * i + *x_start] != trans) {
169  is_trans = 0;
170  break;
171  }
172  }
173  if (!is_trans)
174  break;
175  (*x_start)++;
176  }
177 
178  // crop right
179  while (x_end > *x_start) {
180  int is_trans = 1;
181  for (int i = *y_start; i < y_end; i++) {
182  if (buf[linesize * i + x_end] != trans) {
183  is_trans = 0;
184  break;
185  }
186  }
187  if (!is_trans)
188  break;
189  x_end--;
190  }
191 
192  *height = y_end + 1 - *y_start;
193  *width = x_end + 1 - *x_start;
194  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
195  *width, *height, *x_start, *y_start, avctx->width, avctx->height);
196  }
197 }
198 
199 static void gif_crop_opaque(AVCodecContext *avctx,
200  const uint32_t *palette,
201  const uint8_t *buf, const int linesize,
202  int *width, int *height, int *x_start, int *y_start)
203 {
204  GIFContext *s = avctx->priv_data;
205 
206  /* Crop image */
207  if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
208  const uint8_t *ref = s->last_frame->data[0];
209  const int ref_linesize = s->last_frame->linesize[0];
210  int x_end = avctx->width - 1,
211  y_end = avctx->height - 1;
212 
213  /* skip common lines */
214  while (*y_start < y_end) {
215  if (memcmp(ref + *y_start*ref_linesize, buf + *y_start*linesize, *width))
216  break;
217  (*y_start)++;
218  }
219  while (y_end > *y_start) {
220  if (memcmp(ref + y_end*ref_linesize, buf + y_end*linesize, *width))
221  break;
222  y_end--;
223  }
224  *height = y_end + 1 - *y_start;
225 
226  /* skip common columns */
227  while (*x_start < x_end) {
228  int same_column = 1;
229  for (int y = *y_start; y <= y_end; y++) {
230  if (ref[y*ref_linesize + *x_start] != buf[y*linesize + *x_start]) {
231  same_column = 0;
232  break;
233  }
234  }
235  if (!same_column)
236  break;
237  (*x_start)++;
238  }
239  while (x_end > *x_start) {
240  int same_column = 1;
241  for (int y = *y_start; y <= y_end; y++) {
242  if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) {
243  same_column = 0;
244  break;
245  }
246  }
247  if (!same_column)
248  break;
249  x_end--;
250  }
251  *width = x_end + 1 - *x_start;
252 
253  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
254  *width, *height, *x_start, *y_start, avctx->width, avctx->height);
255  }
256 }
257 
259  uint8_t **bytestream, uint8_t *end,
260  const uint32_t *palette,
261  const uint8_t *buf, const int linesize,
262  AVPacket *pkt)
263 {
264  GIFContext *s = avctx->priv_data;
265  int disposal, len = 0, height = avctx->height, width = avctx->width, x, y;
266  int x_start = 0, y_start = 0, trans = s->transparent_index;
267  int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette;
268  const uint8_t *ptr;
269 
270  if (!s->image && avctx->frame_number && is_image_translucent(avctx, buf, linesize)) {
271  gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start);
272  honor_transparency = 0;
273  disposal = GCE_DISPOSAL_BACKGROUND;
274  } else {
275  gif_crop_opaque(avctx, palette, buf, linesize, &width, &height, &x_start, &y_start);
276  disposal = GCE_DISPOSAL_INPLACE;
277  }
278 
279  if (s->image || !avctx->frame_number) { /* GIF header */
280  const uint32_t *global_palette = palette ? palette : s->palette;
281  const AVRational sar = avctx->sample_aspect_ratio;
282  int64_t aspect = 0;
283 
284  if (sar.num > 0 && sar.den > 0) {
285  aspect = sar.num * 64LL / sar.den - 15;
286  if (aspect < 0 || aspect > 255)
287  aspect = 0;
288  }
289 
290  bytestream_put_buffer(bytestream, gif89a_sig, sizeof(gif89a_sig));
291  bytestream_put_le16(bytestream, avctx->width);
292  bytestream_put_le16(bytestream, avctx->height);
293 
294  bcid = get_palette_transparency_index(global_palette);
295 
296  bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */
297  bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); /* background color index */
298  bytestream_put_byte(bytestream, aspect);
299  for (int i = 0; i < 256; i++) {
300  const uint32_t v = global_palette[i] & 0xffffff;
301  bytestream_put_be24(bytestream, v);
302  }
303  }
304 
305  if (honor_transparency && trans < 0) {
306  trans = pick_palette_entry(buf + y_start*linesize + x_start,
307  linesize, width, height);
308  if (trans < 0) // TODO, patch welcome
309  av_log(avctx, AV_LOG_DEBUG, "No available color, can not use transparency\n");
310  }
311 
312  if (trans < 0)
313  honor_transparency = 0;
314 
315  bcid = honor_transparency || disposal == GCE_DISPOSAL_BACKGROUND ? trans : get_palette_transparency_index(palette);
316 
317  /* graphic control extension */
318  bytestream_put_byte(bytestream, GIF_EXTENSION_INTRODUCER);
319  bytestream_put_byte(bytestream, GIF_GCE_EXT_LABEL);
320  bytestream_put_byte(bytestream, 0x04); /* block size */
321  bytestream_put_byte(bytestream, disposal<<2 | (bcid >= 0));
322  bytestream_put_le16(bytestream, 5); // default delay
323  bytestream_put_byte(bytestream, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid);
324  bytestream_put_byte(bytestream, 0x00);
325 
326  /* image block */
327  bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR);
328  bytestream_put_le16(bytestream, x_start);
329  bytestream_put_le16(bytestream, y_start);
330  bytestream_put_le16(bytestream, width);
331  bytestream_put_le16(bytestream, height);
332 
333  if (!palette) {
334  bytestream_put_byte(bytestream, 0x00); /* flags */
335  } else {
336  unsigned i;
337  bytestream_put_byte(bytestream, 1<<7 | 0x7); /* flags */
338  for (i = 0; i < AVPALETTE_COUNT; i++) {
339  const uint32_t v = palette[i];
340  bytestream_put_be24(bytestream, v);
341  }
342  }
343 
344  bytestream_put_byte(bytestream, 0x08);
345 
346  ff_lzw_encode_init(s->lzw, s->buf, s->buf_size,
347  12, FF_LZW_GIF, put_bits);
348 
349  ptr = buf + y_start*linesize + x_start;
350  if (honor_transparency) {
351  const int ref_linesize = s->last_frame->linesize[0];
352  const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start;
353 
354  for (y = 0; y < height; y++) {
355  memcpy(s->tmpl, ptr, width);
356  for (x = 0; x < width; x++)
357  if (ref[x] == ptr[x])
358  s->tmpl[x] = trans;
359  len += ff_lzw_encode(s->lzw, s->tmpl, width);
360  ptr += linesize;
361  ref += ref_linesize;
362  }
363  } else {
364  for (y = 0; y < height; y++) {
365  len += ff_lzw_encode(s->lzw, ptr, width);
366  ptr += linesize;
367  }
368  }
370 
371  ptr = s->buf;
372  while (len > 0) {
373  int size = FFMIN(255, len);
374  bytestream_put_byte(bytestream, size);
375  if (end - *bytestream < size)
376  return -1;
377  bytestream_put_buffer(bytestream, ptr, size);
378  ptr += size;
379  len -= size;
380  }
381  bytestream_put_byte(bytestream, 0x00); /* end of image block */
382  return 0;
383 }
384 
386 {
387  GIFContext *s = avctx->priv_data;
388 
389  if (avctx->width > 65535 || avctx->height > 65535) {
390  av_log(avctx, AV_LOG_ERROR, "GIF does not support resolutions above 65535x65535\n");
391  return AVERROR(EINVAL);
392  }
393 
394  s->transparent_index = -1;
395 
397  s->buf_size = avctx->width*avctx->height*2 + 1000;
398  s->buf = av_malloc(s->buf_size);
399  s->tmpl = av_malloc(avctx->width);
400  if (!s->tmpl || !s->buf || !s->lzw)
401  return AVERROR(ENOMEM);
402 
403  if (avpriv_set_systematic_pal2(s->palette, avctx->pix_fmt) < 0)
405 
406  return 0;
407 }
408 
410  const AVFrame *pict, int *got_packet)
411 {
412  GIFContext *s = avctx->priv_data;
413  uint8_t *outbuf_ptr, *end;
414  const uint32_t *palette = NULL;
415  int ret;
416 
417  if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*7/5 + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
418  return ret;
419  outbuf_ptr = pkt->data;
420  end = pkt->data + pkt->size;
421 
422  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
423  palette = (uint32_t*)pict->data[1];
424 
425  if (!s->palette_loaded) {
426  memcpy(s->palette, palette, AVPALETTE_SIZE);
427  s->transparent_index = get_palette_transparency_index(palette);
428  s->palette_loaded = 1;
429  } else if (!memcmp(s->palette, palette, AVPALETTE_SIZE)) {
430  palette = NULL;
431  }
432  }
433 
434  gif_image_write_image(avctx, &outbuf_ptr, end, palette,
435  pict->data[0], pict->linesize[0], pkt);
436  if (!s->last_frame && !s->image) {
437  s->last_frame = av_frame_alloc();
438  if (!s->last_frame)
439  return AVERROR(ENOMEM);
440  }
441 
442  if (!s->image) {
443  av_frame_unref(s->last_frame);
444  ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
445  if (ret < 0)
446  return ret;
447  }
448 
449  pkt->size = outbuf_ptr - pkt->data;
450  if (s->image || !avctx->frame_number)
452  *got_packet = 1;
453 
454  return 0;
455 }
456 
458 {
459  GIFContext *s = avctx->priv_data;
460 
461  av_freep(&s->lzw);
462  av_freep(&s->buf);
463  s->buf_size = 0;
464  av_frame_free(&s->last_frame);
465  av_freep(&s->tmpl);
466  return 0;
467 }
468 
469 #define OFFSET(x) offsetof(GIFContext, x)
470 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
471 static const AVOption gif_options[] = {
472  { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" },
473  { "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" },
474  { "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, "flags" },
475  { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
476  { NULL }
477 };
478 
479 static const AVClass gif_class = {
480  .class_name = "GIF encoder",
481  .item_name = av_default_item_name,
482  .option = gif_options,
483  .version = LIBAVUTIL_VERSION_INT,
484 };
485 
487  .name = "gif",
488  .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
489  .type = AVMEDIA_TYPE_VIDEO,
490  .id = AV_CODEC_ID_GIF,
491  .priv_data_size = sizeof(GIFContext),
493  .encode2 = gif_encode_frame,
494  .close = gif_encode_close,
495  .pix_fmts = (const enum AVPixelFormat[]){
498  },
499  .priv_class = &gif_class,
500 };
AVCodec
AVCodec.
Definition: avcodec.h:3481
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
GIFContext::buf
uint8_t * buf
Definition: gif.c:49
ff_lzw_encode_init
void ff_lzw_encode_init(struct LZWEncodeState *s, uint8_t *outbuf, int outsize, int maxbits, enum FF_LZW_MODES mode, void(*lzw_put_bits)(struct PutBitContext *, int, unsigned int))
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
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:65
FLAGS
#define FLAGS
Definition: gif.c:470
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:208
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
AVOption
AVOption.
Definition: opt.h:246
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:457
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
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:120
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:258
GIFContext::palette
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
Definition: gif.c:54
GIFContext::transparent_index
int transparent_index
Definition: gif.c:56
DEFAULT_TRANSPARENCY_INDEX
#define DEFAULT_TRANSPARENCY_INDEX
Definition: gif.c:44
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:189
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
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
av_cold
#define av_cold
Definition: attributes.h:84
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
GF_TRANSDIFF
@ GF_TRANSDIFF
Definition: gif.c:62
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:275
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:197
LZWState
Definition: lzw.c:46
AV_INPUT_BUFFER_MIN_SIZE
#define AV_INPUT_BUFFER_MIN_SIZE
Definition: avcodec.h:797
avpriv_set_systematic_pal2
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:152
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:57
GIFContext::flags
int flags
Definition: gif.c:52
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
GF_OFFSETTING
@ GF_OFFSETTING
Definition: gif.c:61
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:191
GIFContext::image
int image
Definition: gif.c:53
AV_PIX_FMT_RGB8
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
FF_LZW_GIF
@ FF_LZW_GIF
Definition: lzw.h:38
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:469
AVPacket::size
int size
Definition: avcodec.h:1478
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:188
get_palette_transparency_index
static int get_palette_transparency_index(const uint32_t *palette)
Definition: gif.c:86
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:443
lzw.h
LZW decoding routines.
gif.h
size
int size
Definition: twinvq_data.h:11134
gif_encode_init
static av_cold int gif_encode_init(AVCodecContext *avctx)
Definition: gif.c:385
GIFContext
Definition: gif.c:46
GIFContext::buf_size
int buf_size
Definition: gif.c:50
height
#define height
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
GIFContext::palette_loaded
int palette_loaded
Definition: gif.c:55
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
AV_CODEC_ID_GIF
@ AV_CODEC_ID_GIF
Definition: avcodec.h:315
bytestream_put_buffer
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:368
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
ff_gif_encoder
AVCodec ff_gif_encoder
Definition: gif.c:486
GIF_EXTENSION_INTRODUCER
#define GIF_EXTENSION_INTRODUCER
Definition: gif.h:43
uint8_t
uint8_t
Definition: audio_convert.c:194
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
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:236
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
gif_class
static const AVClass gif_class
Definition: gif.c:479
len
int len
Definition: vorbis_enc_data.h:452
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:1738
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
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: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:72
gif_options
static const AVOption gif_options[]
Definition: gif.c:471
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
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:199
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
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
ff_lzw_encode_flush
int ff_lzw_encode_flush(struct LZWEncodeState *s, void(*lzw_flush_put_bits)(struct PutBitContext *))
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecContext::frame_number
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2256
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:101
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
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:1738
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:222
bytestream.h
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
gif_encode_frame
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: gif.c:409
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:104
ff_lzw_encode
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
Definition: lzwenc.c:227
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:32
put_bits.h
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
AVCodecContext::sample_aspect_ratio
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:1944