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);
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) {
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)
451  pkt->flags |= AV_PKT_FLAG_KEY;
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;
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 };
#define NULL
Definition: coverity.c:32
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
Definition: gif.c:54
misc image utilities
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:208
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define GCE_DISPOSAL_BACKGROUND
Definition: gif.h:39
static int get_palette_transparency_index(const uint32_t *palette)
Definition: gif.c:86
int num
Numerator.
Definition: rational.h:59
int size
Definition: avcodec.h:1484
static int gif_encode_close(AVCodecContext *avctx)
Definition: gif.c:457
static const AVClass gif_class
Definition: gif.c:479
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
Definition: lzwenc.c:227
#define GIF_GCE_EXT_LABEL
Definition: gif.h:45
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:1950
AVCodec ff_gif_encoder
Definition: gif.c:486
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1781
int image
Definition: gif.c:53
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
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3495
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:189
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
AVOptions.
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:152
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
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
int buf_size
Definition: gif.c:50
#define height
uint8_t * data
Definition: avcodec.h:1483
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
ptrdiff_t size
Definition: opengl_enc.c:100
uint8_t * tmpl
temporary line buffer
Definition: gif.c:57
int flags
Definition: gif.c:52
#define AV_INPUT_BUFFER_MIN_SIZE
minimum encoding buffer size Used to avoid some checks during header writing.
Definition: avcodec.h:803
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1515
#define FLAGS
Definition: gif.c:470
int ff_lzw_encode_flush(struct LZWEncodeState *s, void(*lzw_flush_put_bits)(struct PutBitContext *))
Definition: lzw.c:46
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
LZWState * lzw
Definition: gif.c:48
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
Definition: gif.c:46
const char * name
Name of the codec implementation.
Definition: avcodec.h:3502
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1489
#define OFFSET(x)
Definition: gif.c:469
#define GIF_IMAGE_SEPARATOR
Definition: gif.h:44
#define FFMIN(a, b)
Definition: common.h:96
Definition: lzw.h:38
static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
Definition: gif.c:104
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
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
#define width
int width
picture width / height.
Definition: avcodec.h:1744
uint8_t w
Definition: llviddspenc.c:38
#define s(width, name)
Definition: cbs_vp9.c:257
#define GIF_EXTENSION_INTRODUCER
Definition: gif.h:43
#define FF_ARRAY_ELEMS(a)
if(ret)
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
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
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
GIF format definitions.
main external API structure.
Definition: avcodec.h:1571
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: gif.c:409
Describe the class of an AVClass context structure.
Definition: log.h:67
Rational number (pair of numerator and denominator).
Definition: rational.h:58
uint8_t * buf
Definition: gif.c:49
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
#define AVPALETTE_COUNT
Definition: pixfmt.h:33
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
#define GCE_DISPOSAL_INPLACE
Definition: gif.h:38
LZW decoding routines.
static int is_image_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize)
Definition: gif.c:65
Y , 8bpp.
Definition: pixfmt.h:74
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))
common internal api header.
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:101
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
static const uint8_t gif89a_sig[6]
Definition: gif.h:35
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
int den
Denominator.
Definition: rational.h:60
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:368
void * priv_data
Definition: avcodec.h:1598
AVFrame * last_frame
Definition: gif.c:51
int len
static av_cold int gif_encode_init(AVCodecContext *avctx)
Definition: gif.c:385
int transparent_index
Definition: gif.c:56
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2262
#define av_freep(p)
int palette_loaded
Definition: gif.c:55
const int ff_lzw_encode_state_size
Definition: lzwenc.c:67
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
static const AVOption gif_options[]
Definition: gif.c:471
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1460
#define DEFAULT_TRANSPARENCY_INDEX
Definition: gif.c:44
bitstream writer API