mirror of http://192.168.1.51:8099/lmh188/twain3.0
1357 lines
47 KiB
C
1357 lines
47 KiB
C
|
/*
|
||
|
# proc: grp4decomp - CCITT Group 4 decompresses an image.
|
||
|
# proc:
|
||
|
*/
|
||
|
|
||
|
/********************************************************************
|
||
|
* File Name: grp4decomp.c *
|
||
|
* Modified: Darlene E. Frederick *
|
||
|
* Michael D. Garris *
|
||
|
* Date: January 25, 1990 *
|
||
|
* Package: CCITT4 compression routines *
|
||
|
* *
|
||
|
* Contents: ccitt4_decompress() *
|
||
|
* read_compressed_file_into_memory() *
|
||
|
* control_decompression() *
|
||
|
* prepare_to_decompress() *
|
||
|
* set_up_first_and_last_changing_elements_d() *
|
||
|
* prepare_to_decompress_next_line() *
|
||
|
* set_up_first_line_d() *
|
||
|
* ReportError() *
|
||
|
********************************************************************/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <memory.h>
|
||
|
//#include <assert.h>
|
||
|
#ifdef TIME
|
||
|
#include <sys/time.h>
|
||
|
#endif
|
||
|
#include "g4codec.h"
|
||
|
#include "grp4deco.h"
|
||
|
|
||
|
// Constants
|
||
|
#define NOALLOC 0
|
||
|
#define ALLOC 1
|
||
|
|
||
|
// Structs
|
||
|
static struct changing_element {
|
||
|
SHORT color; /* the color of the pixel */
|
||
|
SHORT pixel; /* the position of the pixel on the line */
|
||
|
} a0, a1;
|
||
|
|
||
|
static SHORT b1, b2; /* an index into reference_line */
|
||
|
|
||
|
// Local variables
|
||
|
static int decomp_alloc_flag;
|
||
|
static int decomp_write_init_flag;
|
||
|
static int decomp_read_init_flag;
|
||
|
|
||
|
static char *all_white;
|
||
|
static char *output_area;
|
||
|
static char *all_black;
|
||
|
|
||
|
|
||
|
#ifdef TIME
|
||
|
struct timeval t1, t2;
|
||
|
struct timezone tz;
|
||
|
#endif
|
||
|
|
||
|
//#if Debug // to keep track of where we are
|
||
|
static int current_Byte;
|
||
|
static SHORT current_Line = 0; // counting starts from 1
|
||
|
//#endif
|
||
|
|
||
|
// Local functions
|
||
|
static void ReportError(char *message);
|
||
|
|
||
|
/********************************************************************
|
||
|
* grp4decomp is the main routine of this file. It does pre- *
|
||
|
* liminary setup, calls routines, and does final processing. *
|
||
|
********************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* indata - buffer containing the compressed data. *
|
||
|
* inbytes - the number of bytes in indata. *
|
||
|
* width - Width in pixels of uncompressed data. *
|
||
|
* height - Number of lines of uncompressed data. *
|
||
|
* Returned: *
|
||
|
* outdata - buffer containing the decompressed data*
|
||
|
* outbytes - the number of bytes in outdata. *
|
||
|
********************************************************************/
|
||
|
int grp4decomp(unsigned char* indata,
|
||
|
int inbytes,
|
||
|
int width,
|
||
|
int height,
|
||
|
unsigned char *outdata,
|
||
|
int *outbytes)
|
||
|
{
|
||
|
struct compressed_descriptor compressed;
|
||
|
struct decompressed_descriptor decompressed;
|
||
|
|
||
|
compressed.pixels_per_line = width;
|
||
|
compressed.number_of_lines = height;
|
||
|
compressed.length_in_bytes = inbytes;
|
||
|
compressed.data = (char *)indata;
|
||
|
decomp_alloc_flag = NOALLOC;
|
||
|
decomp_write_init_flag = 1;
|
||
|
decomp_read_init_flag = 1;
|
||
|
read_compressed_file_into_memory(&compressed);
|
||
|
decompressed.data = (char *)outdata;
|
||
|
control_decompression( &compressed, &decompressed );
|
||
|
*outbytes =
|
||
|
(decompressed.pixels_per_line >> 3) * decompressed.number_of_lines;
|
||
|
return (*outbytes);
|
||
|
}
|
||
|
|
||
|
|
||
|
/***************************** control_decompression **************************
|
||
|
|
||
|
calls the functions that decompress the compressed file
|
||
|
|
||
|
*****************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* compressed - structure containing the # of *
|
||
|
* pixels per line, the number of *
|
||
|
* lines, and the compressed data. *
|
||
|
* Returned: *
|
||
|
* decompressed - structure containing the # of *
|
||
|
* pixels per line, the number of *
|
||
|
* lines, and the compressed data. *
|
||
|
********************************************************************/
|
||
|
void control_decompression(struct compressed_descriptor *compressed,
|
||
|
struct decompressed_descriptor *decompressed)
|
||
|
{
|
||
|
struct parameters sole_parameters;
|
||
|
struct parameters *params = &sole_parameters;
|
||
|
|
||
|
#ifdef TIME
|
||
|
SHORT i;
|
||
|
tz.tz_minuteswest = 0;
|
||
|
tz.tz_dsttime = 0;
|
||
|
gettimeofday(&t1, &tz);
|
||
|
#endif
|
||
|
|
||
|
prepare_to_decompress( compressed, decompressed, params );
|
||
|
while(decompress_line( params ) != EOFB )
|
||
|
prepare_to_decompress_next_line( params );
|
||
|
/* memory deallocation added by Michael D. Garris 2/23/90 */
|
||
|
free(params->reference_line);
|
||
|
free(params->coding_line);
|
||
|
free(all_white);
|
||
|
free(all_black);
|
||
|
if (current_Line != (decompressed->number_of_lines+1))
|
||
|
{
|
||
|
ReportError("Not enough lines in input!");
|
||
|
}
|
||
|
#ifdef TIME
|
||
|
gettimeofday(&t2, &tz);
|
||
|
printf("\ntime difference: %ld:%ld\n", t2.tv_sec - t1.tv_sec,
|
||
|
t2.tv_usec - t1.tv_usec);
|
||
|
for(i=0; i<5; i++) printf("%c",'\07');
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************ read_compressed_file_into_memory *********************
|
||
|
|
||
|
allocates memory for the compressed image
|
||
|
|
||
|
*****************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* compressed - structure containing the # of *
|
||
|
* pixels per line, the number of *
|
||
|
* lines, and the compressed data. *
|
||
|
* Returned: *
|
||
|
* compressed - structure containing the # of *
|
||
|
* pixels per line, the number of *
|
||
|
* lines, and the compressed data. *
|
||
|
********************************************************************/
|
||
|
void read_compressed_file_into_memory(struct compressed_descriptor *compressed)
|
||
|
{
|
||
|
if(decomp_alloc_flag)
|
||
|
{
|
||
|
if((compressed->data = (char *)calloc(compressed->length_in_bytes,
|
||
|
sizeof(char))) == NULL)
|
||
|
{
|
||
|
printf("\nCannot allocate enough memory for compressed file.\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
else if(compressed->data == NULL)
|
||
|
{
|
||
|
printf("\nNo memory allocated for input data!\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
} /* end read_compressed_file_into_memory() */
|
||
|
|
||
|
|
||
|
|
||
|
/*************************** prepare_to_decompress ****************************
|
||
|
|
||
|
initializes variables in preperation for decompression
|
||
|
|
||
|
*****************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* compressed - structure containing the # of *
|
||
|
* pixels per line, the number of *
|
||
|
* lines, and the compressed data. *
|
||
|
* Returned: *
|
||
|
* decompressed - structure containing the # of *
|
||
|
* pixels per line, the number of *
|
||
|
* lines, and the compressed data. *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
********************************************************************/
|
||
|
void prepare_to_decompress(struct compressed_descriptor *compressed,
|
||
|
struct decompressed_descriptor *decompressed,
|
||
|
struct parameters *params)
|
||
|
{
|
||
|
|
||
|
params->max_pixel = compressed->pixels_per_line;
|
||
|
decompressed->pixels_per_line = compressed->pixels_per_line;
|
||
|
decompressed->number_of_lines = compressed->number_of_lines;
|
||
|
|
||
|
set_up_first_line_d( params );
|
||
|
prepare_to_read_bits( compressed->data );
|
||
|
if(decomp_alloc_flag)
|
||
|
{
|
||
|
decompressed->data = (char *)calloc(compressed->pixels_per_line *
|
||
|
compressed->number_of_lines / Pixels_per_byte, sizeof(char) );
|
||
|
}
|
||
|
else if(decompressed->data == NULL)
|
||
|
{
|
||
|
printf("\nNo memory allocated for decompressed data!\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
prepare_to_write_bits_d( decompressed->data,
|
||
|
(compressed->pixels_per_line / Pixels_per_byte) );
|
||
|
|
||
|
} /* end decompress() */
|
||
|
|
||
|
|
||
|
|
||
|
/******************************* set_up_first_line_d ***************************
|
||
|
|
||
|
initializes variables in preperation for decompressing the first line
|
||
|
|
||
|
******************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
* Returned: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
********************************************************************/
|
||
|
void set_up_first_line_d(struct parameters *params)
|
||
|
{
|
||
|
|
||
|
params->reference_line =
|
||
|
(SHORT *)malloc( (params->max_pixel + Extra_positions) * sizeof(SHORT) );
|
||
|
params->coding_line =
|
||
|
(SHORT *)malloc( (params->max_pixel + Extra_positions) * sizeof(SHORT) );
|
||
|
|
||
|
*(params->reference_line + 0) = Invalid;
|
||
|
*(params->reference_line + 1) = params->max_pixel;
|
||
|
*(params->reference_line + 2) = params->max_pixel;
|
||
|
*(params->reference_line + 3) = params->max_pixel;
|
||
|
|
||
|
/* initialize first changing element on coding line (a0 = -1) */
|
||
|
*(params->coding_line) = Invalid;
|
||
|
|
||
|
params->index = 0;
|
||
|
|
||
|
} /* end set_up_first_line_d() */
|
||
|
|
||
|
|
||
|
|
||
|
/******************* set_up_first_and_last_changing_elements_d *****************
|
||
|
|
||
|
initializes the first and last changing elements in the coding line
|
||
|
|
||
|
******************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
* Returned: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
********************************************************************/
|
||
|
void set_up_first_and_last_changing_elements_d(struct parameters *params)
|
||
|
{
|
||
|
*(params->coding_line) = Invalid;
|
||
|
|
||
|
/*
|
||
|
* set up the imaginary first changing pixel with an illegal value.
|
||
|
*/
|
||
|
|
||
|
*(params->coding_line + ++params->index) = params->max_pixel;
|
||
|
*(params->coding_line + ++params->index) = params->max_pixel;
|
||
|
*(params->coding_line + ++params->index) = params->max_pixel;
|
||
|
|
||
|
/*
|
||
|
* set up three changing pixels at the end of the line, all of which
|
||
|
* contain the end-of-line flag "max_pixel." It is necessary to create
|
||
|
* three of these flags because the changing elements a0 - b2 are sometimes
|
||
|
* advanced by more than one element at a time (and therefore could skip
|
||
|
* over a single flag).
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*********************** prepare_to_decompress_next_line *********************
|
||
|
|
||
|
initializes variables in preperation for decompressing another line
|
||
|
|
||
|
******************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
* Returned: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
********************************************************************/
|
||
|
void prepare_to_decompress_next_line(struct parameters *params)
|
||
|
{
|
||
|
|
||
|
set_up_first_and_last_changing_elements_d( params );
|
||
|
swap_the_reference_and_coding_lines( params );
|
||
|
params->index = 0;
|
||
|
|
||
|
} /* end prepare_to_decompress_next_line() */
|
||
|
|
||
|
|
||
|
|
||
|
/******************** swap_the_reference_and_coding_lines ********************
|
||
|
|
||
|
swaps the reference and coding lines
|
||
|
|
||
|
*****************************************************************************/
|
||
|
/********************************************************************
|
||
|
* Arguments *
|
||
|
* --------- *
|
||
|
* Passed in: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
* Returned: *
|
||
|
* params - structure storing information needed *
|
||
|
* for comparison and other tasks. *
|
||
|
********************************************************************/
|
||
|
void swap_the_reference_and_coding_lines(struct parameters *params)
|
||
|
{
|
||
|
SHORT *temp;
|
||
|
|
||
|
temp = params->reference_line;
|
||
|
params->reference_line = params->coding_line;
|
||
|
params->coding_line = temp;
|
||
|
|
||
|
} /* end swap_the_reference_and_coding_lines() */
|
||
|
|
||
|
|
||
|
|
||
|
/*********************************** ReportError ***********************************
|
||
|
|
||
|
forces the program to crash and create a core file
|
||
|
|
||
|
******************************************************************************/
|
||
|
void ReportError(char *message)
|
||
|
{
|
||
|
FILE *crash_program = NULL;
|
||
|
|
||
|
printf("Detected error: %s\n", message);
|
||
|
printf("Input position: Byte-%d\n", current_Byte);
|
||
|
printf("Output position: Line-%d, Pixel-%d\n", current_Line, a0.pixel);
|
||
|
//printf("Press Enter to continue\n");
|
||
|
//scanf("\n");
|
||
|
system("PAUSE");
|
||
|
exit(-999);
|
||
|
// fprintf(crash_program,"This will kill the program and create a core file");
|
||
|
}
|
||
|
|
||
|
|
||
|
/***************************************************************************/
|
||
|
/* Originally decomp.c */
|
||
|
/***************************************************************************/
|
||
|
|
||
|
|
||
|
/******************************* decompress_line *****************************
|
||
|
|
||
|
decompress one line of the compressed image
|
||
|
|
||
|
******************************************************************************/
|
||
|
SHORT decompress_line(struct parameters *params)
|
||
|
{
|
||
|
SHORT mode;
|
||
|
|
||
|
current_Line++;
|
||
|
#if Debug
|
||
|
printf("\n\nLINE: %d\n", current_Line);
|
||
|
#endif
|
||
|
|
||
|
b1 = 1; /* this puts b1 on the first black element in the reference line ,
|
||
|
* which is appropriate because a0 is white and on -1 */
|
||
|
a0.pixel = 0;
|
||
|
a0.color = White;
|
||
|
do {
|
||
|
|
||
|
#if Debug
|
||
|
printf("a0:%d, a1:%d, b1:%d", a0.pixel, a1.pixel,
|
||
|
*(params->reference_line + b1));
|
||
|
#endif
|
||
|
mode = get_mode();
|
||
|
switch( mode )
|
||
|
{
|
||
|
|
||
|
case V0:
|
||
|
|
||
|
case VR1:
|
||
|
|
||
|
case VL1:
|
||
|
|
||
|
case VR2:
|
||
|
|
||
|
case VL2:
|
||
|
|
||
|
case VR3:
|
||
|
|
||
|
case VL3: vertical_mode_d( params, mode );
|
||
|
break;
|
||
|
|
||
|
case H: horizontal_mode_d( params );
|
||
|
break;
|
||
|
|
||
|
case P: pass_mode_d( params );
|
||
|
continue;
|
||
|
|
||
|
case EOFB: return( EOFB );
|
||
|
|
||
|
default: ReportError("Unrecognized code!");
|
||
|
|
||
|
} /* end case of different modes */
|
||
|
|
||
|
} while(a0.pixel < params->max_pixel);
|
||
|
if (a0.pixel != params->max_pixel)
|
||
|
{
|
||
|
ReportError("Line width larger than expected!");
|
||
|
}
|
||
|
return( Not_done_yet );
|
||
|
|
||
|
} /* end decompress_line */
|
||
|
|
||
|
|
||
|
|
||
|
/********************************** get_mode **********************************
|
||
|
|
||
|
read a mode code from the compressed image
|
||
|
|
||
|
******************************************************************************/
|
||
|
SHORT get_mode()
|
||
|
{
|
||
|
SHORT i;
|
||
|
|
||
|
if (read_bit() == 1)
|
||
|
return(V0); /* 1 */
|
||
|
|
||
|
if (read_bit() == 1) {
|
||
|
if (read_bit() == 1)
|
||
|
return(VR1); /* 011 */
|
||
|
else
|
||
|
return(VL1); /* 010 */
|
||
|
}
|
||
|
else {
|
||
|
if (read_bit() == 1)
|
||
|
return(H); /* 001 */
|
||
|
if (read_bit() == 1)
|
||
|
return(P); /* 0001 */
|
||
|
if (read_bit() == 1) {
|
||
|
if (read_bit() == 1)
|
||
|
return(VR2); /* 000011 */
|
||
|
else
|
||
|
return(VL2); /* 000010 */
|
||
|
}
|
||
|
else {
|
||
|
if (read_bit() == 1) {
|
||
|
if (read_bit() == 1)
|
||
|
return(VR3); /* 0000011 */
|
||
|
else
|
||
|
return(VL3); /* 0000010 */
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
/*
|
||
|
* Have read 6 zero's so far. The only valid code now
|
||
|
* possible is EOFB: 00000000000100000000001.
|
||
|
*/
|
||
|
|
||
|
for(i=0;i<5;i++)
|
||
|
if (read_bit() != 0)
|
||
|
ReportError("Expecting page terminating code!");
|
||
|
|
||
|
if (read_bit() != 1)
|
||
|
ReportError("Expecting page terminating code!");
|
||
|
|
||
|
for(i=0;i<11;i++)
|
||
|
if (read_bit() != 0)
|
||
|
ReportError("Expecting page terminating code!");
|
||
|
|
||
|
if (read_bit() != 1)
|
||
|
ReportError("Expecting page terminating code!");
|
||
|
|
||
|
return(EOFB); /* 00000000000100000000001 */
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} /* end get_mode() */
|
||
|
|
||
|
|
||
|
/********************************** pass_mode_d ********************************
|
||
|
|
||
|
decompress a pass mode code
|
||
|
|
||
|
******************************************************************************/
|
||
|
void pass_mode_d(struct parameters *params)
|
||
|
{
|
||
|
SHORT run_length;
|
||
|
|
||
|
b2 = b1 + 1;
|
||
|
run_length = *(params->reference_line + b2) - a0.pixel;
|
||
|
write_bits_d(run_length, a0.color);
|
||
|
|
||
|
#if Debug
|
||
|
printf(" P Run:%d, Color:%d\n", run_length, a0.color);
|
||
|
#endif
|
||
|
|
||
|
a0.pixel += run_length;
|
||
|
/* a0.color does not change during pass_mode_d() */
|
||
|
b1 += 2;
|
||
|
} /* end pass_mode_d() */
|
||
|
|
||
|
|
||
|
/******************************* vertical_mode_d *******************************
|
||
|
|
||
|
decompress a vertical mode code
|
||
|
|
||
|
******************************************************************************/
|
||
|
void vertical_mode_d(struct parameters *params, SHORT offset)
|
||
|
{
|
||
|
SHORT run_length;
|
||
|
|
||
|
a1.pixel = *(params->reference_line + b1) + offset;
|
||
|
run_length = a1.pixel - a0.pixel;
|
||
|
if (run_length < 0)
|
||
|
{
|
||
|
ReportError("a1 in front of a0!");
|
||
|
}
|
||
|
write_bits_d(run_length, a0.color);
|
||
|
|
||
|
#if Debug
|
||
|
printf(" V%d Run:%d, Color:%d\n", offset, run_length, a0.color);
|
||
|
#endif
|
||
|
|
||
|
a0.pixel = a1.pixel;
|
||
|
a0.color = ! a0.color;
|
||
|
*(params->coding_line + ++params->index) = a0.pixel;
|
||
|
|
||
|
/*
|
||
|
* The color of a0 changes after each vertical mode coding.
|
||
|
*/
|
||
|
|
||
|
if ((offset == -1) || (offset == 0)) {
|
||
|
if ( *(params->reference_line + b1) != params->max_pixel )
|
||
|
b1++;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ((offset == 1) || (offset == 2)) {
|
||
|
b1++;
|
||
|
if ( (*(params->reference_line + b1) <= a0.pixel) &&
|
||
|
(*(params->reference_line + b1) != params->max_pixel) )
|
||
|
b1 += 2;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ((offset == -2) || (offset == -3)) {
|
||
|
if ( *(params->reference_line + b1 - 1) > a0.pixel )
|
||
|
b1--;
|
||
|
else { if ( *(params->reference_line + b1) != params->max_pixel )
|
||
|
b1++;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (offset == 3) {
|
||
|
b1++;
|
||
|
while ( (*(params->reference_line + b1) <= a0.pixel) &&
|
||
|
(*(params->reference_line + b1) != params->max_pixel) )
|
||
|
b1 += 2;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
} /* end vertical_mode_d() */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/******************************* horizontal_mode_d *****************************
|
||
|
|
||
|
decompress a horizontal mode code
|
||
|
|
||
|
******************************************************************************/
|
||
|
void horizontal_mode_d(struct parameters *params)
|
||
|
{
|
||
|
SHORT length, total_length = 0;
|
||
|
|
||
|
do {
|
||
|
length = find_run_length_code(a0.color);
|
||
|
total_length += length;
|
||
|
} while (length > Max_terminating_length);
|
||
|
|
||
|
/*
|
||
|
* Run lengths greater than 63 are followed by terminating codes.
|
||
|
* Thus if "length" is greater than 63, the terminating code must
|
||
|
* also be fetched in order to determine the total run length.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
write_bits_d(total_length, a0.color);
|
||
|
|
||
|
#if Debug
|
||
|
printf(" H Run:%d, Color:%d\n", total_length, a0.color);
|
||
|
#endif
|
||
|
|
||
|
a0.pixel += total_length;
|
||
|
a0.color = !a0.color;
|
||
|
*(params->coding_line + ++params->index) = a0.pixel;
|
||
|
|
||
|
/*
|
||
|
* a0's color changes after each run color.
|
||
|
*/
|
||
|
|
||
|
total_length = 0;
|
||
|
do {
|
||
|
length = find_run_length_code(a0.color);
|
||
|
total_length += length;
|
||
|
} while (length > Max_terminating_length);
|
||
|
|
||
|
write_bits_d(total_length, a0.color);
|
||
|
|
||
|
#if Debug
|
||
|
printf(" Run:%d, Color:%d\n", total_length, a0.color);
|
||
|
#endif
|
||
|
|
||
|
a0.pixel += total_length;
|
||
|
a0.color = !a0.color;
|
||
|
*(params->coding_line + ++params->index) = a0.pixel;
|
||
|
|
||
|
while ( (*(params->reference_line + b1) <= a0.pixel) &&
|
||
|
( *(params->reference_line + b1) < params->max_pixel) )
|
||
|
{
|
||
|
b1 += 2; /* must move ahead by 2 to maintain color difference with */
|
||
|
/* a0, whose color does not change in this mode. */
|
||
|
}
|
||
|
|
||
|
} /* end horizontal_mode_d() */
|
||
|
|
||
|
|
||
|
/***************************************************************************/
|
||
|
/* Originally write.c */
|
||
|
/***************************************************************************/
|
||
|
|
||
|
static char write_one[Pixels_per_byte] =
|
||
|
{
|
||
|
(char)0x80, /* 10000000b: with | operator, it writes a one to bit 0 */
|
||
|
(char)0x40, /* 01000000b: with | operator, it writes a one to bit 1 */
|
||
|
(char)0x20, /* 00100000b: with | operator, it writes a one to bit 2 */
|
||
|
(char)0x10, /* 00010000b: with | operator, it writes a one to bit 3 */
|
||
|
(char)0x8, /* 00001000b: with | operator, it writes a one to bit 4 */
|
||
|
(char)0x4, /* 00000100b: with | operator, it writes a one to bit 5 */
|
||
|
(char)0x2, /* 00000010b: with | operator, it writes a one to bit 6 */
|
||
|
(char)0x1, /* 00000001b: with | operator, it writes a one to bit 7 */
|
||
|
};
|
||
|
|
||
|
static char write_zero[Pixels_per_byte] =
|
||
|
{
|
||
|
(char)0x7F, /* 01111111b: with & operator, it writes a zero to bit 0 */
|
||
|
(char)0xBF, /* 10111111b: with & operator, it writes a zero to bit 1 */
|
||
|
(char)0xDF, /* 11011111b: with & operator, it writes a zero to bit 2 */
|
||
|
(char)0xEF, /* 11101111b: with & operator, it writes a zero to bit 3 */
|
||
|
(char)0xF7, /* 11110111b: with & operator, it writes a zero to bit 4 */
|
||
|
(char)0xFB, /* 11111011b: with & operator, it writes a zero to bit 5 */
|
||
|
(char)0xFD, /* 11111101b: with & operator, it writes a zero to bit 6 */
|
||
|
(char)0xFE, /* 11111110b: with & operator, it writes a zero to bit 7 */
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************* prepare_to_write_bits_d ******************************
|
||
|
|
||
|
initializes variables in preperation for writing decompressed data
|
||
|
|
||
|
******************************************************************************/
|
||
|
void prepare_to_write_bits_d(char *output_pointer,
|
||
|
SHORT bytes_per_line)
|
||
|
{
|
||
|
output_area = output_pointer;
|
||
|
|
||
|
all_white = (char *)calloc( bytes_per_line, sizeof(char) );
|
||
|
all_black = (char *)calloc( bytes_per_line, sizeof(char) );
|
||
|
memset(all_black, Black_byte, bytes_per_line);
|
||
|
/* set all the pixels in "all_black" to '1' */
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/******************************* write_bits_d ***********************************
|
||
|
|
||
|
writes a number of bits of the same color to the memory buffer that holds
|
||
|
the decompressed image.
|
||
|
|
||
|
******************************************************************************/
|
||
|
void write_bits_d(unsigned SHORT length,
|
||
|
unsigned SHORT color)
|
||
|
{
|
||
|
static unsigned SHORT write_on_this_bit = 0;
|
||
|
static unsigned int write_on_this_byte = 0;
|
||
|
unsigned int bytes;
|
||
|
|
||
|
/* global switch added by Michael D. Garris 2/23/90 */
|
||
|
if(decomp_write_init_flag){
|
||
|
write_on_this_bit = 0;
|
||
|
write_on_this_byte = 0;
|
||
|
decomp_write_init_flag = 0;
|
||
|
}
|
||
|
if (color == Black) {
|
||
|
while( (length>0) && (write_on_this_bit != 0) ) {
|
||
|
*(output_area + write_on_this_byte) |= write_one[write_on_this_bit];
|
||
|
length--;
|
||
|
if (write_on_this_bit == Last_bit_in_a_byte) {
|
||
|
write_on_this_bit = 0;
|
||
|
write_on_this_byte++;
|
||
|
}
|
||
|
else
|
||
|
write_on_this_bit++;
|
||
|
}
|
||
|
|
||
|
memcpy((output_area+write_on_this_byte), all_black, (bytes=(length/8)));
|
||
|
write_on_this_byte += bytes;
|
||
|
length %= Bits_per_byte;
|
||
|
|
||
|
while( length>0 ) {
|
||
|
*(output_area + write_on_this_byte) |= write_one[write_on_this_bit];
|
||
|
length--;
|
||
|
if (write_on_this_bit == Last_bit_in_a_byte) {
|
||
|
write_on_this_bit = 0;
|
||
|
write_on_this_byte++;
|
||
|
}
|
||
|
else
|
||
|
write_on_this_bit++;
|
||
|
}
|
||
|
} /* end if color is black */
|
||
|
else {
|
||
|
while( (length>0) && (write_on_this_bit != 0) ) {
|
||
|
*(output_area + write_on_this_byte) &=write_zero[write_on_this_bit];
|
||
|
length--;
|
||
|
if (write_on_this_bit == Last_bit_in_a_byte) {
|
||
|
write_on_this_bit = 0;
|
||
|
write_on_this_byte++;
|
||
|
}
|
||
|
else
|
||
|
write_on_this_bit++;
|
||
|
}
|
||
|
|
||
|
memcpy((output_area+write_on_this_byte), all_white, (bytes=(length/8)));
|
||
|
write_on_this_byte += bytes;
|
||
|
length %= Bits_per_byte;
|
||
|
|
||
|
while( length>0 ) {
|
||
|
*(output_area + write_on_this_byte) &=write_zero[write_on_this_bit];
|
||
|
length--;
|
||
|
if (write_on_this_bit == Last_bit_in_a_byte) {
|
||
|
write_on_this_bit = 0;
|
||
|
write_on_this_byte++;
|
||
|
}
|
||
|
else
|
||
|
write_on_this_bit++;
|
||
|
}
|
||
|
} /* end if color is white */
|
||
|
} /* end write_bits_d() */
|
||
|
|
||
|
|
||
|
/***************************************************************************/
|
||
|
/* Originally read.c */
|
||
|
/***************************************************************************/
|
||
|
|
||
|
static char *input_area;
|
||
|
|
||
|
static char read_bit_mask[Pixels_per_byte] =
|
||
|
{
|
||
|
(char)0x80, /* 10000000b: with & operator, it reads bit 0 */
|
||
|
(char)0x40, /* 01000000b: with & operator, it reads bit 1 */
|
||
|
(char)0x20, /* 00100000b: with & operator, it reads bit 2 */
|
||
|
(char)0x10, /* 00010000b: with & operator, it reads bit 3 */
|
||
|
(char)0x8, /* 00001000b: with & operator, it reads bit 4 */
|
||
|
(char)0x4, /* 00000100b: with & operator, it reads bit 5 */
|
||
|
(char)0x2, /* 00000010b: with & operator, it reads bit 6 */
|
||
|
(char)0x1, /* 00000001b: with & operator, it reads bit 7 */
|
||
|
};
|
||
|
|
||
|
/************************* prepare_to_read_bits ******************************
|
||
|
|
||
|
initialize a local, static variable, input_area
|
||
|
|
||
|
******************************************************************************/
|
||
|
void prepare_to_read_bits(char *input_pointer)
|
||
|
{
|
||
|
input_area = input_pointer;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************* read_bit *************************************
|
||
|
|
||
|
returns the value of the current bit of the compressed image (e.g. 1 or 0)
|
||
|
|
||
|
******************************************************************************/
|
||
|
SHORT read_bit()
|
||
|
{
|
||
|
SHORT bit;
|
||
|
static unsigned SHORT read_this_bit = 0;
|
||
|
static unsigned int read_this_byte = 0;
|
||
|
|
||
|
/* global switch added by Michael D. Garris 2/23/90 */
|
||
|
if(decomp_read_init_flag){
|
||
|
read_this_bit = 0;
|
||
|
read_this_byte = 0;
|
||
|
decomp_read_init_flag = 0;
|
||
|
}
|
||
|
/*
|
||
|
* read_bits gets one bit from the compressed data file,
|
||
|
* and returns it as an integer value of 0 or 1.
|
||
|
*/
|
||
|
|
||
|
bit = *(input_area + read_this_byte) & read_bit_mask[read_this_bit];
|
||
|
if(read_this_bit == Last_bit_in_a_byte) {
|
||
|
read_this_bit = 0;
|
||
|
read_this_byte++;
|
||
|
} /* end if current byte completely read */
|
||
|
else
|
||
|
read_this_bit++;
|
||
|
|
||
|
//#if Debug
|
||
|
current_Byte = read_this_byte; // to keep track of where we are
|
||
|
//#endif
|
||
|
|
||
|
/*
|
||
|
* NOTE: bit contains 0 if the bit read was 0,
|
||
|
* or a non-zero number if the bit was 1.
|
||
|
*/
|
||
|
|
||
|
return( !(bit == 0) );
|
||
|
|
||
|
/*
|
||
|
* the above operation returns a zero if bit is equal to zero, or a
|
||
|
* one if bit is not equal to zero.
|
||
|
*/
|
||
|
|
||
|
} /* end read_bit() */
|
||
|
|
||
|
|
||
|
/***************************************************************************/
|
||
|
/* Originally tree.c */
|
||
|
/***************************************************************************/
|
||
|
|
||
|
struct node {
|
||
|
SHORT value;
|
||
|
struct node *child_zero;
|
||
|
struct node *child_one;
|
||
|
}; /* end node struct */
|
||
|
|
||
|
static struct node *node_ptr;
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
|
||
|
The following declarations create two ordered, unbalanced, binary trees.
|
||
|
The trees contain run length values, and are ordered by the Huffman codes
|
||
|
that correspond to those values.
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
struct node black_tree[] =
|
||
|
{
|
||
|
-1, &black_tree[ 2], &black_tree[ 1],
|
||
|
-1, &black_tree[ 4], &black_tree[ 3],
|
||
|
-1, &black_tree[ 6], &black_tree[ 5],
|
||
|
2, NULL, NULL,
|
||
|
3, NULL, NULL,
|
||
|
-1, &black_tree[ 8], &black_tree[ 7],
|
||
|
-1, &black_tree[ 10], &black_tree[ 9],
|
||
|
4, NULL, NULL,
|
||
|
1, NULL, NULL,
|
||
|
-1, &black_tree[ 12], &black_tree[ 11],
|
||
|
-1, &black_tree[ 14], &black_tree[ 13],
|
||
|
5, NULL, NULL,
|
||
|
6, NULL, NULL,
|
||
|
-1, &black_tree[ 16], &black_tree[ 15],
|
||
|
-1, &black_tree[ 18], &black_tree[ 17],
|
||
|
7, NULL, NULL,
|
||
|
-1, &black_tree[ 20], &black_tree[ 19],
|
||
|
-1, &black_tree[ 22], &black_tree[ 21],
|
||
|
-1, &black_tree[ 24], &black_tree[ 23],
|
||
|
8, NULL, NULL,
|
||
|
9, NULL, NULL,
|
||
|
-1, &black_tree[ 26], &black_tree[ 25],
|
||
|
-1, &black_tree[ 28], &black_tree[ 27],
|
||
|
-1, &black_tree[ 30], &black_tree[ 29],
|
||
|
-1, &black_tree[ 32], &black_tree[ 31],
|
||
|
12, NULL, NULL,
|
||
|
-1, &black_tree[ 34], &black_tree[ 33],
|
||
|
11, NULL, NULL,
|
||
|
10, NULL, NULL,
|
||
|
-1, &black_tree[ 36], &black_tree[ 35],
|
||
|
-1, &black_tree[ 38], &black_tree[ 37],
|
||
|
-1, &black_tree[ 40], &black_tree[ 39],
|
||
|
-1, NULL, &black_tree[ 41],
|
||
|
-1, &black_tree[ 43], &black_tree[ 42],
|
||
|
-1, &black_tree[ 45], &black_tree[ 44],
|
||
|
14, NULL, NULL,
|
||
|
-1, &black_tree[ 47], &black_tree[ 46],
|
||
|
-1, &black_tree[ 49], &black_tree[ 48],
|
||
|
13, NULL, NULL,
|
||
|
-1, &black_tree[ 51], &black_tree[ 50],
|
||
|
-1, &black_tree[ 53], &black_tree[ 52],
|
||
|
-1, &black_tree[ 55], &black_tree[ 54],
|
||
|
-1, &black_tree[ 57], &black_tree[ 56],
|
||
|
-1, &black_tree[ 59], &black_tree[ 58],
|
||
|
-1, &black_tree[ 61], &black_tree[ 60],
|
||
|
15, NULL, NULL,
|
||
|
-1, &black_tree[ 63], &black_tree[ 62],
|
||
|
-1, &black_tree[ 65], &black_tree[ 64],
|
||
|
-1, &black_tree[ 67], &black_tree[ 66],
|
||
|
-1, &black_tree[ 69], &black_tree[ 68],
|
||
|
-1, &black_tree[ 71], &black_tree[ 70],
|
||
|
-1, &black_tree[ 73], &black_tree[ 72],
|
||
|
-1, &black_tree[ 75], &black_tree[ 74],
|
||
|
-1, &black_tree[ 77], &black_tree[ 76],
|
||
|
-1, &black_tree[ 79], &black_tree[ 78],
|
||
|
-1, &black_tree[ 81], &black_tree[ 80],
|
||
|
0, NULL, NULL,
|
||
|
-1, &black_tree[ 83], &black_tree[ 82],
|
||
|
-1, &black_tree[ 85], &black_tree[ 84],
|
||
|
-1, &black_tree[ 87], &black_tree[ 86],
|
||
|
-1, &black_tree[ 89], &black_tree[ 88],
|
||
|
-1, &black_tree[ 91], &black_tree[ 90],
|
||
|
-1, &black_tree[ 93], &black_tree[ 92],
|
||
|
-1, &black_tree[ 95], &black_tree[ 94],
|
||
|
-1, &black_tree[ 97], &black_tree[ 96],
|
||
|
17, NULL, NULL,
|
||
|
16, NULL, NULL,
|
||
|
-1, &black_tree[ 99], &black_tree[ 98],
|
||
|
-1, &black_tree[101], &black_tree[100],
|
||
|
-1, &black_tree[103], &black_tree[102],
|
||
|
64, NULL, NULL,
|
||
|
-1, &black_tree[105], &black_tree[104],
|
||
|
-1, &black_tree[107], &black_tree[106],
|
||
|
-1, &black_tree[109], &black_tree[108],
|
||
|
-1, &black_tree[111], &black_tree[110],
|
||
|
-1, &black_tree[113], &black_tree[112],
|
||
|
-1, &black_tree[115], &black_tree[114],
|
||
|
18, NULL, NULL,
|
||
|
-1, &black_tree[117], &black_tree[116],
|
||
|
-1, &black_tree[119], &black_tree[118],
|
||
|
-1, &black_tree[121], &black_tree[120],
|
||
|
-1, &black_tree[123], &black_tree[122],
|
||
|
-1, &black_tree[125], &black_tree[124],
|
||
|
21, NULL, NULL,
|
||
|
-1, &black_tree[127], &black_tree[126],
|
||
|
-1, &black_tree[129], &black_tree[128],
|
||
|
-1, &black_tree[131], &black_tree[130],
|
||
|
20, NULL, NULL,
|
||
|
19, NULL, NULL,
|
||
|
-1, &black_tree[133], &black_tree[132],
|
||
|
-1, &black_tree[135], &black_tree[134],
|
||
|
-1, &black_tree[137], &black_tree[136],
|
||
|
22, NULL, NULL,
|
||
|
-1, &black_tree[139], &black_tree[138],
|
||
|
-1, &black_tree[141], &black_tree[140],
|
||
|
-1, &black_tree[143], &black_tree[142],
|
||
|
-1, &black_tree[145], &black_tree[144],
|
||
|
-1, &black_tree[147], &black_tree[146],
|
||
|
-1, &black_tree[149], &black_tree[148],
|
||
|
-1, &black_tree[151], &black_tree[150],
|
||
|
-1, &black_tree[153], &black_tree[152],
|
||
|
-1, &black_tree[155], &black_tree[154],
|
||
|
-1, &black_tree[157], &black_tree[156],
|
||
|
23, NULL, NULL,
|
||
|
-1, &black_tree[159], &black_tree[158],
|
||
|
-1, &black_tree[161], &black_tree[160],
|
||
|
-1, &black_tree[163], &black_tree[162],
|
||
|
-1, &black_tree[165], &black_tree[164],
|
||
|
-1, &black_tree[167], &black_tree[166],
|
||
|
25, NULL, NULL,
|
||
|
24, NULL, NULL,
|
||
|
-1, &black_tree[169], &black_tree[168],
|
||
|
-1, &black_tree[171], &black_tree[170],
|
||
|
-1, &black_tree[173], &black_tree[172],
|
||
|
-1, &black_tree[175], &black_tree[174],
|
||
|
-1, &black_tree[177], &black_tree[176],
|
||
|
-1, &black_tree[179], &black_tree[178],
|
||
|
-1, &black_tree[181], &black_tree[180],
|
||
|
1920, NULL, NULL,
|
||
|
1856, NULL, NULL,
|
||
|
-1, &black_tree[183], &black_tree[182],
|
||
|
-1, &black_tree[185], &black_tree[184],
|
||
|
-1, &black_tree[187], &black_tree[186],
|
||
|
1792, NULL, NULL,
|
||
|
43, NULL, NULL,
|
||
|
42, NULL, NULL,
|
||
|
39, NULL, NULL,
|
||
|
38, NULL, NULL,
|
||
|
37, NULL, NULL,
|
||
|
36, NULL, NULL,
|
||
|
35, NULL, NULL,
|
||
|
34, NULL, NULL,
|
||
|
29, NULL, NULL,
|
||
|
28, NULL, NULL,
|
||
|
27, NULL, NULL,
|
||
|
26, NULL, NULL,
|
||
|
192, NULL, NULL,
|
||
|
128, NULL, NULL,
|
||
|
41, NULL, NULL,
|
||
|
40, NULL, NULL,
|
||
|
33, NULL, NULL,
|
||
|
32, NULL, NULL,
|
||
|
31, NULL, NULL,
|
||
|
30, NULL, NULL,
|
||
|
63, NULL, NULL,
|
||
|
62, NULL, NULL,
|
||
|
49, NULL, NULL,
|
||
|
48, NULL, NULL,
|
||
|
256, NULL, NULL,
|
||
|
61, NULL, NULL,
|
||
|
58, NULL, NULL,
|
||
|
57, NULL, NULL,
|
||
|
47, NULL, NULL,
|
||
|
46, NULL, NULL,
|
||
|
45, NULL, NULL,
|
||
|
44, NULL, NULL,
|
||
|
51, NULL, NULL,
|
||
|
50, NULL, NULL,
|
||
|
-1, &black_tree[189], &black_tree[188],
|
||
|
-1, &black_tree[191], &black_tree[190],
|
||
|
-1, &black_tree[193], &black_tree[192],
|
||
|
54, NULL, NULL,
|
||
|
53, NULL, NULL,
|
||
|
-1, &black_tree[195], &black_tree[194],
|
||
|
448, NULL, NULL,
|
||
|
384, NULL, NULL,
|
||
|
320, NULL, NULL,
|
||
|
-1, &black_tree[197], &black_tree[196],
|
||
|
-1, &black_tree[199], &black_tree[198],
|
||
|
60, NULL, NULL,
|
||
|
59, NULL, NULL,
|
||
|
-1, &black_tree[201], &black_tree[200],
|
||
|
-1, &black_tree[203], &black_tree[202],
|
||
|
56, NULL, NULL,
|
||
|
55, NULL, NULL,
|
||
|
-1, &black_tree[205], &black_tree[204],
|
||
|
-1, &black_tree[207], &black_tree[206],
|
||
|
52, NULL, NULL,
|
||
|
2560, NULL, NULL,
|
||
|
2496, NULL, NULL,
|
||
|
2432, NULL, NULL,
|
||
|
2368, NULL, NULL,
|
||
|
2304, NULL, NULL,
|
||
|
2240, NULL, NULL,
|
||
|
2176, NULL, NULL,
|
||
|
2112, NULL, NULL,
|
||
|
2048, NULL, NULL,
|
||
|
1984, NULL, NULL,
|
||
|
1216, NULL, NULL,
|
||
|
1152, NULL, NULL,
|
||
|
1088, NULL, NULL,
|
||
|
1024, NULL, NULL,
|
||
|
960, NULL, NULL,
|
||
|
896, NULL, NULL,
|
||
|
576, NULL, NULL,
|
||
|
512, NULL, NULL,
|
||
|
1728, NULL, NULL,
|
||
|
1664, NULL, NULL,
|
||
|
1600, NULL, NULL,
|
||
|
1536, NULL, NULL,
|
||
|
1472, NULL, NULL,
|
||
|
1408, NULL, NULL,
|
||
|
1344, NULL, NULL,
|
||
|
1280, NULL, NULL,
|
||
|
832, NULL, NULL,
|
||
|
768, NULL, NULL,
|
||
|
704, NULL, NULL,
|
||
|
640, NULL, NULL,
|
||
|
}; /* end black_tree */
|
||
|
|
||
|
|
||
|
|
||
|
struct node white_tree[] =
|
||
|
{
|
||
|
-1, &white_tree[ 2], &white_tree[ 1],
|
||
|
-1, &white_tree[ 4], &white_tree[ 3],
|
||
|
-1, &white_tree[ 6], &white_tree[ 5],
|
||
|
-1, &white_tree[ 8], &white_tree[ 7],
|
||
|
-1, &white_tree[ 10], &white_tree[ 9],
|
||
|
-1, &white_tree[ 12], &white_tree[ 11],
|
||
|
-1, &white_tree[ 14], &white_tree[ 13],
|
||
|
-1, &white_tree[ 16], &white_tree[ 15],
|
||
|
-1, &white_tree[ 18], &white_tree[ 17],
|
||
|
-1, &white_tree[ 20], &white_tree[ 19],
|
||
|
-1, &white_tree[ 22], &white_tree[ 21],
|
||
|
-1, &white_tree[ 24], &white_tree[ 23],
|
||
|
-1, &white_tree[ 26], &white_tree[ 25],
|
||
|
-1, &white_tree[ 28], &white_tree[ 27],
|
||
|
-1, &white_tree[ 30], &white_tree[ 29],
|
||
|
7, NULL, NULL,
|
||
|
6, NULL, NULL,
|
||
|
-1, &white_tree[ 32], &white_tree[ 31],
|
||
|
5, NULL, NULL,
|
||
|
4, NULL, NULL,
|
||
|
-1, &white_tree[ 34], &white_tree[ 33],
|
||
|
-1, &white_tree[ 36], &white_tree[ 35],
|
||
|
3, NULL, NULL,
|
||
|
2, NULL, NULL,
|
||
|
-1, &white_tree[ 38], &white_tree[ 37],
|
||
|
-1, &white_tree[ 40], &white_tree[ 39],
|
||
|
-1, &white_tree[ 42], &white_tree[ 41],
|
||
|
-1, &white_tree[ 44], &white_tree[ 43],
|
||
|
-1, &white_tree[ 46], &white_tree[ 45],
|
||
|
-1, &white_tree[ 48], &white_tree[ 47],
|
||
|
-1, &white_tree[ 50], &white_tree[ 49],
|
||
|
64, NULL, NULL,
|
||
|
-1, &white_tree[ 52], &white_tree[ 51],
|
||
|
-1, &white_tree[ 54], &white_tree[ 53],
|
||
|
9, NULL, NULL,
|
||
|
8, NULL, NULL,
|
||
|
128, NULL, NULL,
|
||
|
-1, &white_tree[ 56], &white_tree[ 55],
|
||
|
-1, &white_tree[ 58], &white_tree[ 57],
|
||
|
-1, &white_tree[ 60], &white_tree[ 59],
|
||
|
-1, &white_tree[ 62], &white_tree[ 61],
|
||
|
-1, &white_tree[ 64], &white_tree[ 63],
|
||
|
11, NULL, NULL,
|
||
|
10, NULL, NULL,
|
||
|
-1, &white_tree[ 66], &white_tree[ 65],
|
||
|
-1, &white_tree[ 68], &white_tree[ 67],
|
||
|
-1, &white_tree[ 70], &white_tree[ 69],
|
||
|
-1, &white_tree[ 72], &white_tree[ 71],
|
||
|
-1, &white_tree[ 74], &white_tree[ 73],
|
||
|
-1, &white_tree[ 76], &white_tree[ 75],
|
||
|
-1, &white_tree[ 78], &white_tree[ 77],
|
||
|
15, NULL, NULL,
|
||
|
14, NULL, NULL,
|
||
|
17, NULL, NULL,
|
||
|
16, NULL, NULL,
|
||
|
-1, &white_tree[ 80], &white_tree[ 79],
|
||
|
-1, &white_tree[ 82], &white_tree[ 81],
|
||
|
-1, &white_tree[ 84], &white_tree[ 83],
|
||
|
1664, NULL, NULL,
|
||
|
192, NULL, NULL,
|
||
|
-1, &white_tree[ 86], &white_tree[ 85],
|
||
|
-1, &white_tree[ 88], &white_tree[ 87],
|
||
|
-1, &white_tree[ 90], &white_tree[ 89],
|
||
|
-1, &white_tree[ 92], &white_tree[ 91],
|
||
|
-1, &white_tree[ 94], &white_tree[ 93],
|
||
|
-1, &white_tree[ 96], &white_tree[ 95],
|
||
|
-1, &white_tree[ 98], &white_tree[ 97],
|
||
|
-1, &white_tree[100], &white_tree[ 99],
|
||
|
-1, &white_tree[102], &white_tree[101],
|
||
|
-1, &white_tree[104], &white_tree[103],
|
||
|
12, NULL, NULL,
|
||
|
1, NULL, NULL,
|
||
|
-1, &white_tree[106], &white_tree[105],
|
||
|
-1, &white_tree[108], &white_tree[107],
|
||
|
-1, &white_tree[110], &white_tree[109],
|
||
|
13, NULL, NULL,
|
||
|
-1, &white_tree[112], &white_tree[111],
|
||
|
-1, &white_tree[114], &white_tree[113],
|
||
|
-1, &white_tree[116], &white_tree[115],
|
||
|
256, NULL, NULL,
|
||
|
-1, &white_tree[118], &white_tree[117],
|
||
|
-1, &white_tree[120], &white_tree[119],
|
||
|
-1, &white_tree[122], &white_tree[121],
|
||
|
-1, &white_tree[124], &white_tree[123],
|
||
|
-1, &white_tree[126], &white_tree[125],
|
||
|
-1, &white_tree[128], &white_tree[127],
|
||
|
-1, &white_tree[130], &white_tree[129],
|
||
|
25, NULL, NULL,
|
||
|
-1, &white_tree[132], &white_tree[131],
|
||
|
-1, &white_tree[134], &white_tree[133],
|
||
|
24, NULL, NULL,
|
||
|
18, NULL, NULL,
|
||
|
-1, &white_tree[136], &white_tree[135],
|
||
|
-1, &white_tree[138], &white_tree[137],
|
||
|
27, NULL, NULL,
|
||
|
-1, &white_tree[140], &white_tree[139],
|
||
|
-1, &white_tree[142], &white_tree[141],
|
||
|
-1, &white_tree[144], &white_tree[143],
|
||
|
28, NULL, NULL,
|
||
|
21, NULL, NULL,
|
||
|
-1, &white_tree[146], &white_tree[145],
|
||
|
-1, &white_tree[148], &white_tree[147],
|
||
|
-1, &white_tree[150], &white_tree[149],
|
||
|
26, NULL, NULL,
|
||
|
-1, &white_tree[152], &white_tree[151],
|
||
|
-1, &white_tree[154], &white_tree[153],
|
||
|
19, NULL, NULL,
|
||
|
-1, &white_tree[156], &white_tree[155],
|
||
|
-1, &white_tree[158], &white_tree[157],
|
||
|
-1, &white_tree[160], &white_tree[159],
|
||
|
20, NULL, NULL,
|
||
|
-1, &white_tree[162], &white_tree[161],
|
||
|
23, NULL, NULL,
|
||
|
22, NULL, NULL,
|
||
|
-1, &white_tree[164], &white_tree[163],
|
||
|
-1, &white_tree[166], &white_tree[165],
|
||
|
-1, NULL, &white_tree[167],
|
||
|
-1, &white_tree[169], &white_tree[168],
|
||
|
-1, &white_tree[171], &white_tree[170],
|
||
|
-1, &white_tree[173], &white_tree[172],
|
||
|
-1, &white_tree[175], &white_tree[174],
|
||
|
-1, &white_tree[177], &white_tree[176],
|
||
|
576, NULL, NULL,
|
||
|
640, NULL, NULL,
|
||
|
-1, &white_tree[179], &white_tree[178],
|
||
|
512, NULL, NULL,
|
||
|
448, NULL, NULL,
|
||
|
58, NULL, NULL,
|
||
|
57, NULL, NULL,
|
||
|
56, NULL, NULL,
|
||
|
55, NULL, NULL,
|
||
|
52, NULL, NULL,
|
||
|
51, NULL, NULL,
|
||
|
50, NULL, NULL,
|
||
|
49, NULL, NULL,
|
||
|
-1, &white_tree[181], &white_tree[180],
|
||
|
-1, &white_tree[183], &white_tree[182],
|
||
|
60, NULL, NULL,
|
||
|
59, NULL, NULL,
|
||
|
384, NULL, NULL,
|
||
|
320, NULL, NULL,
|
||
|
0, NULL, NULL,
|
||
|
63, NULL, NULL,
|
||
|
62, NULL, NULL,
|
||
|
61, NULL, NULL,
|
||
|
44, NULL, NULL,
|
||
|
43, NULL, NULL,
|
||
|
42, NULL, NULL,
|
||
|
41, NULL, NULL,
|
||
|
40, NULL, NULL,
|
||
|
39, NULL, NULL,
|
||
|
54, NULL, NULL,
|
||
|
53, NULL, NULL,
|
||
|
32, NULL, NULL,
|
||
|
31, NULL, NULL,
|
||
|
38, NULL, NULL,
|
||
|
37, NULL, NULL,
|
||
|
36, NULL, NULL,
|
||
|
35, NULL, NULL,
|
||
|
34, NULL, NULL,
|
||
|
33, NULL, NULL,
|
||
|
48, NULL, NULL,
|
||
|
47, NULL, NULL,
|
||
|
46, NULL, NULL,
|
||
|
45, NULL, NULL,
|
||
|
30, NULL, NULL,
|
||
|
29, NULL, NULL,
|
||
|
-1, &white_tree[185], &white_tree[184],
|
||
|
1408, NULL, NULL,
|
||
|
1344, NULL, NULL,
|
||
|
1280, NULL, NULL,
|
||
|
1216, NULL, NULL,
|
||
|
1152, NULL, NULL,
|
||
|
1088, NULL, NULL,
|
||
|
1024, NULL, NULL,
|
||
|
960, NULL, NULL,
|
||
|
896, NULL, NULL,
|
||
|
832, NULL, NULL,
|
||
|
768, NULL, NULL,
|
||
|
704, NULL, NULL,
|
||
|
1728, NULL, NULL,
|
||
|
1600, NULL, NULL,
|
||
|
1536, NULL, NULL,
|
||
|
1472, NULL, NULL,
|
||
|
-1, &white_tree[187], &white_tree[186],
|
||
|
-1, &white_tree[189], &white_tree[188],
|
||
|
-1, &white_tree[191], &white_tree[190],
|
||
|
-1, &white_tree[193], &white_tree[192],
|
||
|
-1, &white_tree[195], &white_tree[194],
|
||
|
-1, &white_tree[197], &white_tree[196],
|
||
|
-1, &white_tree[199], &white_tree[198],
|
||
|
-1, &white_tree[201], &white_tree[200],
|
||
|
1920, NULL, NULL,
|
||
|
1856, NULL, NULL,
|
||
|
-1, &white_tree[203], &white_tree[202],
|
||
|
-1, &white_tree[205], &white_tree[204],
|
||
|
-1, &white_tree[207], &white_tree[206],
|
||
|
1792, NULL, NULL,
|
||
|
2560, NULL, NULL,
|
||
|
2496, NULL, NULL,
|
||
|
2432, NULL, NULL,
|
||
|
2368, NULL, NULL,
|
||
|
2304, NULL, NULL,
|
||
|
2240, NULL, NULL,
|
||
|
2176, NULL, NULL,
|
||
|
2112, NULL, NULL,
|
||
|
2048, NULL, NULL,
|
||
|
1984, NULL, NULL,
|
||
|
}; /* end white_tree */
|
||
|
|
||
|
|
||
|
/************************* find_run_length_code ******************************
|
||
|
|
||
|
finds the length of the run in the compressed image
|
||
|
by traversing the above declared tree of run length codes.
|
||
|
|
||
|
******************************************************************************/
|
||
|
SHORT find_run_length_code(SHORT unsigned color)
|
||
|
{
|
||
|
if(color == White)
|
||
|
node_ptr = white_tree; /* point to root node */
|
||
|
else
|
||
|
node_ptr = black_tree; /* point to root node */
|
||
|
|
||
|
while(node_ptr->value == Invalid) { /* -1 */
|
||
|
if((read_bit()) == 0)
|
||
|
node_ptr = node_ptr->child_zero;
|
||
|
else
|
||
|
node_ptr = node_ptr->child_one;
|
||
|
} /* end while node does not contain a run length value */
|
||
|
|
||
|
/*
|
||
|
* When this line is reached, node_ptr points to a node that contains
|
||
|
* the run length code: return that value.
|
||
|
*/
|
||
|
|
||
|
return(node_ptr->value);
|
||
|
|
||
|
} /* end find_run_length_code */
|