libavcodec/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  *
6  * first version by Francois Revol <revol@free.fr>
7  *
8  * This file is part of FFmpeg.
9  *
10  * FFmpeg is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * FFmpeg is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with FFmpeg; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 /**
26  * @file
27  * GIF encoder
28  * @see http://www.w3.org/Graphics/GIF/spec-gif89a.txt
29  */
30 
31 #include "libavutil/opt.h"
32 #include "libavutil/imgutils.h"
33 #include "avcodec.h"
34 #include "bytestream.h"
35 #include "internal.h"
36 #include "lzw.h"
37 #include "gif.h"
38 
39 #define BITSTREAM_WRITER_LE
40 #include "put_bits.h"
41 
42 typedef struct {
43  const AVClass *class;
48  int flags;
49  uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8
50  uint8_t *tmpl; ///< temporary line buffer
51 } GIFContext;
52 
53 enum {
54  GF_OFFSETTING = 1<<0,
55  GF_TRANSDIFF = 1<<1,
56 };
57 
58 static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
59 {
60  int histogram[AVPALETTE_COUNT] = {0};
61  int x, y, i;
62 
63  for (y = 0; y < h; y++) {
64  for (x = 0; x < w; x++)
65  histogram[buf[x]]++;
66  buf += linesize;
67  }
68  for (i = 0; i < FF_ARRAY_ELEMS(histogram); i++)
69  if (!histogram[i])
70  return i;
71  return -1;
72 }
73 
75  uint8_t **bytestream, uint8_t *end,
76  const uint32_t *palette,
77  const uint8_t *buf, const int linesize,
78  AVPacket *pkt)
79 {
80  GIFContext *s = avctx->priv_data;
81  int len = 0, height = avctx->height, width = avctx->width, x, y;
82  int x_start = 0, y_start = 0, trans = -1;
83  const uint8_t *ptr;
84 
85  /* Crop image */
86  // TODO support with palette change
87  if ((s->flags & GF_OFFSETTING) && s->last_frame && !palette) {
88  const uint8_t *ref = s->last_frame->data[0];
89  const int ref_linesize = s->last_frame->linesize[0];
90  int x_end = avctx->width - 1,
91  y_end = avctx->height - 1;
92 
93  /* skip common lines */
94  while (y_start < y_end) {
95  if (memcmp(ref + y_start*ref_linesize, buf + y_start*linesize, width))
96  break;
97  y_start++;
98  }
99  while (y_end > y_start) {
100  if (memcmp(ref + y_end*ref_linesize, buf + y_end*linesize, width))
101  break;
102  y_end--;
103  }
104  height = y_end + 1 - y_start;
105 
106  /* skip common columns */
107  while (x_start < x_end) {
108  int same_column = 1;
109  for (y = y_start; y < y_end; y++) {
110  if (ref[y*ref_linesize + x_start] != buf[y*linesize + x_start]) {
111  same_column = 0;
112  break;
113  }
114  }
115  if (!same_column)
116  break;
117  x_start++;
118  }
119  while (x_end > x_start) {
120  int same_column = 1;
121  for (y = y_start; y < y_end; y++) {
122  if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) {
123  same_column = 0;
124  break;
125  }
126  }
127  if (!same_column)
128  break;
129  x_end--;
130  }
131  width = x_end + 1 - x_start;
132 
133  av_log(avctx, AV_LOG_DEBUG,"%dx%d image at pos (%d;%d) [area:%dx%d]\n",
134  width, height, x_start, y_start, avctx->width, avctx->height);
135  }
136 
137  /* image block */
138  bytestream_put_byte(bytestream, GIF_IMAGE_SEPARATOR);
139  bytestream_put_le16(bytestream, x_start);
140  bytestream_put_le16(bytestream, y_start);
141  bytestream_put_le16(bytestream, width);
142  bytestream_put_le16(bytestream, height);
143 
144  if (!palette) {
145  bytestream_put_byte(bytestream, 0x00); /* flags */
146  } else {
147  unsigned i;
148  bytestream_put_byte(bytestream, 1<<7 | 0x7); /* flags */
149  for (i = 0; i < AVPALETTE_COUNT; i++) {
150  const uint32_t v = palette[i];
151  bytestream_put_be24(bytestream, v);
152  }
153  }
154 
155  /* TODO: support with palette change (pal8) */
156  if ((s->flags & GF_TRANSDIFF) && s->last_frame && !palette) {
157  trans = pick_palette_entry(buf + y_start*linesize + x_start,
158  linesize, width, height);
159  if (trans < 0) { // TODO, patch welcome
160  av_log(avctx, AV_LOG_DEBUG, "No available color, can not use transparency\n");
161  } else {
163  if (!pal_exdata)
164  return AVERROR(ENOMEM);
165  memcpy(pal_exdata, s->palette, AVPALETTE_SIZE);
166  pal_exdata[trans*4 + 3] = 0x00;
167  }
168  }
169 
170  bytestream_put_byte(bytestream, 0x08);
171 
173  12, FF_LZW_GIF, put_bits);
174 
175  ptr = buf + y_start*linesize + x_start;
176  if (trans >= 0) {
177  const int ref_linesize = s->last_frame->linesize[0];
178  const uint8_t *ref = s->last_frame->data[0] + y_start*ref_linesize + x_start;
179 
180  for (y = 0; y < height; y++) {
181  memcpy(s->tmpl, ptr, width);
182  for (x = 0; x < width; x++)
183  if (ref[x] == ptr[x])
184  s->tmpl[x] = trans;
185  len += ff_lzw_encode(s->lzw, s->tmpl, width);
186  ptr += linesize;
187  ref += ref_linesize;
188  }
189  } else {
190  for (y = 0; y < height; y++) {
191  len += ff_lzw_encode(s->lzw, ptr, width);
192  ptr += linesize;
193  }
194  }
196 
197  ptr = s->buf;
198  while (len > 0) {
199  int size = FFMIN(255, len);
200  bytestream_put_byte(bytestream, size);
201  if (end - *bytestream < size)
202  return -1;
203  bytestream_put_buffer(bytestream, ptr, size);
204  ptr += size;
205  len -= size;
206  }
207  bytestream_put_byte(bytestream, 0x00); /* end of image block */
208  return 0;
209 }
210 
212 {
213  GIFContext *s = avctx->priv_data;
214 
215  if (avctx->width > 65535 || avctx->height > 65535) {
216  av_log(avctx, AV_LOG_ERROR, "GIF does not support resolutions above 65535x65535\n");
217  return AVERROR(EINVAL);
218  }
219 
220  avctx->coded_frame = &s->picture;
222  s->buf = av_malloc(avctx->width*avctx->height*2);
223  s->tmpl = av_malloc(avctx->width);
224  if (!s->tmpl || !s->buf || !s->lzw)
225  return AVERROR(ENOMEM);
226 
227  if (avpriv_set_systematic_pal2(s->palette, avctx->pix_fmt) < 0)
229 
230  return 0;
231 }
232 
234  const AVFrame *pict, int *got_packet)
235 {
236  GIFContext *s = avctx->priv_data;
237  AVFrame *const p = &s->picture;
238  uint8_t *outbuf_ptr, *end;
239  const uint32_t *palette = NULL;
240  int ret;
241 
242  if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*7/5 + FF_MIN_BUFFER_SIZE)) < 0)
243  return ret;
244  outbuf_ptr = pkt->data;
245  end = pkt->data + pkt->size;
246 
247  *p = *pict;
249  p->key_frame = 1;
250 
251  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
253  if (!pal_exdata)
254  return AVERROR(ENOMEM);
255  memcpy(pal_exdata, p->data[1], AVPALETTE_SIZE);
256  palette = (uint32_t*)p->data[1];
257  }
258 
259  gif_image_write_image(avctx, &outbuf_ptr, end, palette,
260  pict->data[0], pict->linesize[0], pkt);
261  if (!s->last_frame) {
262  s->last_frame = av_frame_alloc();
263  if (!s->last_frame)
264  return AVERROR(ENOMEM);
265  }
267  ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
268  if (ret < 0)
269  return ret;
270 
271  pkt->size = outbuf_ptr - pkt->data;
272  pkt->flags |= AV_PKT_FLAG_KEY;
273  *got_packet = 1;
274 
275  return 0;
276 }
277 
279 {
280  GIFContext *s = avctx->priv_data;
281 
282  av_freep(&s->lzw);
283  av_freep(&s->buf);
285  av_freep(&s->tmpl);
286  return 0;
287 }
288 
289 #define OFFSET(x) offsetof(GIFContext, x)
290 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
291 static const AVOption gif_options[] = {
292  { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" },
293  { "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" },
294  { "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, "flags" },
295  { NULL }
296 };
297 
298 static const AVClass gif_class = {
299  .class_name = "GIF encoder",
300  .item_name = av_default_item_name,
301  .option = gif_options,
302  .version = LIBAVUTIL_VERSION_INT,
303 };
304 
306  .name = "gif",
307  .type = AVMEDIA_TYPE_VIDEO,
308  .id = AV_CODEC_ID_GIF,
309  .priv_data_size = sizeof(GIFContext),
311  .encode2 = gif_encode_frame,
313  .pix_fmts = (const enum AVPixelFormat[]){
316  },
317  .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
318  .priv_class = &gif_class,
319 };
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
float v
const char * s
Definition: avisynth_c.h:668
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
FIXME Range Coding of cr are ref
Definition: snow.txt:367
AVOption.
Definition: opt.h:251
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
av_default_item_name
misc image utilities
AVFrame * coded_frame
the picture in the bitstream
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static int gif_encode_close(AVCodecContext *avctx)
static const AVClass gif_class
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
Definition: lzwenc.c:226
AVCodec ff_gif_encoder
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define FF_ARRAY_ELEMS(a)
output residual component w
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
Definition: pixfmt.h:89
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:55
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
#define av_cold
Definition: attributes.h:78
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
AVOptions.
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
static AVPacket pkt
Definition: demuxing.c:56
end end
uint8_t * data
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)
uint8_t * tmpl
temporary line buffer
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
#define FLAGS
int ff_lzw_encode_flush(struct LZWEncodeState *s, void(*lzw_flush_put_bits)(struct PutBitContext *))
Discrete Time axis x
Definition: lzw.c:45
LZWState * lzw
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:150
const char * name
Name of the codec implementation.
static void put_bits(J2kEncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:160
external API header
int size
int flags
A combination of AV_PKT_FLAG values.
#define OFFSET(x)
#define GIF_IMAGE_SEPARATOR
Definition: gif.h:44
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
#define FFMIN(a, b)
Definition: common.h:58
Definition: lzw.h:38
static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
Definition: pixfmt.h:92
#define FF_MIN_BUFFER_SIZE
minimum encoding buffer size Used to avoid some checks during header writing.
ret
Definition: avfilter.c:821
int width
picture width / height.
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
Check AVPacket size and/or allocate data.
NULL
Definition: eval.c:55
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:87
static int width
Definition: tests/utils.c:158
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
GIF format definitions.
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
void * buf
Definition: avisynth_c.h:594
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
synthesis window for stochastic i
uint8_t * buf
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:330
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define AVPALETTE_COUNT
Definition: pixfmt.h:34
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
static int flags
Definition: cpu.c:23
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
LZW decoding routines.
int palette
Definition: v4l.c:61
Y , 8bpp.
Definition: pixfmt.h:76
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.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:81
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
Definition: pixfmt.h:90
function y
Definition: D.m:1
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition: bytestream.h:337
AVFrame * last_frame
int len
static av_cold int gif_encode_init(AVCodecContext *avctx)
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
const int ff_lzw_encode_state_size
Definition: lzwenc.c:66
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:264
AVFrame picture
static const AVOption gif_options[]
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
This structure stores compressed data.
bitstream writer API