Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
Data Structures | Macros | Typedefs | Functions
compgif.c File Reference
#include "rle_config.h"
#include <stdio.h>
#include "rletogif.h"
Include dependency graph for compgif.c:

Go to the source code of this file.

Data Structures

struct  str_table_entry
 
struct  str_table_node
 

Macros

#define MAXIMUMCODE   4095 /* 2**maximum_code_size */
 
#define BLOCKSIZE   256 /* max block byte count + 1 */
 
#define NULLPREFIX   -1
 

Typedefs

typedef struct str_table_entry strTableEntry
 
typedef struct str_table_node strTableNode
 
typedef struct str_table_nodestrTableNodePtr
 
typedef struct str_table_node ** strTable
 

Functions

int pack_bits ()
 
int compgif (int code_size, FILE *os, ifunptr infun)
 
int pack_bits (int compress_size, int prefix, FILE *os)
 

Macro Definition Documentation

#define BLOCKSIZE   256 /* max block byte count + 1 */

Definition at line 40 of file compgif.c.

#define MAXIMUMCODE   4095 /* 2**maximum_code_size */

Definition at line 39 of file compgif.c.

#define NULLPREFIX   -1

Definition at line 41 of file compgif.c.

Typedef Documentation

typedef struct str_table_node ** strTable
typedef struct str_table_node strTableNode
typedef struct str_table_node * strTableNodePtr

Function Documentation

int compgif ( int  code_size,
FILE*  os,
ifunptr  infun 
)

Definition at line 70 of file compgif.c.

74 {
75  strTable heap; /* our very own memory manager */
76  int heap_index;
77  int clear_code, end_code, cur_code;
78  int i, found, num_colors, prefix, compress_size;
79  int cur_char, end_of_data, bits_per_pix;
80  strTableNodePtr cur_node;
81  strTable root; /* root of string table for LZW compression */
82  /* is an array of 2**bits_per_pix pointers
83  to atomic nodes */
84  heap_index = 0;
85  heap = (strTable)malloc(sizeof(strTableNodePtr)*MAXIMUMCODE);
86  if (heap == NULL) error("can't allocate heap");
87  for (i=0; i < MAXIMUMCODE; i++) {
88  heap[i] = (strTableNodePtr)malloc(sizeof(strTableNode));
89  if (heap[i] == NULL) error("can't allocate heap");
90  }
91  bits_per_pix = code_size - 1;
92  compress_size = code_size;
93  num_colors = 1<<(bits_per_pix);
94  clear_code = num_colors;
95  end_code = clear_code + 1;
96  cur_code = end_code + 1;
97  prefix = NULLPREFIX;
98  root = (strTable)malloc(sizeof(strTableNodePtr)*num_colors);
99  if (!root) error("memory allocation failure (root)");
100  for(i=0; i<num_colors; i++) {
101  root[i] = heap[heap_index++];
102  root[i]->entry.code = i;
103  root[i]->entry.prefix = NULLPREFIX;
104  root[i]->entry.suffix = i;
105  root[i]->left = NULL;
106  root[i]->right = NULL;
107  root[i]->children = NULL;
108  }
109  /* initialize output block */
110  pack_bits(compress_size, -1, os);
111  pack_bits(compress_size, clear_code, os);
112  end_of_data = 0;
113  if((cur_char = GIFNextPixel(infun)) == EOF) error("premature end of data");
114  while (!end_of_data) {
115  prefix = cur_char;
116  cur_node = root[prefix];
117  found = 1;
118  if((cur_char = GIFNextPixel(infun)) == EOF) {
119  end_of_data = 1; break;
120  }
121  while(cur_node->children && found) {
122  cur_node = cur_node->children;
123  while(cur_node->entry.suffix != cur_char) {
124  if (cur_char < cur_node->entry.suffix) {
125  if (cur_node->left) cur_node = cur_node->left;
126  else {
127  cur_node->left = heap[heap_index++];
128  cur_node = cur_node->left;
129  found = 0; break;
130  }
131  }
132  else {
133  if (cur_node->right) cur_node = cur_node->right;
134  else {
135  cur_node->right = heap[heap_index++];
136  cur_node = cur_node->right;
137  found = 0; break;
138  }
139  }
140  }
141  if (found) {
142  prefix = cur_node->entry.code;
143  if((cur_char = GIFNextPixel(infun)) == EOF) {
144  end_of_data = 1; break;
145  }
146  }
147  }
148  if (end_of_data) break;
149  if (found) {
150  cur_node->children = heap[heap_index++];
151  cur_node = cur_node->children;
152  }
153  cur_node->children = NULL;
154  cur_node->left = NULL;
155  cur_node->right = NULL;
156  cur_node->entry.code = cur_code;
157  cur_node->entry.prefix = prefix;
158  cur_node->entry.suffix = cur_char;
159  pack_bits(compress_size, prefix, os);
160  if (cur_code > ((1<<(compress_size))-1))
161  compress_size++;
162  if (cur_code < MAXIMUMCODE) {
163  cur_code++;
164  }
165  else {
166  heap_index = num_colors; /* reinitialize string table */
167  for (i=0; i < num_colors; i++ ) root[i]->children = NULL;
168  pack_bits(compress_size, clear_code, os);
169  compress_size = bits_per_pix + 1;
170  cur_code = end_code + 1;
171  }
172  }
173  pack_bits(compress_size, prefix, os);
174  pack_bits(compress_size, end_code, os);
175  pack_bits(compress_size, -1, os);
176  for (i=0; i < MAXIMUMCODE; i++) free(heap[i]);
177  free(heap);
178  free(root);
179  return (1);
180 }
struct str_table_node * children
Definition: compgif.c:54
int GIFNextPixel()
struct str_table_node * right
Definition: compgif.c:53
struct str_table_node * strTableNodePtr
int suffix
Definition: compgif.c:47
struct str_table_node * left
Definition: compgif.c:52
#define NULLPREFIX
Definition: compgif.c:41
static void error(int)
Definition: aliastorle.c:559
#define MAXIMUMCODE
Definition: compgif.c:39
int code
Definition: compgif.c:45
void * malloc()
int i
Definition: rletorla.c:82
int pack_bits()
strTableEntry entry
Definition: compgif.c:51
int prefix
Definition: compgif.c:46
struct str_table_node ** strTable
int pack_bits ( )
int pack_bits ( int  compress_size,
int  prefix,
FILE*  os 
)

