* 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
*/
/**
+ * @file
* LZW encoder
- * @file lzwenc.c
* @author Bartlomiej Wolowiec
*/
#include "avcodec.h"
-#include "bitstream.h"
#include "lzw.h"
+#include "mathops.h"
+#include "put_bits.h"
#define LZW_MAXBITS 12
#define LZW_SIZTABLE (1<<LZW_MAXBITS)
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;
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);
}
s->tabsize++;
- if (s->tabsize >= 1 << s->bits)
+ if (s->tabsize >= (1 << s->bits) + (s->mode == FF_LZW_GIF))
s->bits++;
}
* @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;
* @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;
}
/**
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);
}
* @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);