X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flzwenc.c;h=df38116c0db8cff795628d3d39b9192cfdc8bafd;hb=4320a309ce10a7eec93aef239a0776a33b1a5a34;hp=5b448953c83f5bb5f99067be63da36304a5a75f1;hpb=f0790c59f4485f32eace69ab68b53f097a617a8d;p=ffmpeg diff --git a/libavcodec/lzwenc.c b/libavcodec/lzwenc.c index 5b448953c83..df38116c0db 100644 --- a/libavcodec/lzwenc.c +++ b/libavcodec/lzwenc.c @@ -2,31 +2,31 @@ * LZW encoder * Copyright (c) 2007 Bartlomiej Wolowiec * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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, + * Libav 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 + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * LZW encoder - * @file lzwenc.c + * @file * @author Bartlomiej Wolowiec */ #include "avcodec.h" -#include "bitstream.h" +#include "put_bits.h" #include "lzw.h" #define LZW_MAXBITS 12 @@ -58,6 +58,8 @@ typedef struct LZWEncodeState { int maxcode; ///< Max value of code int output_bytes; ///< Number of written bytes int last_code; ///< Value of last output code or LZW_PREFIX_EMPTY + enum FF_LZW_MODES mode; ///< TIFF or GIF + void (*put_bits)(PutBitContext *, int, unsigned); ///< GIF is LE while TIFF is BE }LZWEncodeState; @@ -110,7 +112,7 @@ static inline int hashOffset(const int head) static inline void writeCode(LZWEncodeState * s, int c) { assert(0 <= c && c < 1 << s->bits); - put_bits(&s->pb, s->bits, c); + s->put_bits(&s->pb, s->bits, c); } @@ -151,7 +153,7 @@ static inline void addCode(LZWEncodeState * s, uint8_t c, int hash_prefix, int h s->tabsize++; - if (s->tabsize >= 1 << s->bits) + if (s->tabsize >= (1 << s->bits) + (s->mode == FF_LZW_GIF)) s->bits++; } @@ -183,7 +185,7 @@ static void clearTable(LZWEncodeState * s) * @return Number of bytes written */ static int writtenBytes(LZWEncodeState *s){ - int ret = (put_bits_count(&s->pb)) >> 3; + int ret = put_bits_count(&s->pb) >> 3; ret -= s->output_bytes; s->output_bytes += ret; return ret; @@ -196,18 +198,22 @@ static int writtenBytes(LZWEncodeState *s){ * @param outsize Size of output buffer * @param maxbits Maximum length of code */ -void ff_lzw_encode_init(LZWEncodeState * s, uint8_t * outbuf, int outsize, int maxbits) +void ff_lzw_encode_init(LZWEncodeState *s, uint8_t *outbuf, int outsize, + int maxbits, enum FF_LZW_MODES mode, + void (*lzw_put_bits)(PutBitContext *, int, unsigned)) { s->clear_code = 256; s->end_code = 257; s->maxbits = maxbits; init_put_bits(&s->pb, outbuf, outsize); s->bufsize = outsize; - assert(9 <= s->maxbits && s->maxbits <= s->maxbits); + assert(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS); s->maxcode = 1 << s->maxbits; s->output_bytes = 0; s->last_code = LZW_PREFIX_EMPTY; s->bits = 9; + s->mode = mode; + s->put_bits = lzw_put_bits; } /** @@ -220,30 +226,27 @@ void ff_lzw_encode_init(LZWEncodeState * s, uint8_t * outbuf, int outsize, int m int ff_lzw_encode(LZWEncodeState * s, const uint8_t * inbuf, int insize) { int i; - int code_prefix = s->last_code; if(insize * 3 > (s->bufsize - s->output_bytes) * 2){ return -1; } - if (code_prefix == LZW_PREFIX_EMPTY) + if (s->last_code == LZW_PREFIX_EMPTY) clearTable(s); for (i = 0; i < insize; i++) { uint8_t c = *inbuf++; - int code = findCode(s, c, code_prefix); - if (s->tab[code].hash_prefix != LZW_PREFIX_FREE) { - code_prefix = s->tab[code].code; - } else { - writeCode(s, code_prefix); - addCode(s, c, code_prefix, code); - code_prefix = s->tab[hash(0, c)].code; + int code = findCode(s, c, s->last_code); + if (s->tab[code].hash_prefix == LZW_PREFIX_FREE) { + writeCode(s, s->last_code); + addCode(s, c, s->last_code, code); + code= hash(0, c); } + s->last_code = s->tab[code].code; if (s->tabsize >= s->maxcode - 1) { clearTable(s); } } - s->last_code = code_prefix; return writtenBytes(s); } @@ -253,12 +256,13 @@ int ff_lzw_encode(LZWEncodeState * s, const uint8_t * inbuf, int insize) * @param s LZW state * @return Number of bytes written or -1 on error */ -int ff_lzw_encode_flush(LZWEncodeState * s) +int ff_lzw_encode_flush(LZWEncodeState *s, + void (*lzw_flush_put_bits)(PutBitContext *)) { if (s->last_code != -1) writeCode(s, s->last_code); writeCode(s, s->end_code); - flush_put_bits(&s->pb); + lzw_flush_put_bits(&s->pb); s->last_code = -1; return writtenBytes(s);