Definition at line 192 of file compgif.c.

196 {
197  static int cur_bit = 8;
198  static unsigned char block[BLOCKSIZE] = { 0 };
199  int i, left_over_bits;
200 
201  /* if we are about to excede the bounds of block or if the flush
202  code (code_bis < 0) we output the block */
203  if((cur_bit + compress_size > (BLOCKSIZE-1)*8) || (prefix < 0)) {
204  /* handle case of data overlapping blocks */
205  if ((left_over_bits = (((cur_bit>>3) +
206  ((cur_bit & 7) != 0))<<3) - cur_bit) != 0) {
207  for (i=0; i < left_over_bits; i++) {
208  if(prefix & (1<<i)) block[cur_bit>>3] |= (char)(1<<(cur_bit & 7));
209  /* note n>>3 == n/8 and n & 7 == n % 8 */
210  cur_bit++;
211  }
212  }
213  compress_size -= left_over_bits;
214  prefix = prefix>>left_over_bits;
215  block[0] = (unsigned char)((cur_bit>>3) - 1);
216  if (block[0]) fwrite(block,1,block[0]+1,os);
217  for(i=0; i < BLOCKSIZE; i++) block[i] = 0;
218  cur_bit = 8;
219  }
220  if (prefix >= 0) {
221  for (i=0; i < compress_size; i++) {
222  if(prefix & (1<<i)) block[cur_bit>>3] |=
223  (unsigned char)(1<<(cur_bit & 7));
224  /* note n>>3 == n/8 and n & 7 == n % 8 */
225  cur_bit++;
226  }
227  }
228  return (1);
229 }
#define BLOCKSIZE
Definition: compgif.c:40
int i
Definition: rletorla.c:82