LZWState *lzw;
uint8_t *buf;
int buf_size;
- int is_first_frame;
AVFrame *last_frame;
int flags;
+ int image;
uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8
int palette_loaded;
int transparent_index;
while (*y_start < y_end) {
int is_trans = 1;
for (int i = 0; i < w; i++) {
- if (buf[w * *y_start + i] != trans) {
+ if (buf[linesize * *y_start + i] != trans) {
is_trans = 0;
break;
}
}
// crop bottom
- while (y_end < h) {
+ while (y_end > *y_start) {
int is_trans = 1;
for (int i = 0; i < w; i++) {
- if (buf[w * y_end + i] != trans) {
+ if (buf[linesize * y_end + i] != trans) {
is_trans = 0;
break;
}
while (*x_start < x_end) {
int is_trans = 1;
for (int i = *y_start; i < y_end; i++) {
- if (buf[w * i + *x_start] != trans) {
+ if (buf[linesize * i + *x_start] != trans) {
is_trans = 0;
break;
}
}
// crop right
- while (x_end < w) {
+ while (x_end > *x_start) {
int is_trans = 1;
for (int i = *y_start; i < y_end; i++) {
- if (buf[w * i + x_end] != trans) {
+ if (buf[linesize * i + x_end] != trans) {
is_trans = 0;
break;
}
int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette;
const uint8_t *ptr;
- if (!s->is_first_frame && is_image_translucent(avctx, buf, linesize)) {
+ if (!s->image && avctx->frame_number && is_image_translucent(avctx, buf, linesize)) {
gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start);
honor_transparency = 0;
disposal = GCE_DISPOSAL_BACKGROUND;
disposal = GCE_DISPOSAL_INPLACE;
}
- if (s->is_first_frame) { /* GIF header */
+ if (s->image || !avctx->frame_number) { /* GIF header */
const uint32_t *global_palette = palette ? palette : s->palette;
const AVRational sar = avctx->sample_aspect_ratio;
int64_t aspect = 0;
const uint32_t v = global_palette[i] & 0xffffff;
bytestream_put_be24(bytestream, v);
}
-
- s->is_first_frame = 0;
}
if (honor_transparency && trans < 0) {
}
s->transparent_index = -1;
- s->is_first_frame = 1;
s->lzw = av_mallocz(ff_lzw_encode_state_size);
s->buf_size = avctx->width*avctx->height*2 + 1000;
gif_image_write_image(avctx, &outbuf_ptr, end, palette,
pict->data[0], pict->linesize[0], pkt);
- if (!s->last_frame) {
+ if (!s->last_frame && !s->image) {
s->last_frame = av_frame_alloc();
if (!s->last_frame)
return AVERROR(ENOMEM);
}
- av_frame_unref(s->last_frame);
- ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
- if (ret < 0)
- return ret;
+ if (!s->image) {
+ av_frame_unref(s->last_frame);
+ ret = av_frame_ref(s->last_frame, (AVFrame*)pict);
+ if (ret < 0)
+ return ret;
+ }
pkt->size = outbuf_ptr - pkt->data;
- pkt->flags |= AV_PKT_FLAG_KEY;
+ if (s->image || !avctx->frame_number)
+ pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = 1;
return 0;
{ "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" },
{ "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" },
{ "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, "flags" },
+ { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
{ NULL }
};