From c6ecd9c8dca0482978b1a0c08ac64c4a1f5a418b Mon Sep 17 00:00:00 2001 From: David McPaul Date: Mon, 15 Sep 2008 14:04:00 +0000 Subject: [PATCH] Update avcodec to 20080825 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27548 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/avcodec/libavcodec/g726.c | 402 ++++++++++++++++++ .../media/plugins/avcodec/libavcodec/g729.h | 29 ++ .../plugins/avcodec/libavcodec/g729data.h | 206 +++++++++ .../plugins/avcodec/libavcodec/g729dec.c | 70 +++ .../media/plugins/avcodec/libavcodec/gif.c | 345 +++++++++++++++ .../media/plugins/avcodec/libavcodec/gifdec.c | 337 +++++++++++++++ .../media/plugins/avcodec/libavcodec/golomb.c | 53 ++- .../media/plugins/avcodec/libavcodec/golomb.h | 245 ++++++++--- 8 files changed, 1604 insertions(+), 83 deletions(-) create mode 100644 src/add-ons/media/plugins/avcodec/libavcodec/g726.c create mode 100644 src/add-ons/media/plugins/avcodec/libavcodec/g729.h create mode 100644 src/add-ons/media/plugins/avcodec/libavcodec/g729data.h create mode 100644 src/add-ons/media/plugins/avcodec/libavcodec/g729dec.c create mode 100644 src/add-ons/media/plugins/avcodec/libavcodec/gif.c create mode 100644 src/add-ons/media/plugins/avcodec/libavcodec/gifdec.c diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/g726.c b/src/add-ons/media/plugins/avcodec/libavcodec/g726.c new file mode 100644 index 0000000000..463d993137 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/g726.c @@ -0,0 +1,402 @@ +/* + * G.726 ADPCM audio codec + * Copyright (c) 2004 Roman Shaposhnik. + * + * This is a very straightforward rendition of the G.726 + * Section 4 "Computational Details". + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include "avcodec.h" +#include "bitstream.h" + +/** + * G.726 11bit float. + * G.726 Standard uses rather odd 11bit floating point arithmentic for + * numerous occasions. It's a mistery to me why they did it this way + * instead of simply using 32bit integer arithmetic. + */ +typedef struct Float11 { + uint8_t sign; /**< 1bit sign */ + uint8_t exp; /**< 4bit exponent */ + uint8_t mant; /**< 6bit mantissa */ +} Float11; + +static inline Float11* i2f(int i, Float11* f) +{ + f->sign = (i < 0); + if (f->sign) + i = -i; + f->exp = av_log2_16bit(i) + !!i; + f->mant = i? (i<<6) >> f->exp : 1<<5; + return f; +} + +static inline int16_t mult(Float11* f1, Float11* f2) +{ + int res, exp; + + exp = f1->exp + f2->exp; + res = (((f1->mant * f2->mant) + 0x30) >> 4); + res = exp > 19 ? res << (exp - 19) : res >> (19 - exp); + return (f1->sign ^ f2->sign) ? -res : res; +} + +static inline int sgn(int value) +{ + return (value < 0) ? -1 : 1; +} + +typedef struct G726Tables { + const int* quant; /**< quantization table */ + const int16_t* iquant; /**< inverse quantization table */ + const int16_t* W; /**< special table #1 ;-) */ + const uint8_t* F; /**< special table #2 */ +} G726Tables; + +typedef struct G726Context { + G726Tables tbls; /**< static tables needed for computation */ + + Float11 sr[2]; /**< prev. reconstructed samples */ + Float11 dq[6]; /**< prev. difference */ + int a[2]; /**< second order predictor coeffs */ + int b[6]; /**< sixth order predictor coeffs */ + int pk[2]; /**< signs of prev. 2 sez + dq */ + + int ap; /**< scale factor control */ + int yu; /**< fast scale factor */ + int yl; /**< slow scale factor */ + int dms; /**< short average magnitude of F[i] */ + int dml; /**< long average magnitude of F[i] */ + int td; /**< tone detect */ + + int se; /**< estimated signal for the next iteration */ + int sez; /**< estimated second order prediction */ + int y; /**< quantizer scaling factor for the next iteration */ + int code_size; +} G726Context; + +static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ + { 260, INT_MAX }; +static const int16_t iquant_tbl16[] = + { 116, 365, 365, 116 }; +static const int16_t W_tbl16[] = + { -22, 439, 439, -22 }; +static const uint8_t F_tbl16[] = + { 0, 7, 7, 0 }; + +static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ + { 7, 217, 330, INT_MAX }; +static const int16_t iquant_tbl24[] = + { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN }; +static const int16_t W_tbl24[] = + { -4, 30, 137, 582, 582, 137, 30, -4 }; +static const uint8_t F_tbl24[] = + { 0, 1, 2, 7, 7, 2, 1, 0 }; + +static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ + { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; +static const int16_t iquant_tbl32[] = + { INT16_MIN, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, INT16_MIN }; +static const int16_t W_tbl32[] = + { -12, 18, 41, 64, 112, 198, 355, 1122, + 1122, 355, 198, 112, 64, 41, 18, -12}; +static const uint8_t F_tbl32[] = + { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; + +static const int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ + { -122, -16, 67, 138, 197, 249, 297, 338, + 377, 412, 444, 474, 501, 527, 552, INT_MAX }; +static const int16_t iquant_tbl40[] = + { INT16_MIN, -66, 28, 104, 169, 224, 274, 318, + 358, 395, 429, 459, 488, 514, 539, 566, + 566, 539, 514, 488, 459, 429, 395, 358, + 318, 274, 224, 169, 104, 28, -66, INT16_MIN }; +static const int16_t W_tbl40[] = + { 14, 14, 24, 39, 40, 41, 58, 100, + 141, 179, 219, 280, 358, 440, 529, 696, + 696, 529, 440, 358, 280, 219, 179, 141, + 100, 58, 41, 40, 39, 24, 14, 14 }; +static const uint8_t F_tbl40[] = + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, + 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + +static const G726Tables G726Tables_pool[] = + {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, + { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, + { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, + { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }}; + + +/** + * Para 4.2.2 page 18: Adaptive quantizer. + */ +static inline uint8_t quant(G726Context* c, int d) +{ + int sign, exp, i, dln; + + sign = i = 0; + if (d < 0) { + sign = 1; + d = -d; + } + exp = av_log2_16bit(d); + dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2); + + while (c->tbls.quant[i] < INT_MAX && c->tbls.quant[i] < dln) + ++i; + + if (sign) + i = ~i; + if (c->code_size != 2 && i == 0) /* I'm not sure this is a good idea */ + i = 0xff; + + return i; +} + +/** + * Para 4.2.3 page 22: Inverse adaptive quantizer. + */ +static inline int16_t inverse_quant(G726Context* c, int i) +{ + int dql, dex, dqt; + + dql = c->tbls.iquant[i] + (c->y >> 2); + dex = (dql>>7) & 0xf; /* 4bit exponent */ + dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */ + return (dql < 0) ? 0 : ((dqt<> 7); +} + +static int16_t g726_decode(G726Context* c, int I) +{ + int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0; + Float11 f; + int I_sig= I >> (c->code_size - 1); + + dq = inverse_quant(c, I); + + /* Transition detect */ + ylint = (c->yl >> 15); + ylfrac = (c->yl >> 10) & 0x1f; + thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; + tr= (c->td == 1 && dq > ((3*thr2)>>2)); + + if (I_sig) /* get the sign */ + dq = -dq; + re_signal = c->se + dq; + + /* Update second order predictor coefficient A2 and A1 */ + pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0; + dq0 = dq ? sgn(dq) : 0; + if (tr) { + c->a[0] = 0; + c->a[1] = 0; + for (i=0; i<6; i++) + c->b[i] = 0; + } else { + /* This is a bit crazy, but it really is +255 not +256 */ + fa1 = av_clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255); + + c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7); + c->a[1] = av_clip(c->a[1], -12288, 12288); + c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); + c->a[0] = av_clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]); + + for (i=0; i<6; i++) + c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8); + } + + /* Update Dq and Sr and Pk */ + c->pk[1] = c->pk[0]; + c->pk[0] = pk0 ? pk0 : 1; + c->sr[1] = c->sr[0]; + i2f(re_signal, &c->sr[0]); + for (i=5; i>0; i--) + c->dq[i] = c->dq[i-1]; + i2f(dq, &c->dq[0]); + c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */ + + c->td = c->a[1] < -11776; + + /* Update Ap */ + c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5); + c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7); + if (tr) + c->ap = 256; + else { + c->ap += (-c->ap) >> 4; + if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3)) + c->ap += 0x20; + } + + /* Update Yu and Yl */ + c->yu = av_clip(c->y + c->tbls.W[I] + ((-c->y)>>5), 544, 5120); + c->yl += c->yu + ((-c->yl)>>6); + + /* Next iteration for Y */ + al = (c->ap >= 256) ? 1<<6 : c->ap >> 2; + c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6; + + /* Next iteration for SE and SEZ */ + c->se = 0; + for (i=0; i<6; i++) + c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]); + c->sez = c->se >> 1; + for (i=0; i<2; i++) + c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]); + c->se >>= 1; + + return av_clip(re_signal << 2, -0xffff, 0xffff); +} + +static av_cold int g726_reset(G726Context* c, int index) +{ + int i; + + c->tbls = G726Tables_pool[index]; + for (i=0; i<2; i++) { + c->sr[i].mant = 1<<5; + c->pk[i] = 1; + } + for (i=0; i<6; i++) { + c->dq[i].mant = 1<<5; + } + c->yu = 544; + c->yl = 34816; + + c->y = 544; + + return 0; +} + +#ifdef CONFIG_ENCODERS +static int16_t g726_encode(G726Context* c, int16_t sig) +{ + uint8_t i; + + i = quant(c, sig/4 - c->se) & ((1<code_size) - 1); + g726_decode(c, i); + return i; +} +#endif + +/* Interfacing to the libavcodec */ + +static av_cold int g726_init(AVCodecContext * avctx) +{ + G726Context* c = avctx->priv_data; + unsigned int index= (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2; + + if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) { + av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n"); + return -1; + } + if(avctx->channels != 1){ + av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); + return -1; + } + if(index>3){ + av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2); + return -1; + } + g726_reset(c, index); + c->code_size = index+2; + + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + avctx->coded_frame->key_frame = 1; + + if (avctx->codec->decode) + avctx->sample_fmt = SAMPLE_FMT_S16; + + return 0; +} + +static av_cold int g726_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + return 0; +} + +#ifdef CONFIG_ENCODERS +static int g726_encode_frame(AVCodecContext *avctx, + uint8_t *dst, int buf_size, void *data) +{ + G726Context *c = avctx->priv_data; + short *samples = data; + PutBitContext pb; + + init_put_bits(&pb, dst, 1024*1024); + + for (; buf_size; buf_size--) + put_bits(&pb, c->code_size, g726_encode(c, *samples++)); + + flush_put_bits(&pb); + + return put_bits_count(&pb)>>3; +} +#endif + +static int g726_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + G726Context *c = avctx->priv_data; + short *samples = data; + GetBitContext gb; + + init_get_bits(&gb, buf, buf_size * 8); + + while (get_bits_count(&gb) + c->code_size <= buf_size*8) + *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); + + if(buf_size*8 != get_bits_count(&gb)) + av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); + + *data_size = (uint8_t*)samples - (uint8_t*)data; + return buf_size; +} + +#ifdef CONFIG_ENCODERS +AVCodec adpcm_g726_encoder = { + "g726", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_G726, + sizeof(G726Context), + g726_init, + g726_encode_frame, + g726_close, + NULL, + .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), +}; +#endif //CONFIG_ENCODERS + +AVCodec adpcm_g726_decoder = { + "g726", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_G726, + sizeof(G726Context), + g726_init, + NULL, + g726_close, + g726_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/g729.h b/src/add-ons/media/plugins/avcodec/libavcodec/g729.h new file mode 100644 index 0000000000..8e6378367a --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/g729.h @@ -0,0 +1,29 @@ +/* + * G.729 decoder + * Copyright (c) 2008 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef FFMPEG_G729_H +#define FFMPEG_G729_H + +/** + * maximum possible subframe size + */ +#define MAX_SUBFRAME_SIZE 44 + +#endif // FFMPEG_G729_H diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/g729data.h b/src/add-ons/media/plugins/avcodec/libavcodec/g729data.h new file mode 100644 index 0000000000..5334e48093 --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/g729data.h @@ -0,0 +1,206 @@ +/* + * data for G.729 decoder + * Copyright (c) 2007 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FFMPEG_G729DATA_H +#define FFMPEG_G729DATA_H + +#include + +/// Moving Average (MA) prediction order +#define MA_NP 4 + +/** + * first stage LSP codebook + * (10-dimensional, with 128 entries (3.24 of G.729) + */ +static const int16_t cb_lsp_1st[1< +#include +#include +#include +#include +#include +#include + +#include "avcodec.h" +#include "libavutil/avutil.h" +#include "bitstream.h" + +/** + * minimum quantized LSF value (3.2.4) + * 0.005 in Q13 + */ +#define LSFQ_MIN 40 + +/** + * maximum quantized LSF value (3.2.4) + * 3.135 in Q13 + */ +#define LSFQ_MAX 25681 + +/** + * minimum LSF distance (3.2.4) + * 0.0391 in Q13 + */ +#define LSFQ_DIFF_MIN 321 + +/** + * \brief pseudo random number generator + */ +static inline uint16_t g729_random(uint16_t value) +{ + return 31821 * value + 13849; +} + +AVCodec g729_decoder = +{ + "g729", + CODEC_TYPE_AUDIO, + CODEC_ID_G729, + sizeof(G729_Context), + ff_g729_decoder_init, + NULL, + NULL, + ff_g729_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("G.729"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/gif.c b/src/add-ons/media/plugins/avcodec/libavcodec/gif.c new file mode 100644 index 0000000000..35cd0a012e --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/gif.c @@ -0,0 +1,345 @@ +/* + * GIF encoder. + * Copyright (c) 2000 Fabrice Bellard. + * Copyright (c) 2002 Francois Revol. + * Copyright (c) 2006 Baptiste Coudurier. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * First version by Francois Revol revol@free.fr + * + * Features and limitations: + * - currently no compression is performed, + * in fact the size of the data is 9/8 the size of the image in 8bpp + * - uses only a global standard palette + * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). + * + * Reference documents: + * http://www.goice.co.jp/member/mo/formats/gif.html + * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ + * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt + * + * this url claims to have an LZW algorithm not covered by Unisys patent: + * http://www.msg.net/utility/whirlgif/gifencod.html + * could help reduce the size of the files _a lot_... + * some sites mentions an RLE type compression also. + */ + +#include "avcodec.h" +#include "bytestream.h" +#include "bitstream.h" + +/* bitstream minipacket size */ +#define GIF_CHUNKS 100 + +/* slows down the decoding (and some browsers don't like it) */ +/* update on the 'some browsers don't like it issue from above: this was probably due to missing 'Data Sub-block Terminator' (byte 19) in the app_header */ +#define GIF_ADD_APP_HEADER // required to enable looping of animated gif + +typedef struct { + unsigned char r; + unsigned char g; + unsigned char b; +} rgb_triplet; + +/* we use the standard 216 color palette */ + +/* this script was used to create the palette: + * for r in 00 33 66 99 cc ff; do for g in 00 33 66 99 cc ff; do echo -n " "; for b in 00 33 66 99 cc ff; do + * echo -n "{ 0x$r, 0x$g, 0x$b }, "; done; echo ""; done; done + */ + +static const rgb_triplet gif_clut[216] = { + { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff }, + { 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff }, + { 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff }, + { 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff }, + { 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff }, + { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff }, + { 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff }, + { 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff }, + { 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff }, + { 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff }, + { 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff }, + { 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff }, + { 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff }, + { 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff }, + { 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff }, + { 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff }, + { 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff }, + { 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff }, + { 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff }, + { 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff }, + { 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff }, + { 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff }, + { 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff }, + { 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff }, + { 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff }, + { 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff }, + { 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff }, + { 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff }, + { 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff }, + { 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff }, + { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff }, + { 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff }, + { 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff }, + { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff }, + { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff }, + { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff }, +}; + +/* The GIF format uses reversed order for bitstreams... */ +/* at least they don't use PDP_ENDIAN :) */ +/* so we 'extend' PutBitContext. hmmm, OOP :) */ +/* seems this thing changed slightly since I wrote it... */ + +#ifdef ALT_BITSTREAM_WRITER +# error no ALT_BITSTREAM_WRITER support for now +#endif + +static void gif_put_bits_rev(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_cnt; + + // printf("put_bits=%d %x\n", n, value); + assert(n == 32 || value < (1U << n)); + + bit_buf = s->bit_buf; + bit_cnt = 32 - s->bit_left; /* XXX:lazyness... was = s->bit_cnt; */ + + // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); + /* XXX: optimize */ + if (n < (32-bit_cnt)) { + bit_buf |= value << (bit_cnt); + bit_cnt+=n; + } else { + bit_buf |= value << (bit_cnt); + + bytestream_put_le32(&s->buf_ptr, bit_buf); + + //printf("bitbuf = %08x\n", bit_buf); + if (s->buf_ptr >= s->buf_end) + abort(); +// flush_buffer_rev(s); + bit_cnt=bit_cnt + n - 32; + if (bit_cnt == 0) { + bit_buf = 0; + } else { + bit_buf = value >> (n - bit_cnt); + } + } + + s->bit_buf = bit_buf; + s->bit_left = 32 - bit_cnt; +} + +/* pad the end of the output stream with zeros */ +static void gif_flush_put_bits_rev(PutBitContext *s) +{ + while (s->bit_left < 32) { + /* XXX: should test end of buffer */ + *s->buf_ptr++=s->bit_buf & 0xff; + s->bit_buf>>=8; + s->bit_left+=8; + } +// flush_buffer_rev(s); + s->bit_left=32; + s->bit_buf=0; +} + +/* !RevPutBitContext */ + +/* GIF header */ +static int gif_image_write_header(uint8_t **bytestream, + int width, int height, int loop_count, + uint32_t *palette) +{ + int i; + unsigned int v; + + bytestream_put_buffer(bytestream, "GIF", 3); + bytestream_put_buffer(bytestream, "89a", 3); + bytestream_put_le16(bytestream, width); + bytestream_put_le16(bytestream, height); + + bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ + bytestream_put_byte(bytestream, 0x1f); /* background color index */ + bytestream_put_byte(bytestream, 0); /* aspect ratio */ + + /* the global palette */ + if (!palette) { + bytestream_put_buffer(bytestream, (const unsigned char *)gif_clut, 216*3); + for(i=0;i<((256-216)*3);i++) + bytestream_put_byte(bytestream, 0); + } else { + for(i=0;i<256;i++) { + v = palette[i]; + bytestream_put_be24(bytestream, v); + } + } + + /* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated gif + see http://members.aol.com/royalef/gifabout.htm#net-extension + + byte 1 : 33 (hex 0x21) GIF Extension code + byte 2 : 255 (hex 0xFF) Application Extension Label + byte 3 : 11 (hex (0x0B) Length of Application Block + (eleven bytes of data to follow) + bytes 4 to 11 : "NETSCAPE" + bytes 12 to 14 : "2.0" + byte 15 : 3 (hex 0x03) Length of Data Sub-Block + (three bytes of data to follow) + byte 16 : 1 (hex 0x01) + bytes 17 to 18 : 0 to 65535, an unsigned integer in + lo-hi byte format. This indicate the + number of iterations the loop should + be executed. + bytes 19 : 0 (hex 0x00) a Data Sub-block Terminator + */ + + /* application extension header */ +#ifdef GIF_ADD_APP_HEADER + if (loop_count >= 0 && loop_count <= 65535) { + bytestream_put_byte(bytestream, 0x21); + bytestream_put_byte(bytestream, 0xff); + bytestream_put_byte(bytestream, 0x0b); + bytestream_put_buffer(bytestream, "NETSCAPE2.0", 11); // bytes 4 to 14 + bytestream_put_byte(bytestream, 0x03); // byte 15 + bytestream_put_byte(bytestream, 0x01); // byte 16 + bytestream_put_le16(bytestream, (uint16_t)loop_count); + bytestream_put_byte(bytestream, 0x00); // byte 19 + } +#endif + return 0; +} + +/* this is maybe slow, but allows for extensions */ +static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) +{ + return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6)); +} + + +static int gif_image_write_image(uint8_t **bytestream, + int x1, int y1, int width, int height, + const uint8_t *buf, int linesize, int pix_fmt) +{ + PutBitContext p; + uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */ + int i, left, w, v; + const uint8_t *ptr; + /* image block */ + + bytestream_put_byte(bytestream, 0x2c); + bytestream_put_le16(bytestream, x1); + bytestream_put_le16(bytestream, y1); + bytestream_put_le16(bytestream, width); + bytestream_put_le16(bytestream, height); + bytestream_put_byte(bytestream, 0x00); /* flags */ + /* no local clut */ + + bytestream_put_byte(bytestream, 0x08); + + left= width * height; + + init_put_bits(&p, buffer, 130); + +/* + * the thing here is the bitstream is written as little packets, with a size byte before + * but it's still the same bitstream between packets (no flush !) + */ + ptr = buf; + w = width; + while(left>0) { + + gif_put_bits_rev(&p, 9, 0x0100); /* clear code */ + + for(i=(left 0) { + bytestream_put_byte(bytestream, pbBufPtr(&p) - p.buf); /* byte count of the packet */ + bytestream_put_buffer(bytestream, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */ + p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */ + } + left-=GIF_CHUNKS; + } + bytestream_put_byte(bytestream, 0x00); /* end of image block */ + bytestream_put_byte(bytestream, 0x3b); + return 0; +} + +typedef struct { + int64_t time, file_time; + uint8_t buffer[100]; /* data chunks */ + AVFrame picture; +} GIFContext; + +static av_cold int gif_encode_init(AVCodecContext *avctx) +{ + GIFContext *s = avctx->priv_data; + + avctx->coded_frame = &s->picture; + return 0; +} + +/* better than nothing gif encoder */ +static int gif_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data) +{ + GIFContext *s = avctx->priv_data; + AVFrame *pict = data; + AVFrame *const p = (AVFrame *)&s->picture; + uint8_t *outbuf_ptr = outbuf; + + *p = *pict; + p->pict_type = FF_I_TYPE; + p->key_frame = 1; + gif_image_write_header(&outbuf_ptr, avctx->width, avctx->height, -1, (uint32_t *)pict->data[1]); + gif_image_write_image(&outbuf_ptr, 0, 0, avctx->width, avctx->height, pict->data[0], pict->linesize[0], PIX_FMT_PAL8); + return outbuf_ptr - outbuf; +} + +AVCodec gif_encoder = { + "gif", + CODEC_TYPE_VIDEO, + CODEC_ID_GIF, + sizeof(GIFContext), + gif_encode_init, + gif_encode_frame, + NULL, //encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_PAL8, PIX_FMT_NONE}, + .long_name= NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/gifdec.c b/src/add-ons/media/plugins/avcodec/libavcodec/gifdec.c new file mode 100644 index 0000000000..ee805a8d5a --- /dev/null +++ b/src/add-ons/media/plugins/avcodec/libavcodec/gifdec.c @@ -0,0 +1,337 @@ +/* + * GIF decoder + * Copyright (c) 2003 Fabrice Bellard. + * Copyright (c) 2006 Baptiste Coudurier. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +//#define DEBUG + +#include "avcodec.h" +#include "bytestream.h" +#include "lzw.h" + +#define GCE_DISPOSAL_NONE 0 +#define GCE_DISPOSAL_INPLACE 1 +#define GCE_DISPOSAL_BACKGROUND 2 +#define GCE_DISPOSAL_RESTORE 3 + +typedef struct GifState { + AVFrame picture; + int screen_width; + int screen_height; + int bits_per_pixel; + int background_color_index; + int transparent_color_index; + int color_resolution; + uint32_t *image_palette; + + /* after the frame is displayed, the disposal method is used */ + int gce_disposal; + /* delay during which the frame is shown */ + int gce_delay; + + /* LZW compatible decoder */ + const uint8_t *bytestream; + const uint8_t *bytestream_end; + LZWState *lzw; + + /* aux buffers */ + uint8_t global_palette[256 * 3]; + uint8_t local_palette[256 * 3]; + + AVCodecContext* avctx; +} GifState; + +static const uint8_t gif87a_sig[6] = "GIF87a"; +static const uint8_t gif89a_sig[6] = "GIF89a"; + +static int gif_read_image(GifState *s) +{ + int left, top, width, height, bits_per_pixel, code_size, flags; + int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i; + uint8_t *ptr, *spal, *palette, *ptr1; + + left = bytestream_get_le16(&s->bytestream); + top = bytestream_get_le16(&s->bytestream); + width = bytestream_get_le16(&s->bytestream); + height = bytestream_get_le16(&s->bytestream); + flags = bytestream_get_byte(&s->bytestream); + is_interleaved = flags & 0x40; + has_local_palette = flags & 0x80; + bits_per_pixel = (flags & 0x07) + 1; +#ifdef DEBUG + dprintf(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height); +#endif + + if (has_local_palette) { + bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel)); + palette = s->local_palette; + } else { + palette = s->global_palette; + bits_per_pixel = s->bits_per_pixel; + } + + /* verify that all the image is inside the screen dimensions */ + if (left + width > s->screen_width || + top + height > s->screen_height) + return AVERROR(EINVAL); + + /* build the palette */ + n = (1 << bits_per_pixel); + spal = palette; + for(i = 0; i < n; i++) { + s->image_palette[i] = (0xff << 24) | AV_RB24(spal); + spal += 3; + } + for(; i < 256; i++) + s->image_palette[i] = (0xff << 24); + /* handle transparency */ + if (s->transparent_color_index >= 0) + s->image_palette[s->transparent_color_index] = 0; + + /* now get the image data */ + code_size = bytestream_get_byte(&s->bytestream); + ff_lzw_decode_init(s->lzw, code_size, s->bytestream, + s->bytestream_end - s->bytestream, FF_LZW_GIF); + + /* read all the image */ + linesize = s->picture.linesize[0]; + ptr1 = s->picture.data[0] + top * linesize + left; + ptr = ptr1; + pass = 0; + y1 = 0; + for (y = 0; y < height; y++) { + ff_lzw_decode(s->lzw, ptr, width); + if (is_interleaved) { + switch(pass) { + default: + case 0: + case 1: + y1 += 8; + ptr += linesize * 8; + if (y1 >= height) { + y1 = pass ? 2 : 4; + ptr = ptr1 + linesize * y1; + pass++; + } + break; + case 2: + y1 += 4; + ptr += linesize * 4; + if (y1 >= height) { + y1 = 1; + ptr = ptr1 + linesize; + pass++; + } + break; + case 3: + y1 += 2; + ptr += linesize * 2; + break; + } + } else { + ptr += linesize; + } + } + /* read the garbage data until end marker is found */ + ff_lzw_decode_tail(s->lzw); + s->bytestream = ff_lzw_cur_ptr(s->lzw); + return 0; +} + +static int gif_read_extension(GifState *s) +{ + int ext_code, ext_len, i, gce_flags, gce_transparent_index; + + /* extension */ + ext_code = bytestream_get_byte(&s->bytestream); + ext_len = bytestream_get_byte(&s->bytestream); +#ifdef DEBUG + dprintf(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len); +#endif + switch(ext_code) { + case 0xf9: + if (ext_len != 4) + goto discard_ext; + s->transparent_color_index = -1; + gce_flags = bytestream_get_byte(&s->bytestream); + s->gce_delay = bytestream_get_le16(&s->bytestream); + gce_transparent_index = bytestream_get_byte(&s->bytestream); + if (gce_flags & 0x01) + s->transparent_color_index = gce_transparent_index; + else + s->transparent_color_index = -1; + s->gce_disposal = (gce_flags >> 2) & 0x7; +#ifdef DEBUG + dprintf(s->avctx, "gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n", + gce_flags, s->gce_delay, + s->transparent_color_index, s->gce_disposal); +#endif + ext_len = bytestream_get_byte(&s->bytestream); + break; + } + + /* NOTE: many extension blocks can come after */ + discard_ext: + while (ext_len != 0) { + for (i = 0; i < ext_len; i++) + bytestream_get_byte(&s->bytestream); + ext_len = bytestream_get_byte(&s->bytestream); +#ifdef DEBUG + dprintf(s->avctx, "gif: ext_len1=%d\n", ext_len); +#endif + } + return 0; +} + +static int gif_read_header1(GifState *s) +{ + uint8_t sig[6]; + int v, n; + int has_global_palette; + + if (s->bytestream_end < s->bytestream + 13) + return -1; + + /* read gif signature */ + bytestream_get_buffer(&s->bytestream, sig, 6); + if (memcmp(sig, gif87a_sig, 6) != 0 && + memcmp(sig, gif89a_sig, 6) != 0) + return -1; + + /* read screen header */ + s->transparent_color_index = -1; + s->screen_width = bytestream_get_le16(&s->bytestream); + s->screen_height = bytestream_get_le16(&s->bytestream); + if( (unsigned)s->screen_width > 32767 + || (unsigned)s->screen_height > 32767){ + av_log(NULL, AV_LOG_ERROR, "picture size too large\n"); + return -1; + } + + v = bytestream_get_byte(&s->bytestream); + s->color_resolution = ((v & 0x70) >> 4) + 1; + has_global_palette = (v & 0x80); + s->bits_per_pixel = (v & 0x07) + 1; + s->background_color_index = bytestream_get_byte(&s->bytestream); + bytestream_get_byte(&s->bytestream); /* ignored */ +#ifdef DEBUG + dprintf(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n", + s->screen_width, s->screen_height, s->bits_per_pixel, + has_global_palette); +#endif + if (has_global_palette) { + n = 1 << s->bits_per_pixel; + if (s->bytestream_end < s->bytestream + n * 3) + return -1; + bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3); + } + return 0; +} + +static int gif_parse_next_image(GifState *s) +{ + while (s->bytestream < s->bytestream_end) { + int code = bytestream_get_byte(&s->bytestream); +#ifdef DEBUG + dprintf(s->avctx, "gif: code=%02x '%c'\n", code, code); +#endif + switch (code) { + case ',': + return gif_read_image(s); + case '!': + if (gif_read_extension(s) < 0) + return -1; + break; + case ';': + /* end of image */ + default: + /* error or erroneous EOF */ + return -1; + } + } + return -1; +} + +static av_cold int gif_decode_init(AVCodecContext *avctx) +{ + GifState *s = avctx->priv_data; + + s->avctx = avctx; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame= &s->picture; + s->picture.data[0] = NULL; + ff_lzw_decode_open(&s->lzw); + return 0; +} + +static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) +{ + GifState *s = avctx->priv_data; + AVFrame *picture = data; + int ret; + + s->bytestream = buf; + s->bytestream_end = buf + buf_size; + if (gif_read_header1(s) < 0) + return -1; + + avctx->pix_fmt = PIX_FMT_PAL8; + if (avcodec_check_dimensions(avctx, s->screen_width, s->screen_height)) + return -1; + avcodec_set_dimensions(avctx, s->screen_width, s->screen_height); + + if (s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + if (avctx->get_buffer(avctx, &s->picture) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + s->image_palette = (uint32_t *)s->picture.data[1]; + ret = gif_parse_next_image(s); + if (ret < 0) + return ret; + + *picture = s->picture; + *data_size = sizeof(AVPicture); + return s->bytestream - buf; +} + +static av_cold int gif_decode_close(AVCodecContext *avctx) +{ + GifState *s = avctx->priv_data; + + ff_lzw_decode_close(&s->lzw); + if(s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + return 0; +} + +AVCodec gif_decoder = { + "gif", + CODEC_TYPE_VIDEO, + CODEC_ID_GIF, + sizeof(GifState), + gif_decode_init, + NULL, + gif_decode_close, + gif_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"), +}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/golomb.c b/src/add-ons/media/plugins/avcodec/libavcodec/golomb.c index a63f822809..79dc0a71cb 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/golomb.c +++ b/src/add-ons/media/plugins/avcodec/libavcodec/golomb.c @@ -2,31 +2,32 @@ * exp golomb vlc stuff * Copyright (c) 2003 Michael Niedermayer * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - + /** * @file golomb.c - * @brief + * @brief * exp golomb vlc stuff * @author Michael Niedermayer */ -#include "common.h" - +#include "libavutil/common.h" + const uint8_t ff_golomb_vlc_len[512]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, @@ -46,7 +47,7 @@ const uint8_t ff_golomb_vlc_len[512]={ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; -const uint8_t ff_ue_golomb_vlc_code[512]={ +const uint8_t ff_ue_golomb_vlc_code[512]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, @@ -65,7 +66,7 @@ const uint8_t ff_ue_golomb_vlc_code[512]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const int8_t ff_se_golomb_vlc_code[512]={ +const int8_t ff_se_golomb_vlc_code[512]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15, 4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, @@ -85,7 +86,7 @@ const int8_t ff_se_golomb_vlc_code[512]={ }; -const uint8_t ff_ue_golomb_len[256]={ +const uint8_t ff_ue_golomb_len[256]={ 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13, 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, @@ -115,12 +116,12 @@ const uint8_t ff_interleaved_golomb_vlc_len[256]={ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, }; -const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={ +const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={ 15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3, - 19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4, + 19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5, + 23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5, 27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -134,7 +135,7 @@ const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -const int8_t ff_interleaved_se_golomb_vlc_code[256]={ +const int8_t ff_interleaved_se_golomb_vlc_code[256]={ 8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2, 10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -152,3 +153,21 @@ const int8_t ff_interleaved_se_golomb_vlc_code[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + +const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={ +0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, +4, 5, 2, 2, 6, 7, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2, +12,13,6, 6, 14,15,7, 7, 3, 3, 3, 3, 3, 3, 3, 3, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; diff --git a/src/add-ons/media/plugins/avcodec/libavcodec/golomb.h b/src/add-ons/media/plugins/avcodec/libavcodec/golomb.h index 5ebebe94ce..db4586521c 100644 --- a/src/add-ons/media/plugins/avcodec/libavcodec/golomb.h +++ b/src/add-ons/media/plugins/avcodec/libavcodec/golomb.h @@ -1,30 +1,38 @@ /* * exp golomb vlc stuff * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2004 Alex Beregszaszi * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - + /** * @file golomb.h - * @brief + * @brief * exp golomb vlc stuff - * @author Michael Niedermayer + * @author Michael Niedermayer and Alex Beregszaszi */ +#ifndef FFMPEG_GOLOMB_H +#define FFMPEG_GOLOMB_H + +#include +#include "bitstream.h" + #define INVALID_VLC 0x80000000 extern const uint8_t ff_golomb_vlc_len[512]; @@ -35,24 +43,25 @@ extern const uint8_t ff_ue_golomb_len[256]; extern const uint8_t ff_interleaved_golomb_vlc_len[256]; extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; +extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]; + - /** * read unsigned exp golomb code. */ static inline int get_ue_golomb(GetBitContext *gb){ unsigned int buf; int log; - + OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); - + if(buf >= (1<<27)){ buf >>= 32 - 9; LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); CLOSE_READER(re, gb); - + return ff_ue_golomb_vlc_code[buf]; }else{ log= 2*av_log2(buf) - 31; @@ -60,38 +69,43 @@ static inline int get_ue_golomb(GetBitContext *gb){ buf--; LAST_SKIP_BITS(re, gb, 32 - log); CLOSE_READER(re, gb); - + return buf; } } static inline int svq3_get_ue_golomb(GetBitContext *gb){ uint32_t buf; - int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); - + if(buf&0xAA800000){ buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); CLOSE_READER(re, gb); - + return ff_interleaved_ue_golomb_vlc_code[buf]; }else{ - buf|=1; - if((buf & 0xAAAAAAAA) == 0) - return INVALID_VLC; + int ret = 1; - for(log=31; (buf & 0x80000000) == 0; log--){ - buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + while (1) { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); + + if (ff_interleaved_golomb_vlc_len[buf] != 9){ + ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; + ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; + break; + } + ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); } - LAST_SKIP_BITS(re, gb, 63 - 2*log); CLOSE_READER(re, gb); - - return ((buf << log) >> log) - 1; + return ret - 1; } } @@ -100,7 +114,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ */ static inline int get_te0_golomb(GetBitContext *gb, int range){ assert(range >= 1); - + if(range==1) return 0; else if(range==2) return get_bits1(gb)^1; else return get_ue_golomb(gb); @@ -111,7 +125,7 @@ static inline int get_te0_golomb(GetBitContext *gb, int range){ */ static inline int get_te_golomb(GetBitContext *gb, int range){ assert(range >= 1); - + if(range==2) return get_bits1(gb)^1; else return get_ue_golomb(gb); } @@ -123,24 +137,24 @@ static inline int get_te_golomb(GetBitContext *gb, int range){ static inline int get_se_golomb(GetBitContext *gb){ unsigned int buf; int log; - + OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); - + if(buf >= (1<<27)){ buf >>= 32 - 9; LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); CLOSE_READER(re, gb); - + return ff_se_golomb_vlc_code[buf]; }else{ log= 2*av_log2(buf) - 31; buf>>= log; - + LAST_SKIP_BITS(re, gb, 32 - log); CLOSE_READER(re, gb); - + if(buf&1) buf= -(buf>>1); else buf= (buf>>1); @@ -160,10 +174,13 @@ static inline int svq3_get_se_golomb(GetBitContext *gb){ buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); CLOSE_READER(re, gb); - + return ff_interleaved_se_golomb_vlc_code[buf]; }else{ - buf |=1; + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + if((buf & 0xAAAAAAAA) == 0) return INVALID_VLC; @@ -171,20 +188,38 @@ static inline int svq3_get_se_golomb(GetBitContext *gb){ buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); } - LAST_SKIP_BITS(re, gb, 63 - 2*log); + LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); CLOSE_READER(re, gb); return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; } } +static inline int dirac_get_se_golomb(GetBitContext *gb){ + uint32_t buf; + uint32_t ret; + + ret = svq3_get_ue_golomb(gb); + + if (ret) { + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = SHOW_SBITS(re, gb, 1); + LAST_SKIP_BITS(re, gb, 1); + ret = (ret ^ buf) - buf; + CLOSE_READER(re, gb); + } + + return ret; +} + /** * read unsigned golomb rice code (ffv1). */ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){ unsigned int buf; int log; - + OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); @@ -196,13 +231,13 @@ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len buf += (30-log)<>= 32 - limit - esc_len; LAST_SKIP_BITS(re, gb, esc_len + limit); CLOSE_READER(re, gb); - + return buf + limit - 1; } } @@ -213,19 +248,19 @@ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){ unsigned int buf; int log; - + OPEN_READER(re, gb); UPDATE_CACHE(re, gb); buf=GET_CACHE(re, gb); log= av_log2(buf); - + if(log > 31-11){ buf >>= log - k; buf += (30-log)<>1; + else return -(v>>1); + +// return (v>>1) ^ -(v&1); +} + +/** + * read signed golomb rice code (flac). + */ +static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){ + int v= get_ur_golomb_jpegls(gb, k, limit, esc_len); + return (v>>1) ^ -(v&1); +} + +/** + * read unsigned golomb rice code (shorten). + */ +static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){ + return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); +} + +/** + * read signed golomb rice code (shorten). + */ +static inline int get_sr_golomb_shorten(GetBitContext* gb, int k) +{ + int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); + if (uvar & 1) + return ~(uvar >> 1); + else + return uvar >> 1; +} + + + #ifdef TRACE -static inline int get_ue(GetBitContext *s, char *file, char *func, int line){ +static inline int get_ue(GetBitContext *s, char *file, const char *func, int line){ int show= show_bits(s, 24); int pos= get_bits_count(s); int i= get_ue_golomb(s); int len= get_bits_count(s) - pos; int bits= show>>(24-len); - + print_bin(bits, len); - - printf("%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); - + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + return i; } -static inline int get_se(GetBitContext *s, char *file, char *func, int line){ +static inline int get_se(GetBitContext *s, char *file, const char *func, int line){ int show= show_bits(s, 24); int pos= get_bits_count(s); int i= get_se_golomb(s); int len= get_bits_count(s) - pos; int bits= show>>(24-len); - + print_bin(bits, len); - - printf("%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); - + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + return i; } -static inline int get_te(GetBitContext *s, int r, char *file, char *func, int line){ +static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){ int show= show_bits(s, 24); int pos= get_bits_count(s); int i= get_te0_golomb(s, r); int len= get_bits_count(s) - pos; int bits= show>>(24-len); - + print_bin(bits, len); - - printf("%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); - + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + return i; } @@ -312,7 +389,7 @@ static inline int get_te(GetBitContext *s, int r, char *file, char *func, int li */ static inline void set_ue_golomb(PutBitContext *pb, int i){ int e; - + assert(i>=0); #if 0 @@ -325,7 +402,7 @@ static inline void set_ue_golomb(PutBitContext *pb, int i){ put_bits(pb, ff_ue_golomb_len[i], i+1); else{ e= av_log2(i+1); - + put_bits(pb, 2*e+1, i+1); } } @@ -342,10 +419,12 @@ static inline void set_te_golomb(PutBitContext *pb, int i, int range){ } /** - * write signed exp golomb code. + * write signed exp golomb code. 16 bits at most. */ static inline void set_se_golomb(PutBitContext *pb, int i){ -#if 0 +// if (i>32767 || i<-32767) +// av_log(NULL,AV_LOG_ERROR,"value out of range %d\n", i); +#if 0 if(i<=0) i= -2*i; else i= 2*i-1; #elif 1 @@ -363,9 +442,9 @@ static inline void set_se_golomb(PutBitContext *pb, int i){ */ static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ int e; - + assert(i>=0); - + e= i>>k; if(e=0); - + e= (i>>k) + 1; if(e 31) { + put_bits(pb, 31, 0); + e -= 31; + } put_bits(pb, e, 1); if(k) - put_bits(pb, k, i&((1< 31) { + put_bits(pb, 31, 0); + limit -= 31; + } put_bits(pb, limit , 1); put_bits(pb, esc_len, i - 1); } } + +/** + * write signed golomb rice code (ffv1). + */ +static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int v; + + v = -2*i-1; + v ^= (v>>31); + + set_ur_golomb(pb, v, k, limit, esc_len); +} + +/** + * write signed golomb rice code (flac). + */ +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int v; + + v = -2*i-1; + v ^= (v>>31); + + set_ur_golomb_jpegls(pb, v, k, limit, esc_len); +} + +#endif /* FFMPEG_GOLOMB_H */