44#define DEFAULT_TRANSPARENCY_INDEX 0x1f
68 uint32_t *
dst,
size_t *palette_count)
70 size_t colors_seen = 0;
74 for (
size_t c = 0;
c < colors_seen;
c++) {
87 *palette_count = colors_seen;
91 uint8_t *
dst,
int dst_linesize,
92 int w,
int h, uint8_t *
map)
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]];
100 const uint8_t *buf,
const int linesize)
103 int trans =
s->transparent_index;
108 for (
int y = 0; y < avctx->
height; y++) {
109 for (
int x = 0; x < avctx->
width; x++) {
110 if (buf[x] == trans) {
122 int transparent_color_index = -1;
123 unsigned i, smallest_alpha = 0xff;
129 const uint32_t v = palette[
i];
130 if (v >> 24 < smallest_alpha) {
131 smallest_alpha = v >> 24;
132 transparent_color_index =
i;
135 return smallest_alpha < 128 ? transparent_color_index : -1;
143 for (y = 0; y <
h; y++) {
144 for (x = 0; x <
w; x++)
155 const uint8_t *buf,
const int linesize,
157 int *x_start,
int *y_start)
160 int trans =
s->transparent_index;
164 const int w = avctx->
width;
170 while (*y_start < y_end) {
172 for (
int i = 0;
i <
w;
i++) {
173 if (buf[linesize * *y_start +
i] != trans) {
185 while (y_end > *y_start) {
187 for (
int i = 0;
i <
w;
i++) {
188 if (buf[linesize * y_end +
i] != trans) {
199 while (*x_start < x_end) {
201 for (
int i = *y_start;
i < y_end;
i++) {
202 if (buf[linesize *
i + *x_start] != trans) {
213 while (x_end > *x_start) {
215 for (
int i = *y_start;
i < y_end;
i++) {
216 if (buf[linesize *
i + x_end] != trans) {
226 *
height = y_end + 1 - *y_start;
227 *
width = x_end + 1 - *x_start;
234 const uint32_t *palette,
235 const uint8_t *buf,
const int linesize,
236 int *
width,
int *
height,
int *x_start,
int *y_start)
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;
248 while (*y_start < y_end) {
249 if (memcmp(
ref + *y_start*ref_linesize, buf + *y_start*linesize, *
width))
253 while (y_end > *y_start) {
254 if (memcmp(
ref + y_end*ref_linesize, buf + y_end*linesize, *
width))
258 *
height = y_end + 1 - *y_start;
261 while (*x_start < x_end) {
263 for (
int y = *y_start; y <= y_end; y++) {
264 if (
ref[y*ref_linesize + *x_start] != buf[y*linesize + *x_start]) {
273 while (x_end > *x_start) {
275 for (
int y = *y_start; y <= y_end; y++) {
276 if (
ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) {
285 *
width = x_end + 1 - *x_start;
293 uint8_t **bytestream, uint8_t *end,
294 const uint32_t *palette,
295 const uint8_t *buf,
const int linesize,
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;
305 size_t shrunk_palette_count = 0;
317 honor_transparency = 0;
325 const uint32_t *global_palette = palette ? palette :
s->palette;
329 if (sar.
num > 0 && sar.
den > 0) {
330 aspect = sar.
num * 64LL / sar.
den - 15;
331 if (aspect < 0 || aspect > 255)
336 bytestream_put_le16(bytestream, avctx->
width);
337 bytestream_put_le16(bytestream, avctx->
height);
341 bytestream_put_byte(bytestream, ((uint8_t)
s->use_global_palette << 7) | 0x70 | (
s->use_global_palette ? 7 : 0));
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);
352 if (honor_transparency && trans < 0) {
360 honor_transparency = 0;
362 if (palette || !
s->use_global_palette) {
363 const uint32_t *pal = palette ? palette :
s->palette;
372 bytestream_put_byte(bytestream, 0x04);
373 bytestream_put_byte(bytestream, disposal<<2 | (bcid >= 0));
374 bytestream_put_le16(bytestream, 5);
376 bytestream_put_byte(bytestream, 0x00);
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);
385 if (palette || !
s->use_global_palette) {
386 unsigned pow2_count =
av_log2(shrunk_palette_count - 1);
389 bytestream_put_byte(bytestream, 1<<7 | pow2_count);
390 for (
i = 0;
i < 1 << (pow2_count + 1);
i++) {
391 const uint32_t v = shrunk_palette[
i];
392 bytestream_put_be24(bytestream, v);
395 bytestream_put_byte(bytestream, 0x00);
398 bytestream_put_byte(bytestream, 0x08);
403 if (shrunk_palette_count) {
404 if (!
s->shrunk_buf) {
406 if (!
s->shrunk_buf) {
412 ptr =
s->shrunk_buf + y_start*linesize + x_start;
414 ptr = buf + y_start*linesize + x_start;
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;
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])
430 for (y = 0; y <
height; y++) {
440 bytestream_put_byte(bytestream,
size);
441 if (end - *bytestream <
size)
447 bytestream_put_byte(bytestream, 0x00);
455 if (avctx->
width > 65535 || avctx->
height > 65535) {
460 s->transparent_index = -1;
466 if (!
s->tmpl || !
s->buf || !
s->lzw)
476 const AVFrame *pict,
int *got_packet)
479 uint8_t *outbuf_ptr, *end;
480 const uint32_t *palette =
NULL;
485 outbuf_ptr =
pkt->data;
486 end =
pkt->data +
pkt->size;
489 palette = (uint32_t*)pict->
data[1];
491 if (!
s->palette_loaded) {
494 s->palette_loaded = 1;
495 if (
s->use_global_palette)
504 if (!
s->last_frame && !
s->image) {
516 pkt->size = outbuf_ptr -
pkt->data;
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 },
549 .class_name =
"GIF encoder",
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
const FFCodec ff_gif_encoder
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
#define CODEC_PIXFMTS(...)
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
int(* init)(AVBSFContext *ctx)
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
#define FF_INPUT_BUFFER_MIN_SIZE
Used by some encoders as upper bound for the length of headers.
#define GIF_IMAGE_SEPARATOR
static attribute_nonstring const uint8_t gif89a_sig[6]
#define GCE_DISPOSAL_INPLACE
#define GIF_EXTENSION_INTRODUCER
#define GIF_GCE_EXT_LABEL
#define GCE_DISPOSAL_BACKGROUND
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
int av_frame_replace(AVFrame *dst, const AVFrame *src)
Ensure the destination frame refers to the same data described by the source frame,...
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
#define LIBAVUTIL_VERSION_INT
const VDPAUPixFmtMap * map
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
static const AVOption gif_options[]
static int is_image_translucent(AVCodecContext *avctx, const uint8_t *buf, const int linesize)
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)
static av_cold int gif_encode_close(AVCodecContext *avctx)
static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet)
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)
static av_cold int gif_encode_init(AVCodecContext *avctx)
static void shrink_palette(const uint32_t *src, uint8_t *map, uint32_t *dst, size_t *palette_count)
static const AVClass gif_class
static int get_palette_transparency_index(const uint32_t *palette)
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 pick_palette_entry(const uint8_t *buf, int linesize, int w, int h)
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)
#define DEFAULT_TRANSPARENCY_INDEX
Macro definitions for various function/variable attributes.
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.
const int ff_lzw_encode_state_size
int ff_lzw_encode(struct LZWEncodeState *s, const uint8_t *inbuf, int insize)
LZW main compress function.
int ff_lzw_encode_flush(struct LZWEncodeState *s)
Write end code and flush bitstream.
Memory handling functions.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)3R 3G 2B(lsb)
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
@ AV_PIX_FMT_RGB4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb)
@ AV_PIX_FMT_BGR4_BYTE
packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb)
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
int64_t frame_num
Frame counter, set by libavcodec.
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
This structure stores compressed data.
Rational number (pair of numerator and denominator).
uint32_t palette[AVPALETTE_COUNT]
local reference palette for !pal8
uint8_t * tmpl
temporary line buffer
static int ref[MAX_W *MAX_W]