33 #define BITSTREAM_WRITER_LE
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++) {
75 if (
src[
i] == dst[
c]) {
81 dst[colors_seen] =
src[
i];
87 *palette_count = colors_seen;
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)
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;
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;
324 if (
s->image || !avctx->frame_number) {
325 const uint32_t *global_palette = palette ? palette :
s->palette;
326 const AVRational sar = avctx->sample_aspect_ratio;
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) {
405 s->shrunk_buf =
av_malloc(avctx->height * linesize);
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)
480 const uint32_t *palette =
NULL;
489 palette = (uint32_t*)pict->
data[1];
491 if (!
s->palette_loaded) {
494 s->palette_loaded = 1;
502 if (!
s->last_frame && !
s->image) {
536 #define OFFSET(x) offsetof(GIFContext, x)
537 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
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 },
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
#define flags(name, subs,...)
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
#define GIF_IMAGE_SEPARATOR
static const uint8_t gif89a_sig[6]
#define GCE_DISPOSAL_INPLACE
#define GIF_EXTENSION_INTRODUCER
#define GIF_GCE_EXT_LABEL
#define GCE_DISPOSAL_BACKGROUND
#define AV_INPUT_BUFFER_MIN_SIZE
minimum encoding buffer size Used to avoid some checks during header writing.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the 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.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
#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 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 gif_encode_close(AVCodecContext *avctx)
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
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
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.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_RGB8
packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(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.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
int frame_number
Frame counter, set by libavcodec.
const char * name
Name of the codec implementation.
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, size in bytes of each picture line.
This structure stores compressed data.
int flags
A combination of AV_PKT_FLAG values.
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]