1/* 2 * LZW encoder 3 * Copyright (c) 2007 Bartlomiej Wolowiec 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * LZW encoder 25 * @author Bartlomiej Wolowiec 26 */ 27 28#include <stdint.h> 29#include "libavutil/avassert.h" 30#include "libavutil/macros.h" 31#include "lzw.h" 32#include "put_bits.h" 33 34#define LZW_MAXBITS 12 35#define LZW_SIZTABLE (1<<LZW_MAXBITS) 36#define LZW_HASH_SIZE 16411 37#define LZW_HASH_SHIFT 6 38 39#define LZW_PREFIX_EMPTY -1 40#define LZW_PREFIX_FREE -2 41 42/** One code in hash table */ 43typedef struct Code{ 44 /// Hash code of prefix, LZW_PREFIX_EMPTY if empty prefix, or LZW_PREFIX_FREE if no code 45 int hash_prefix; 46 int code; ///< LZW code 47 uint8_t suffix; ///< Last character in code block 48}Code; 49 50/** LZW encode state */ 51typedef struct LZWEncodeState { 52 int clear_code; ///< Value of clear code 53 int end_code; ///< Value of end code 54 Code tab[LZW_HASH_SIZE]; ///< Hash table 55 int tabsize; ///< Number of values in hash table 56 int bits; ///< Actual bits code 57 int bufsize; ///< Size of output buffer 58 PutBitContext pb; ///< Put bit context for output 59 int maxbits; ///< Max bits code 60 int maxcode; ///< Max value of code 61 int output_bytes; ///< Number of written bytes 62 int last_code; ///< Value of last output code or LZW_PREFIX_EMPTY 63 enum FF_LZW_MODES mode; ///< TIFF or GIF 64 int little_endian; ///< GIF is LE while TIFF is BE 65}LZWEncodeState; 66 67 68const int ff_lzw_encode_state_size = sizeof(LZWEncodeState); 69 70/** 71 * Hash function adding character 72 * @param head LZW code for prefix 73 * @param add Character to add 74 * @return New hash value 75 */ 76static inline int hash(int head, const int add) 77{ 78 head ^= (add << LZW_HASH_SHIFT); 79 if (head >= LZW_HASH_SIZE) 80 head -= LZW_HASH_SIZE; 81 av_assert2(head >= 0 && head < LZW_HASH_SIZE); 82 return head; 83} 84 85/** 86 * Hash function calculates next hash value 87 * @param head Actual hash code 88 * @param offset Offset calculated by hashOffset 89 * @return New hash value 90 */ 91static inline int hashNext(int head, const int offset) 92{ 93 head -= offset; 94 if(head < 0) 95 head += LZW_HASH_SIZE; 96 return head; 97} 98 99/** 100 * Hash function calculates hash offset 101 * @param head Actual hash code 102 * @return Hash offset 103 */ 104static inline int hashOffset(const int head) 105{ 106 return head ? LZW_HASH_SIZE - head : 1; 107} 108 109/** 110 * Write one code to stream 111 * @param s LZW state 112 * @param c code to write 113 */ 114static inline void writeCode(LZWEncodeState * s, int c) 115{ 116 av_assert2(0 <= c && c < 1 << s->bits); 117 if (s->little_endian) 118 put_bits_le(&s->pb, s->bits, c); 119 else 120 put_bits(&s->pb, s->bits, c); 121} 122 123 124/** 125 * Find LZW code for block 126 * @param s LZW state 127 * @param c Last character in block 128 * @param hash_prefix LZW code for prefix 129 * @return LZW code for block or -1 if not found in table 130 */ 131static inline int findCode(LZWEncodeState * s, uint8_t c, int hash_prefix) 132{ 133 int h = hash(FFMAX(hash_prefix, 0), c); 134 int hash_offset = hashOffset(h); 135 136 while (s->tab[h].hash_prefix != LZW_PREFIX_FREE) { 137 if ((s->tab[h].suffix == c) 138 && (s->tab[h].hash_prefix == hash_prefix)) 139 return h; 140 h = hashNext(h, hash_offset); 141 } 142 143 return h; 144} 145 146/** 147 * Add block to LZW code table 148 * @param s LZW state 149 * @param c Last character in block 150 * @param hash_prefix LZW code for prefix 151 * @param hash_code LZW code for bytes block 152 */ 153static inline void addCode(LZWEncodeState * s, uint8_t c, int hash_prefix, int hash_code) 154{ 155 s->tab[hash_code].code = s->tabsize; 156 s->tab[hash_code].suffix = c; 157 s->tab[hash_code].hash_prefix = hash_prefix; 158 159 s->tabsize++; 160 161 if (s->tabsize >= (1 << s->bits) + (s->mode == FF_LZW_GIF)) 162 s->bits++; 163} 164 165/** 166 * Clear LZW code table 167 * @param s LZW state 168 */ 169static void clearTable(LZWEncodeState * s) 170{ 171 int i, h; 172 173 writeCode(s, s->clear_code); 174 s->bits = 9; 175 for (i = 0; i < LZW_HASH_SIZE; i++) { 176 s->tab[i].hash_prefix = LZW_PREFIX_FREE; 177 } 178 for (i = 0; i < 256; i++) { 179 h = hash(0, i); 180 s->tab[h].code = i; 181 s->tab[h].suffix = i; 182 s->tab[h].hash_prefix = LZW_PREFIX_EMPTY; 183 } 184 s->tabsize = 258; 185} 186 187/** 188 * Calculate number of bytes written 189 * @param s LZW encode state 190 * @return Number of bytes written 191 */ 192static int writtenBytes(LZWEncodeState *s){ 193 int ret = put_bytes_count(&s->pb, 0); 194 ret -= s->output_bytes; 195 s->output_bytes += ret; 196 return ret; 197} 198 199/** 200 * Initialize LZW encoder. Please set s->clear_code, s->end_code and s->maxbits before run. 201 * @param s LZW state 202 * @param outbuf Output buffer 203 * @param outsize Size of output buffer 204 * @param maxbits Maximum length of code 205 */ 206void ff_lzw_encode_init(LZWEncodeState *s, uint8_t *outbuf, int outsize, 207 int maxbits, enum FF_LZW_MODES mode, int little_endian) 208{ 209 s->clear_code = 256; 210 s->end_code = 257; 211 s->maxbits = maxbits; 212 init_put_bits(&s->pb, outbuf, outsize); 213 s->bufsize = outsize; 214 av_assert0(s->maxbits >= 9 && s->maxbits <= LZW_MAXBITS); 215 s->maxcode = 1 << s->maxbits; 216 s->output_bytes = 0; 217 s->last_code = LZW_PREFIX_EMPTY; 218 s->bits = 9; 219 s->mode = mode; 220 s->little_endian = little_endian; 221} 222 223/** 224 * LZW main compress function 225 * @param s LZW state 226 * @param inbuf Input buffer 227 * @param insize Size of input buffer 228 * @return Number of bytes written or -1 on error 229 */ 230int ff_lzw_encode(LZWEncodeState * s, const uint8_t * inbuf, int insize) 231{ 232 int i; 233 234 if(insize * 3 > (s->bufsize - s->output_bytes) * 2){ 235 return -1; 236 } 237 238 if (s->last_code == LZW_PREFIX_EMPTY) 239 clearTable(s); 240 241 for (i = 0; i < insize; i++) { 242 uint8_t c = *inbuf++; 243 int code = findCode(s, c, s->last_code); 244 if (s->tab[code].hash_prefix == LZW_PREFIX_FREE) { 245 writeCode(s, s->last_code); 246 addCode(s, c, s->last_code, code); 247 code= hash(0, c); 248 } 249 s->last_code = s->tab[code].code; 250 if (s->tabsize >= s->maxcode - 1) { 251 clearTable(s); 252 } 253 } 254 255 return writtenBytes(s); 256} 257 258/** 259 * Write end code and flush bitstream 260 * @param s LZW state 261 * @return Number of bytes written or -1 on error 262 */ 263int ff_lzw_encode_flush(LZWEncodeState *s) 264{ 265 if (s->last_code != -1) 266 writeCode(s, s->last_code); 267 writeCode(s, s->end_code); 268 if (s->little_endian) { 269 if (s->mode == FF_LZW_GIF) 270 put_bits_le(&s->pb, 1, 0); 271 272 flush_put_bits_le(&s->pb); 273 } else { 274 if (s->mode == FF_LZW_GIF) 275 put_bits(&s->pb, 1, 0); 276 277 flush_put_bits(&s->pb); 278 } 279 s->last_code = -1; 280 281 return writtenBytes(s); 282} 283