FreeBASIC  0.91.0
gfx_lzw_enc.c
Go to the documentation of this file.
1 /* tiny LZW codec
2  * Based on code by Mark Nelson, Dr. Dobb's Journal October, 1989
3  */
4 
5 #include "fb_gfx.h"
6 #include "fb_gfx_lzw.h"
7 
8 static LZW_ENTRY *find_match(unsigned short prefix, unsigned char value)
9 {
10  unsigned short index, offset = 1;
11 
12  index = ((unsigned short)value << 4) ^ prefix;
13  if (index)
14  offset = TABLE_SIZE - index;
15  while (1) {
16  if ((fb_lzw_entry[index].code == -1) ||
17  ((fb_lzw_entry[index].prefix == prefix) && (fb_lzw_entry[index].value == value)))
18  return &fb_lzw_entry[index];
19  index = (index + offset) % TABLE_SIZE;
20  }
21 }
22 
24  (
25  const unsigned char *in_buffer,
26  ssize_t in_size,
27  unsigned char *out_buffer,
28  ssize_t *out_size
29  )
30 {
31  LZW_ENTRY *e;
32  unsigned short string_code, next_code = 256;
33  unsigned char bit = 0;
34  ssize_t size;
35 
36  size = 0;
37  fb_hMemSet(fb_lzw_entry, -1, sizeof(fb_lzw_entry));
38  string_code = *in_buffer++;
39  in_size--;
40  while (in_size) {
41  e = find_match(string_code, *in_buffer);
42  if (e->code != -1)
43  string_code = (unsigned short)e->code;
44  else {
45  if (next_code < MAX_CODE) {
46  e->code = next_code++;
47  e->prefix = string_code;
48  e->value = *in_buffer;
49  }
50  OUTPUT_CODE(string_code);
51  string_code = *in_buffer;
52  }
53  in_buffer++;
54  in_size--;
55  }
56  OUTPUT_CODE(string_code);
58  if (bit)
59  size++;
60  *out_size = size;
61  return 0;
62 }