FFmpeg  4.4
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;
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,
568  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
569 };
#define av_cold
Definition: attributes.h:88
uint8_t
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:372
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
#define NULL
Definition: coverity.c:32
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
GIF format definitions.
#define GIF_IMAGE_SEPARATOR
Definition: gif.h:44
static const uint8_t gif89a_sig[6]
Definition: gif.h:35
#define GCE_DISPOSAL_INPLACE
Definition: gif.h:38
#define GIF_EXTENSION_INTRODUCER
Definition: gif.h:43
#define GIF_GCE_EXT_LABEL
Definition: gif.h:45
#define GCE_DISPOSAL_BACKGROUND
Definition: gif.h:39
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:224
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
@ AV_CODEC_ID_GIF
Definition: codec_id.h:146
#define AV_INPUT_BUFFER_MIN_SIZE
minimum encoding buffer size Used to avoid some checks during header writing.
Definition: avcodec.h:222
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:410
#define AVERROR(e)
Definition: error.h:43
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
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
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
const VDPAUPixFmtMap * map
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:176
misc image utilities
int i
Definition: input.c:407
#define av_log2
Definition: intmath.h:83
static const AVOption gif_options[]
Definition: gif.c:538
static int is_image_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize)
Definition: gif.c:99
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
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
Definition: gif.c:475
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
static av_cold int gif_encode_init(AVCodecContext *avctx)
Definition: gif.c:451
static void shrink_palette(const uint32_t *src, uint8_t *map, uint32_t *dst, size_t *palette_count)
Definition: gif.c:67
#define FLAGS
Definition: gif.c:537
static const AVClass gif_class
Definition: gif.c:547
static int get_palette_transparency_index(const uint32_t *palette)
Definition: gif.c:120
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
static int gif_encode_close(AVCodecContext *avctx)
Definition: gif.c:523
static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
Definition: gif.c:138
AVCodec ff_gif_encoder
Definition: gif.c:554
#define OFFSET(x)
Definition: gif.c:536
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
@ GF_OFFSETTING
Definition: gif.c:63
@ GF_TRANSDIFF
Definition: gif.c:64
#define DEFAULT_TRANSPARENCY_INDEX
Definition: gif.c:44
#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
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:303
uint8_t w
Definition: llviddspenc.c:39
LZW decoding routines.
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
const int ff_lzw_encode_state_size
Definition: lzwenc.c:67
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
Definition: lzwenc.c:229
@ FF_LZW_GIF
Definition: lzw.h:38
int ff_lzw_encode_flush(struct LZWEncodeState *s)
Write end code and flush bitstream.
Definition: lzwenc.c:262
AVOptions.
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:86
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:88
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:85
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
#define AVPALETTE_COUNT
Definition: pixfmt.h:33
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
bitstream writer API
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
Definition: log.h:67
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
main external API structure.
Definition: avcodec.h:536
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
int width
picture width / height.
Definition: avcodec.h:709
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:1227
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
AVOption.
Definition: opt.h:248
This structure stores compressed data.
Definition: packet.h:346
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:375
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int num
Numerator.
Definition: rational.h:59
int den
Denominator.
Definition: rational.h:60
Definition: gif.c:46
int image
Definition: gif.c:54
int palette_loaded
Definition: gif.c:57
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
Definition: gif.c:56
int buf_size
Definition: gif.c:51
uint8_t * tmpl
temporary line buffer
Definition: gif.c:59
int use_global_palette
Definition: gif.c:55
uint8_t * shrunk_buf
Definition: gif.c:50
int flags
Definition: gif.c:53
int transparent_index
Definition: gif.c:58
AVFrame * last_frame
Definition: gif.c:52
LZWState * lzw
Definition: gif.c:48
uint8_t * buf
Definition: gif.c:49
Definition: lzw.c:46
#define av_freep(p)
#define av_malloc(s)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
AVPacket * pkt
Definition: movenc.c:59
#define height
#define width
int size
if(ret< 0)
Definition: vf_mcdeint.c:282
int len
static double c[64]