Go to the documentation of this file.
33 #define BITSTREAM_WRITER_LE
45 #define DEFAULT_TRANSPARENCY_INDEX 0x1f
69 uint32_t *dst,
size_t *palette_count)
71 size_t colors_seen = 0;
75 for (
size_t c = 0;
c < colors_seen;
c++) {
76 if (
src[
i] == dst[
c]) {
82 dst[colors_seen] =
src[
i];
88 *palette_count = colors_seen;
92 uint8_t *dst,
int dst_linesize,
93 int w,
int h, uint8_t *
map)
95 for (
int i = 0;
i <
h;
i++)
96 for (
int j = 0; j <
w; j++)
97 dst[
i * dst_linesize + j] =
map[
src[
i * src_linesize + j]];
101 const uint8_t *buf,
const int linesize)
104 int trans =
s->transparent_index;
109 for (
int y = 0; y < avctx->
height; y++) {
110 for (
int x = 0; x < avctx->
width; x++) {
111 if (buf[x] == trans) {
123 int transparent_color_index = -1;
124 unsigned i, smallest_alpha = 0xff;
130 const uint32_t v = palette[
i];
131 if (v >> 24 < smallest_alpha) {
132 smallest_alpha = v >> 24;
133 transparent_color_index =
i;
136 return smallest_alpha < 128 ? transparent_color_index : -1;
144 for (y = 0; y <
h; y++) {
145 for (x = 0; x <
w; x++)
156 const uint8_t *buf,
const int linesize,
158 int *x_start,
int *y_start)
161 int trans =
s->transparent_index;
165 const int w = avctx->
width;
171 while (*y_start < y_end) {
173 for (
int i = 0;
i <
w;
i++) {
174 if (buf[linesize * *y_start +
i] != trans) {
186 while (y_end > *y_start) {
188 for (
int i = 0;
i <
w;
i++) {
189 if (buf[linesize * y_end +
i] != trans) {
200 while (*x_start < x_end) {
202 for (
int i = *y_start;
i < y_end;
i++) {
203 if (buf[linesize *
i + *x_start] != trans) {
214 while (x_end > *x_start) {
216 for (
int i = *y_start;
i < y_end;
i++) {
217 if (buf[linesize *
i + x_end] != trans) {
227 *
height = y_end + 1 - *y_start;
228 *
width = x_end + 1 - *x_start;
235 const uint32_t *palette,
236 const uint8_t *buf,
const int linesize,
237 int *
width,
int *
height,
int *x_start,
int *y_start)
243 const uint8_t *
ref =
s->last_frame->data[0];
244 const int ref_linesize =
s->last_frame->linesize[0];
245 int x_end = avctx->
width - 1,
246 y_end = avctx->
height - 1;
249 while (*y_start < y_end) {
250 if (memcmp(
ref + *y_start*ref_linesize, buf + *y_start*linesize, *
width))
254 while (y_end > *y_start) {
255 if (memcmp(
ref + y_end*ref_linesize, buf + y_end*linesize, *
width))
259 *
height = y_end + 1 - *y_start;
262 while (*x_start < x_end) {
264 for (
int y = *y_start; y <= y_end; y++) {
265 if (
ref[y*ref_linesize + *x_start] != buf[y*linesize + *x_start]) {
274 while (x_end > *x_start) {
276 for (
int y = *y_start; y <= y_end; y++) {
277 if (
ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) {
286 *
width = x_end + 1 - *x_start;
294 uint8_t **bytestream, uint8_t *end,
295 const uint32_t *palette,
296 const uint8_t *buf,
const int linesize,
301 int x_start = 0, y_start = 0, trans =
s->transparent_index;
302 int bcid = -1, honor_transparency = (
s->flags &
GF_TRANSDIFF) &&
s->last_frame && !palette;
306 size_t shrunk_palette_count = 0;
318 honor_transparency = 0;
325 if (
s->image || !avctx->frame_number) {
326 const uint32_t *global_palette = palette ? palette :
s->palette;
327 const AVRational sar = avctx->sample_aspect_ratio;
330 if (sar.
num > 0 && sar.
den > 0) {
331 aspect = sar.
num * 64LL / sar.
den - 15;
332 if (aspect < 0 || aspect > 255)
337 bytestream_put_le16(bytestream, avctx->width);
338 bytestream_put_le16(bytestream, avctx->height);
342 bytestream_put_byte(bytestream, ((uint8_t)
s->use_global_palette << 7) | 0x70 | (
s->use_global_palette ? 7 : 0));
344 bytestream_put_byte(bytestream, aspect);
345 if (
s->use_global_palette) {
346 for (
int i = 0;
i < 256;
i++) {
347 const uint32_t v = global_palette[
i] & 0xffffff;
348 bytestream_put_be24(bytestream, v);
353 if (honor_transparency && trans < 0) {
361 honor_transparency = 0;
363 if (palette || !
s->use_global_palette) {
364 const uint32_t *pal = palette ? palette :
s->palette;
373 bytestream_put_byte(bytestream, 0x04);
374 bytestream_put_byte(bytestream, disposal<<2 | (bcid >= 0));
375 bytestream_put_le16(bytestream, 5);
377 bytestream_put_byte(bytestream, 0x00);
381 bytestream_put_le16(bytestream, x_start);
382 bytestream_put_le16(bytestream, y_start);
383 bytestream_put_le16(bytestream,
width);
384 bytestream_put_le16(bytestream,
height);
386 if (palette || !
s->use_global_palette) {
387 unsigned pow2_count =
av_log2(shrunk_palette_count - 1);
390 bytestream_put_byte(bytestream, 1<<7 | pow2_count);
391 for (
i = 0;
i < 1 << (pow2_count + 1);
i++) {
392 const uint32_t v = shrunk_palette[
i];
393 bytestream_put_be24(bytestream, v);
396 bytestream_put_byte(bytestream, 0x00);
399 bytestream_put_byte(bytestream, 0x08);
404 if (shrunk_palette_count) {
405 if (!
s->shrunk_buf) {
406 s->shrunk_buf =
av_malloc(avctx->height * linesize);
407 if (!
s->shrunk_buf) {
413 ptr =
s->shrunk_buf + y_start*linesize + x_start;
415 ptr = buf + y_start*linesize + x_start;
417 if (honor_transparency) {
418 const int ref_linesize =
s->last_frame->linesize[0];
419 const uint8_t *
ref =
s->last_frame->data[0] + y_start*ref_linesize + x_start;
421 for (y = 0; y <
height; y++) {
422 memcpy(
s->tmpl, ptr,
width);
423 for (x = 0; x <
width; x++)
424 if (
ref[x] == ptr[x])
431 for (y = 0; y <
height; y++) {
441 bytestream_put_byte(bytestream,
size);
442 if (end - *bytestream <
size)
448 bytestream_put_byte(bytestream, 0x00);
456 if (avctx->
width > 65535 || avctx->
height > 65535) {
461 s->transparent_index = -1;
467 if (!
s->tmpl || !
s->buf || !
s->lzw)
477 const AVFrame *pict,
int *got_packet)
480 uint8_t *outbuf_ptr, *end;
481 const uint32_t *palette =
NULL;
490 palette = (uint32_t*)pict->
data[1];
492 if (!
s->palette_loaded) {
495 s->palette_loaded = 1;
503 if (!
s->last_frame && !
s->image) {
537 #define OFFSET(x) offsetof(GIFContext, x)
538 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
544 {
"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 },
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
AVPixelFormat
Pixel format.
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 int is_image_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
This structure describes decoded (raw) audio or video data.
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)
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.
#define GIF_GCE_EXT_LABEL
static int gif_encode_close(AVCodecContext *avctx)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static void gif_crop_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize, int *width, int *height, int *x_start, int *y_start)
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)
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
#define DEFAULT_TRANSPARENCY_INDEX
static void shrink_palette(const uint32_t *src, uint8_t *map, uint32_t *dst, size_t *palette_count)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static const uint8_t gif89a_sig[6]
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define FF_ARRAY_ELEMS(a)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static enum AVPixelFormat pix_fmts[]
#define GIF_IMAGE_SEPARATOR
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_INPUT_BUFFER_MIN_SIZE
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
#define LIBAVUTIL_VERSION_INT
Describe the class of an AVClass context structure.
uint8_t * tmpl
temporary line buffer
Rational number (pair of numerator and denominator).
const char * av_default_item_name(void *ptr)
Return the context name.
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb)
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
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
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static int get_palette_transparency_index(const uint32_t *palette)
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
static av_cold int gif_encode_init(AVCodecContext *avctx)
int flags
A combination of AV_PKT_FLAG values.
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
#define i(width, name, range_min, range_max)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define GIF_EXTENSION_INTRODUCER
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const char * name
Name of the codec implementation.
int ff_lzw_encode_flush(struct LZWEncodeState *s)
Write end code and flush bitstream.
static const AVClass gif_class
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
#define GCE_DISPOSAL_BACKGROUND
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
static const AVOption gif_options[]
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)
main external API structure.
static int ref[MAX_W *MAX_W]
int frame_number
Frame counter, set by libavcodec.
const VDPAUPixFmtMap * map
This structure stores compressed data.
const int ff_lzw_encode_state_size
int width
picture width / height.
const AVCodec ff_gif_encoder
#define flags(name, subs,...)
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
#define GCE_DISPOSAL_INPLACE
static int pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.