增加针对G4 压缩的相关操作类

This commit is contained in:
lovelyyoung 2020-06-20 10:57:34 +08:00
parent 4079d5cb0d
commit 9d99bc37d0
10 changed files with 4543 additions and 0 deletions

102
huagao/G4Tiff.cpp Normal file
View File

@ -0,0 +1,102 @@
#include "stdafx.h"
#include "G4Tiff.h"
#include <io.h>
G4Tiff::G4Tiff(cv::Mat & mat, int threshold)
{
m_tmppath = cv::tempfile(".tif");
if (mat.channels() != 1)
throw std::runtime_error("mat channel error");
TIFF* pTiffHandle = TIFFOpen(m_tmppath.c_str(), "w");
if (!pTiffHandle)
{
printf("can't open TIFF descriptor\n");
}
int width = mat.cols;
int height = mat.rows;
try
{
except(TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width), "width");
except(TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height), "length");
except(TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, 1), "bits per sample");
except(TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, 1), "samples per pixel");
except(TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, 1), "rows per strip");
except(TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4), "compression");
except(TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE), "photometric");
except(TIFFSetField(pTiffHandle, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB), "photometric");
except(TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG), "planar config");
// not necessary
except(TIFFSetField(pTiffHandle, TIFFTAG_XRESOLUTION, 200.0), "res x");
except(TIFFSetField(pTiffHandle, TIFFTAG_YRESOLUTION, 200.0), "res y");
except(TIFFSetField(pTiffHandle, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH), "res unit");
std::vector<uchar> _buffer(width / 8 + 8, 0);
uchar* buffer = &_buffer[0];
int bytes = int(width / 8.0 + 0.5);
for (int y = 0; y < height; ++y)
{
uint8_t* src_row = mat.ptr(y);
for (int x = 0; x < width; ++x, ++src_row)
{
uint8_t eight_pixels = buffer[x / 8];
eight_pixels = eight_pixels << 1;
if (*src_row < threshold)
eight_pixels = eight_pixels | 1; //
buffer[x / 8] = eight_pixels;
}
except(TIFFWriteScanline(pTiffHandle, buffer, y, bytes) != -1, "write scanline");
}
}
catch (const std::runtime_error& e)
{
printf("TIFF writing: %s\n", e.what());
TIFFClose(pTiffHandle);
}
TIFFClose(pTiffHandle);
}
G4Tiff::~G4Tiff()
{
if (_access(m_tmppath.c_str(), 0) == 0)
{
if (!std::remove(m_tmppath.c_str())) {}//ɾ³ý³É¹¦
else
throw std::runtime_error("File is not exist");
}
}
void G4Tiff::GetCompressedData(std::vector<uchar>& cmpeddata)
{
if (m_tmppath.empty())
throw std::runtime_error("file is not exist");
FILE* file = fopen(m_tmppath.c_str(), "rb");
if (file)
{
int filesize = _lseek(_fileno(file), 0, SEEK_END); // seek to EOF
fseek(file, 0, SEEK_SET);
if (filesize)
{
cmpeddata.resize(filesize);
fread(cmpeddata.data(), 1, filesize, file);
}
FILE* file1 = fopen("d:\\1.tiff", "wb");
fwrite(cmpeddata.data(), filesize, 1, file1);
fclose(file1);
}
fclose(file);
//TIFF* pTiffHandle = TIFFOpen(m_tmppath.c_str(), "w");
//TIFFGetField()
//TIFFClose(pTiffHandle);
}
void G4Tiff::except(bool condition, const std::string & message)
{
if (!condition)
throw std::runtime_error("Error " + message);
}

17
huagao/G4Tiff.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <opencv2/opencv.hpp>
#include <tiff.h>
#include <tiffio.h>
class G4Tiff
{
public:
G4Tiff(cv::Mat& mat,int threshold=120);
~G4Tiff();
public:
void GetCompressedData(std::vector<uchar>& cmpeddata);
private:
void except(bool condition, const std::string& message = "");
std::string m_tmppath;
};

View File

@ -0,0 +1,516 @@
#include "TiffG4Compression.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#ifdef TIME
struct timeval t1, t2;
struct timezone tz;
#endif
TiffG4Compression::TiffG4Compression()
{
}
TiffG4Compression::~TiffG4Compression()
{
}
int TiffG4Compression::G4Compress(unsigned char * indata, int inbytes, int width, int height, unsigned char * outdata, int * outbytes)
{
struct uncompressed_descriptor uncompressed;
struct compressed_descriptor compressed;
uncompressed.pixels_per_line = width;
uncompressed.number_of_lines = height;
uncompressed.data = indata;
comp_alloc_flag = NOALLOC;
comp_write_init_flag = 1;
read_uncompressed_file_into_memory(&uncompressed);
compressed.data = outdata;
control_compression(&uncompressed, &compressed);
*outbytes = compressed.length_in_bytes;
return *outbytes;
}
void TiffG4Compression::control_compression(uncompressed_descriptor * uncompressed, compressed_descriptor * compressed)
{
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_compress(uncompressed, compressed, params);
compress_image(uncompressed, compressed, params);
/* memory deallocation added by Michael D. Garris 2/26/90 */
free(params->reference_line);
free(params->coding_line);
#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
}
void TiffG4Compression::read_uncompressed_file_into_memory(uncompressed_descriptor * uncompressed)
{
int file_size;
if (comp_alloc_flag)
{
file_size = uncompressed->pixels_per_line * uncompressed->number_of_lines
/ Pixels_per_byte;
if ((uncompressed->data = (unsigned char *)calloc(file_size, sizeof(char))) == NULL)
{
printf("\nCannot allocate enough memory for uncomp file.\n");
}
}
else if (uncompressed->data == NULL)
{
printf("\nNo memory allocated for input data!\n");
}
}
void TiffG4Compression::prepare_to_compress(uncompressed_descriptor * uncompressed, compressed_descriptor * compressed, parameters * params)
{
params->max_pixel = uncompressed->pixels_per_line;
compressed->pixels_per_line = uncompressed->pixels_per_line;
compressed->number_of_lines = uncompressed->number_of_lines;
set_up_first_line_c(params);
prepare_to_write_bits_c(compressed);
}
void TiffG4Compression::compress_image(uncompressed_descriptor * uncompressed, compressed_descriptor * compressed, parameters * params)
{
SHORT line;
for (line = 0; line < uncompressed->number_of_lines; line++)
{
make_array_of_changing_elements(params, uncompressed, line);
set_up_first_and_last_changing_elements_c(params);
compress_line(params);
prepare_to_compress_next_line(params);
} /* end for each line loop */
write_bits_c(const_cast<char*>("000000000001000000000001"));
compressed->length_in_bytes = flush_buffer();
}
void TiffG4Compression::make_array_of_changing_elements(parameters * params, uncompressed_descriptor * uncompressed, SHORT line_number)
{
SHORT bytes_per_line;
int line_offset;
SHORT byte_offset;
bytes_per_line = params->max_pixel / Pixels_per_byte;
line_offset = bytes_per_line * line_number;
for (byte_offset = 0; byte_offset < bytes_per_line; byte_offset++)
{
process_char(*(uncompressed->data + line_offset + byte_offset), params);
}
}
void TiffG4Compression::set_up_first_and_last_changing_elements_c(parameters * params)
{
*(params->coding_line) = Invalid;
*(params->coding_line + ++params->index) = params->max_pixel;
*(params->coding_line + ++params->index) = params->max_pixel;
*(params->coding_line + ++params->index) = params->max_pixel;
}
void TiffG4Compression::prepare_to_compress_next_line(parameters * params)
{
SHORT *temp;
/* swap the reference and unchanged coding lines */
temp = params->reference_line;
params->reference_line = params->coding_line;
params->coding_line = temp;
params->pixel = 0;
params->index = 0;
params->previous_color = White;
}
void TiffG4Compression::set_up_first_line_c(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->pixel = 0;
params->index = 0;
params->previous_color = White;
}
void TiffG4Compression::compress_line(parameters * params)
{
#if Debug
static SHORT line = 0;
printf("\nLINE %d. ", line);
line++;
#endif
A_0 = Invalid; /* set A0 equal to imaginary first array element */
A0_color = White;
A_1 = 1;
initialize_b1(params);
b2 = b1 + 1;
#if Debug
printf("\nA0:%d A1:%d b1:%d b2:%d ",
A0, *(params->coding_line + A1),
*(params->reference_line + b1), *(params->reference_line + b2));
#endif
do {
if (*(params->reference_line + b2) < *(params->coding_line + A_1))
{
pass_mode_c(params);
continue;
}
else
if (abs(*(params->coding_line + A_1) - *(params->reference_line + b1)) <= 3)
vertical_mode_c(params);
else
horizontal_mode_c(params);
#if Debug
printf("\nA0:%d A1:%d b1:%d b2:%d ", A0, *(params->coding_line + A1),
*(params->reference_line + b1), *(params->reference_line + b2));
#endif
} while (A_0 < params->max_pixel);
}
void TiffG4Compression::initialize_b1(parameters * params)
{
SHORT last_bit_of_b1;
b1 = 1;
last_bit_of_b1 = b1 & Last_bit_mask;
while (((*(params->reference_line + b1) <= A_0) || (A0_color == last_bit_of_b1))
&& (*(params->reference_line + b1) < params->max_pixel))
{
b1++;
last_bit_of_b1 = b1 & Last_bit_mask;
} /* end while loop */
#if Debug
printf("\nb1:%d :%d, A0:%d", b1, *(params->reference_line + b1), A0);
#endif
}
void TiffG4Compression::pass_mode_c(parameters * params)
{
write_bits_c(const_cast<char*>("0001"));
#if Debug
printf(" P ");
#endif
/*
* Reset the value A0 points to to a'0 (the value that b2 points to).
*/
A_0 = *(params->reference_line + b2);
/*
* Since A0 is now greater than the pixel b1 points to, both b1 and b2
* must be advanced twice to maintain the color difference between A0 and
* b1, and the positional requirement that b1 point to a pixel greater than
* the one A0 points to.
*/
b1 += 2;
b2 += 2;
/*
* Note that the b's can be advanced by two positions without fear of
* moving them beyond the last changing element because pass_mode cannot
* occur if b2 is already pointing to max_pixel.
*/
}
void TiffG4Compression::vertical_mode_c(parameters * params)
{
SHORT difference;
difference = *(params->coding_line + A_1) - *(params->reference_line + b1);
A_0 = *(params->coding_line + A_1);
A0_color = !A0_color;
A_1++;
#if Debug
printf(" V%d ", difference);
#endif
switch (difference) {
case 0:
write_bits_c(const_cast<char*>("1"));
if (*(params->reference_line + b1) != params->max_pixel)
{
b1++;
b2++;
} /* end if b1 is not on the last changing element */
break;
case 1:
write_bits_c(const_cast<char*>("011"));
b1++;
b2++;
if ((*(params->reference_line + b1) <= A_0) &&
(*(params->reference_line + b1) != params->max_pixel))
{
b1 += 2;
b2 += 2;
}
break;
case -1:
write_bits_c(const_cast<char*>("010"));
if (*(params->reference_line + b1) != params->max_pixel)
{
b1++;
b2++;
} /* end if b1 is not on the last changing element */
break;
case 2:
write_bits_c(const_cast<char*>("000011"));
b1++;
b2++;
if ((*(params->reference_line + b1) <= A_0) &&
(*(params->reference_line + b1) != params->max_pixel))
{
b1 += 2;
b2 += 2;
}
break;
case -2:
write_bits_c(const_cast<char*>("000010"));
if (*(params->reference_line + b1 - 1) > A_0)
{
b1--;
b2--;
}
else if (*(params->reference_line + b1) != params->max_pixel)
{
b1++;
b2++;
}
break;
case 3:
write_bits_c(const_cast<char*>("0000011"));
b1++;
b2++;
while ((*(params->reference_line + b1) <= A_0) &&
(*(params->reference_line + b1) != params->max_pixel))
{
b1 += 2;
b2 += 2;
}
break;
case -3:
write_bits_c(const_cast<char*>("0000010"));
if (*(params->reference_line + b1 - 1) > A_0)
{
b1--;
b2--;
}
else if (*(params->reference_line + b1) != params->max_pixel)
{
b1++;
b2++;
}
break;
default:
printf("ERROR in vertical_mode_c() ");
} /* end case of difference */
}
void TiffG4Compression::horizontal_mode_c(parameters * params)
{
SHORT run_length;
#if Debug
printf(" a2:%d H ", *(params->coding_line + a2));
#endif
a2 = A_1 + 1;
write_bits_c(const_cast<char*>("001"));
if (A_0 == Invalid) /* on imaginary first pixel */
run_length = *(params->coding_line + A_1);
else
run_length = *(params->coding_line + A_1) - A_0;
write_run_length(run_length, A0_color);
/* the last bit contains the color of the changing element */
run_length = *(params->coding_line + a2) - *(params->coding_line + A_1);
write_run_length(run_length, !A0_color);
/*
* Must use !A0_color instead of A1 because in cases in which A1 occurs
* on max_pixel, its color is bogus.
*/
/* NOTE: is the above statement true? if A1 were on max_pixel, you should
not get horizontal mode. */
A_0 = *(params->coding_line + a2);
A_1 = a2 + 1;
while ((*(params->reference_line + b1) <= *(params->coding_line + a2)) &&
(*(params->reference_line + b1) < params->max_pixel))
{
b1 += 2; /* must move ahead by 2 to maintain color difference with */
b2 += 2; /* A0, whose color does not change in this mode. */
}
}
void TiffG4Compression::prepare_to_write_bits_c(compressed_descriptor * compressed)
{
if (comp_alloc_flag) {
compressed->data = (unsigned char*)calloc((compressed->pixels_per_line *
compressed->number_of_lines / Pixels_per_byte), sizeof(unsigned char));
}
/*
* This allocation is usually very wasteful, but because there is no
* way of knowing how much space is needed, I decided to be generous.
*/
if (compressed->data == NULL) {
printf("\nMemory allocation error for compressed output data.\n");
//crash_c();
}
output_area = (char*)compressed->data;
}
void TiffG4Compression::write_bits_c(char * string_ptr)
{
/* global switch added by Michael D. Garris 2/26/90 */
if (comp_write_init_flag)
{
bit_place_mark = 0;
byte_place_mark = 0;
comp_write_init_flag = 0;
}
while (*string_ptr != '\0')
{
if (*string_ptr == '1')
*(output_area + byte_place_mark) |= write_one[bit_place_mark];
else
*(output_area + byte_place_mark) &= write_zero[bit_place_mark];
if (bit_place_mark == Last_bit_in_a_byte)
{
bit_place_mark = 0;
byte_place_mark++;
} /* end if byte is full */
else
bit_place_mark++;
string_ptr++;
} /* end while */
}
unsigned int TiffG4Compression::flush_buffer()
{
SHORT i;
if (bit_place_mark != 0) {
for (i = bit_place_mark; i < Pixels_per_byte; i++)
*(output_area + byte_place_mark) &= write_zero[i];
/*
* pad the rest of the last byte with '0' bits.
*/
++byte_place_mark;
}
return byte_place_mark;
}
void TiffG4Compression::write_run_length(SHORT length, SHORT color)
{
SHORT multiples_of_largest_code, i,
make_up_code_index, remainder;
multiples_of_largest_code = length / Largest_code;
length %= Largest_code;
for (i = 0; i < multiples_of_largest_code; i++)
write_bits_c(const_cast<char*>(largest_colorless_code));
remainder = length % Size_of_make_up_code_increments;
/* remainder in the range 0 - 63 */
make_up_code_index = length / Size_of_make_up_code_increments;
/*
* make_up_code_index in the range 0 - 39, and represents a run length
* of 64 times its value (i.e. 0 - 2496). To translate this value into
* an index into the arrays that store the bit sequence that represents
* the appropriate run length, 1 must be subtracted from make_up_code_
* index. If this results in the value -1, no make up code should be
* written.
*/
make_up_code_index--;
if (make_up_code_index != Invalid) {
if (color == White)
write_bits_c(const_cast<char*>(white_make_up_code[make_up_code_index]));
else
write_bits_c(const_cast<char*>(black_make_up_code[make_up_code_index]));
}
if (color == White)
write_bits_c(const_cast<char*>(white_terminating_code[remainder]));
else
write_bits_c(const_cast<char*>(black_terminating_code[remainder]));
}
void TiffG4Compression::process_char(unsigned char data_byte, parameters * params)
{
static char color = 0;
SHORT i = 0;
color = -(data_byte & Last_bit_mask);
data_byte ^= params->previous_color;
/* if the previous color is black - which is contrary to our assumptions -
* the bits in the byte must all be changed so that the result, when used
* as an index into the array 'bytes,' yields the correct result. In the
* above operation, if the previous color is black (11111111b), all bits
* are changed; if the previous color is white (00000000b), no bits are
* changed. */
while (table[data_byte].pixel[i] != Invalid)
*(params->coding_line + ++params->index) =
params->pixel + table[data_byte].pixel[i++];
params->pixel += Pixels_per_byte;
params->previous_color = color;
/* 'color' is a temporary holding place for the value of previous color */
}

668
huagao/TiffG4Compression.h Normal file
View File

@ -0,0 +1,668 @@
#pragma once
#define White 0
#define Black 1
#define Black_byte 255 // byte of all black bits: 11111111b
/* WARNING */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/* !!!!!!!!!!!!!!!!!! Change Here. Redeclaration of Type. !!!!!!!!!!!!!!!! */
#define SHORT int /* this type was just a regular old C "short". */
/* In images with > 2^15 rows the 2 byte definition */
/* gave garbage output because short overflowed. */
/* Increasing all variables from 2 to 4 bytes seems */
/* to fix it. I have used the macro SHORT here to show */
/* where this change applies, so that it can be undone */
/* if desired. Some variables of type "int" existed in */
/* the code before this change, and the SHORT macro */
/* allows reversal of just the correct ones. */
/* Patrick Grother Dec 9 1994 */
/* !!!!!!!!!!!!!!!!!! Change Here. Redeclaration of Type. !!!!!!!!!!!!!!!! */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
#define Largest_code 2560
#define Size_of_make_up_code_increments 64
#define Max_terminating_length 63 /* longest terminating code*/
#define Number_of_different_bytes 256
#define Pixels_per_byte 8
#define Bits_per_byte 8
#define Last_bit_in_a_byte 7 /* assumes bits numbered from 0 - 7 */
#define Last_bit_mask 1 /* masks the last (low magnitude) bit */
#define Default_width_in_pixels 2560 /* default width of a scan line */
#define Default_number_of_lines 3300 /* default length of an image */
#define Invalid -1
#define Extra_positions 25 /* ensures extra room in allocations */
#define Not_done_yet 0
#define VL3 -3 /* Vertical Left 3 mode */
#define VL2 -2 /* Vertical Left 2 mode */
#define VL1 -1 /* Vertical Left 1 mode */
#define V0 0 /* Vertical mode */
#define VR1 1 /* Vertical Right 1 mode */
#define VR2 2 /* Vertical Right 2 mode */
#define VR3 3 /* Vertical Right 3 mode */
#define P 4 /* Pass mode */
#define H 5 /* Horizontal mode */
#define EOFB 6 /* End Of File Buffer */
#define No_offset 0 /* no offset during fseek() */
#define End_of_file 2 /* start at EOF during fseek() */
#define Start_of_file 0 /* start at SOF during fseek() */
/*
unsigned char *calloc();
SHORT *malloc();
*/
struct parameters {
SHORT previous_color; /* color of last run of pixels */
SHORT index; /* indicates current position in "coding_line" */
SHORT max_pixel; /* the number of pixels in a scan line */
SHORT pixel; /* pixel number of the last changing element */
SHORT *reference_line; /* array of changing elements on reference line */
SHORT *coding_line; /* array of changing elements on coding line */
};
struct compressed_descriptor {
unsigned char *data; /* pointer to compressed image */
SHORT pixels_per_line; /* the number of pixels in a scan line */
SHORT number_of_lines; /* the number of scan lines in the image */
int length_in_bytes; /* length of the compressed image in bytes */
};
struct uncompressed_descriptor {
unsigned char *data; /* pointer to uncompressed image */
SHORT pixels_per_line; /* the number of pixels in a scan line */
SHORT number_of_lines; /* the number of scan lines in the image */
};
static const char write_one[Pixels_per_byte] =
{
(char)0x80,
(char)0x40,
(char)0x20,
(char)0x10,
(char)0x8,
(char)0x4,
(char)0x2,
(char)0x1,
};
static const char write_zero[Pixels_per_byte] =
{
(char)0x7F,
(char)0xBF,
(char)0xDF,
(char)0xEF,
(char)0xF7,
(char)0xFB,
(char)0xFD,
(char)0xFE,
};
static const char *white_terminating_code[64] =
{
"00110101",
"000111",
"0111",
"1000",
"1011",
"1100",
"1110",
"1111",
"10011",
"10100",
"00111",
"01000",
"001000",
"000011",
"110100",
"110101",
"101010",
"101011",
"0100111",
"0001100",
"0001000",
"0010111",
"0000011",
"0000100",
"0101000",
"0101011",
"0010011",
"0100100",
"0011000",
"00000010",
"00000011",
"00011010",
"00011011",
"00010010",
"00010011",
"00010100",
"00010101",
"00010110",
"00010111",
"00101000",
"00101001",
"00101010",
"00101011",
"00101100",
"00101101",
"00000100",
"00000101",
"00001010",
"00001011",
"01010010",
"01010011",
"01010100",
"01010101",
"00100100",
"00100101",
"01011000",
"01011001",
"01011010",
"01011011",
"01001010",
"01001011",
"00110010",
"00110011",
"00110100",
};/* end array of white terminating code */
static const char *black_terminating_code[64] =
{
"0000110111",
"010",
"11",
"10",
"011",
"0011",
"0010",
"00011",
"000101",
"000100",
"0000100",
"0000101",
"0000111",
"00000100",
"00000111",
"000011000",
"0000010111",
"0000011000",
"0000001000",
"00001100111",
"00001101000",
"00001101100",
"00000110111",
"00000101000",
"00000010111",
"00000011000",
"000011001010",
"000011001011",
"000011001100",
"000011001101",
"000001101000",
"000001101001",
"000001101010",
"000001101011",
"000011010010",
"000011010011",
"000011010100",
"000011010101",
"000011010110",
"000011010111",
"000001101100",
"000001101101",
"000011011010",
"000011011011",
"000001010100",
"000001010101",
"000001010110",
"000001010111",
"000001100100",
"000001100101",
"000001010010",
"000001010011",
"000000100100",
"000000110111",
"000000111000",
"000000100111",
"000000101000",
"000001011000",
"000001011001",
"000000101011",
"000000101100",
"000001011010",
"000001100110",
"000001100111",
}; /* end black_terminating_array */
static const char *white_make_up_code[40] =
{
"11011",
"10010",
"010111",
"0110111",
"00110110",
"00110111",
"01100100",
"01100101",
"01101000",
"01100111",
"011001100",
"011001101",
"011010010",
"011010011",
"011010100",
"011010101",
"011010110",
"011010111",
"011011000",
"011011001",
"011011010",
"011011011",
"010011000",
"010011001",
"010011010",
"011000",
"010011011",
/*
* from this line on, the codes are colorless and represnt runs from
* 1792 pixels to 2560 pixels. In other words, the longest run length
* codes have been added onto both the white make up codes and the black
* make up codes. This has been done to make the procedure
* "write_run_length()" easier to write and to understand. No other
* procedure in the compression algorithm is affected by this merging of
* different types of run length codes, and the compatibility of the
* program is in no way effected.
*/
"00000001000",
"00000001100",
"00000001101",
"000000010010",
"000000010011",
"000000010100",
"000000010101",
"000000010110",
"000000010111",
"000000011100",
"000000011101",
"000000011110",
"000000011111",
}; /* end case of white makeup code */
static const char *black_make_up_code[40] =
{
"0000001111",
"000011001000",
"000011001001",
"000001011011",
"000000110011",
"000000110100",
"000000110101",
"0000001101100",
"0000001101101",
"0000001001010",
"0000001001011",
"0000001001100",
"0000001001101",
"0000001110010",
"0000001110011",
"0000001110100",
"0000001110101",
"0000001110110",
"0000001110111",
"0000001010010",
"0000001010011",
"0000001010100",
"0000001010101",
"0000001011010",
"0000001011011",
"0000001100100",
"0000001100101",
/*
* from this line on, the codes are colorless and represnt runs from
* 1792 pixels to 2560 pixels. In other words, the longest run length
* codes have been added onto both the white make up codes and the black
* make up codes. This has been done to make the procedure
* "write_run_length()" easier to write and to understand. No other
* procedure in the compression algorithm is affected by this merging of
* different types of run length codes, and the compatibility of the
* program is in no way compromised.
*/
"00000001000",
"00000001100",
"00000001101",
"000000010010",
"000000010011",
"000000010100",
"000000010101",
"000000010110",
"000000010111",
"000000011100",
"000000011101",
"000000011110",
"000000011111",
}; /* end black makeup code */
struct byte_descriptor {
SHORT pixel[9];
};
static const struct byte_descriptor table[Number_of_different_bytes] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1,
7, -1, -1, -1, -1, -1, -1, -1, -1,
6, 7, -1, -1, -1, -1, -1, -1, -1,
6, -1, -1, -1, -1, -1, -1, -1, -1,
5, 6, -1, -1, -1, -1, -1, -1, -1,
5, 6, 7, -1, -1, -1, -1, -1, -1,
5, 7, -1, -1, -1, -1, -1, -1, -1,
5, -1, -1, -1, -1, -1, -1, -1, -1,
4, 5, -1, -1, -1, -1, -1, -1, -1,
4, 5, 7, -1, -1, -1, -1, -1, -1,
4, 5, 6, 7, -1, -1, -1, -1, -1,
4, 5, 6, -1, -1, -1, -1, -1, -1,
4, 6, -1, -1, -1, -1, -1, -1, -1,
4, 6, 7, -1, -1, -1, -1, -1, -1,
4, 7, -1, -1, -1, -1, -1, -1, -1,
4, -1, -1, -1, -1, -1, -1, -1, -1,
3, 4, -1, -1, -1, -1, -1, -1, -1,
3, 4, 7, -1, -1, -1, -1, -1, -1,
3, 4, 6, 7, -1, -1, -1, -1, -1,
3, 4, 6, -1, -1, -1, -1, -1, -1,
3, 4, 5, 6, -1, -1, -1, -1, -1,
3, 4, 5, 6, 7, -1, -1, -1, -1,
3, 4, 5, 7, -1, -1, -1, -1, -1,
3, 4, 5, -1, -1, -1, -1, -1, -1,
3, 5, -1, -1, -1, -1, -1, -1, -1,
3, 5, 7, -1, -1, -1, -1, -1, -1,
3, 5, 6, 7, -1, -1, -1, -1, -1,
3, 5, 6, -1, -1, -1, -1, -1, -1,
3, 6, -1, -1, -1, -1, -1, -1, -1,
3, 6, 7, -1, -1, -1, -1, -1, -1,
3, 7, -1, -1, -1, -1, -1, -1, -1,
3, -1, -1, -1, -1, -1, -1, -1, -1,
2, 3, -1, -1, -1, -1, -1, -1, -1,
2, 3, 7, -1, -1, -1, -1, -1, -1,
2, 3, 6, 7, -1, -1, -1, -1, -1,
2, 3, 6, -1, -1, -1, -1, -1, -1,
2, 3, 5, 6, -1, -1, -1, -1, -1,
2, 3, 5, 6, 7, -1, -1, -1, -1,
2, 3, 5, 7, -1, -1, -1, -1, -1,
2, 3, 5, -1, -1, -1, -1, -1, -1,
2, 3, 4, 5, -1, -1, -1, -1, -1,
2, 3, 4, 5, 7, -1, -1, -1, -1,
2, 3, 4, 5, 6, 7, -1, -1, -1,
2, 3, 4, 5, 6, -1, -1, -1, -1,
2, 3, 4, 6, -1, -1, -1, -1, -1,
2, 3, 4, 6, 7, -1, -1, -1, -1,
2, 3, 4, 7, -1, -1, -1, -1, -1,
2, 3, 4, -1, -1, -1, -1, -1, -1,
2, 4, -1, -1, -1, -1, -1, -1, -1,
2, 4, 7, -1, -1, -1, -1, -1, -1,
2, 4, 6, 7, -1, -1, -1, -1, -1,
2, 4, 6, -1, -1, -1, -1, -1, -1,
2, 4, 5, 6, -1, -1, -1, -1, -1,
2, 4, 5, 6, 7, -1, -1, -1, -1,
2, 4, 5, 7, -1, -1, -1, -1, -1,
2, 4, 5, -1, -1, -1, -1, -1, -1,
2, 5, -1, -1, -1, -1, -1, -1, -1,
2, 5, 7, -1, -1, -1, -1, -1, -1,
2, 5, 6, 7, -1, -1, -1, -1, -1,
2, 5, 6, -1, -1, -1, -1, -1, -1,
2, 6, -1, -1, -1, -1, -1, -1, -1,
2, 6, 7, -1, -1, -1, -1, -1, -1,
2, 7, -1, -1, -1, -1, -1, -1, -1,
2, -1, -1, -1, -1, -1, -1, -1, -1,
1, 2, -1, -1, -1, -1, -1, -1, -1,
1, 2, 7, -1, -1, -1, -1, -1, -1,
1, 2, 6, 7, -1, -1, -1, -1, -1,
1, 2, 6, -1, -1, -1, -1, -1, -1,
1, 2, 5, 6, -1, -1, -1, -1, -1,
1, 2, 5, 6, 7, -1, -1, -1, -1,
1, 2, 5, 7, -1, -1, -1, -1, -1,
1, 2, 5, -1, -1, -1, -1, -1, -1,
1, 2, 4, 5, -1, -1, -1, -1, -1,
1, 2, 4, 5, 7, -1, -1, -1, -1,
1, 2, 4, 5, 6, 7, -1, -1, -1,
1, 2, 4, 5, 6, -1, -1, -1, -1,
1, 2, 4, 6, -1, -1, -1, -1, -1,
1, 2, 4, 6, 7, -1, -1, -1, -1,
1, 2, 4, 7, -1, -1, -1, -1, -1,
1, 2, 4, -1, -1, -1, -1, -1, -1,
1, 2, 3, 4, -1, -1, -1, -1, -1,
1, 2, 3, 4, 7, -1, -1, -1, -1,
1, 2, 3, 4, 6, 7, -1, -1, -1,
1, 2, 3, 4, 6, -1, -1, -1, -1,
1, 2, 3, 4, 5, 6, -1, -1, -1,
1, 2, 3, 4, 5, 6, 7, -1, -1,
1, 2, 3, 4, 5, 7, -1, -1, -1,
1, 2, 3, 4, 5, -1, -1, -1, -1,
1, 2, 3, 5, -1, -1, -1, -1, -1,
1, 2, 3, 5, 7, -1, -1, -1, -1,
1, 2, 3, 5, 6, 7, -1, -1, -1,
1, 2, 3, 5, 6, -1, -1, -1, -1,
1, 2, 3, 6, -1, -1, -1, -1, -1,
1, 2, 3, 6, 7, -1, -1, -1, -1,
1, 2, 3, 7, -1, -1, -1, -1, -1,
1, 2, 3, -1, -1, -1, -1, -1, -1,
1, 3, -1, -1, -1, -1, -1, -1, -1,
1, 3, 7, -1, -1, -1, -1, -1, -1,
1, 3, 6, 7, -1, -1, -1, -1, -1,
1, 3, 6, -1, -1, -1, -1, -1, -1,
1, 3, 5, 6, -1, -1, -1, -1, -1,
1, 3, 5, 6, 7, -1, -1, -1, -1,
1, 3, 5, 7, -1, -1, -1, -1, -1,
1, 3, 5, -1, -1, -1, -1, -1, -1,
1, 3, 4, 5, -1, -1, -1, -1, -1,
1, 3, 4, 5, 7, -1, -1, -1, -1,
1, 3, 4, 5, 6, 7, -1, -1, -1,
1, 3, 4, 5, 6, -1, -1, -1, -1,
1, 3, 4, 6, -1, -1, -1, -1, -1,
1, 3, 4, 6, 7, -1, -1, -1, -1,
1, 3, 4, 7, -1, -1, -1, -1, -1,
1, 3, 4, -1, -1, -1, -1, -1, -1,
1, 4, -1, -1, -1, -1, -1, -1, -1,
1, 4, 7, -1, -1, -1, -1, -1, -1,
1, 4, 6, 7, -1, -1, -1, -1, -1,
1, 4, 6, -1, -1, -1, -1, -1, -1,
1, 4, 5, 6, -1, -1, -1, -1, -1,
1, 4, 5, 6, 7, -1, -1, -1, -1,
1, 4, 5, 7, -1, -1, -1, -1, -1,
1, 4, 5, -1, -1, -1, -1, -1, -1,
1, 5, -1, -1, -1, -1, -1, -1, -1,
1, 5, 7, -1, -1, -1, -1, -1, -1,
1, 5, 6, 7, -1, -1, -1, -1, -1,
1, 5, 6, -1, -1, -1, -1, -1, -1,
1, 6, -1, -1, -1, -1, -1, -1, -1,
1, 6, 7, -1, -1, -1, -1, -1, -1,
1, 7, -1, -1, -1, -1, -1, -1, -1,
1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 7, -1, -1, -1, -1, -1, -1,
0, 1, 6, 7, -1, -1, -1, -1, -1,
0, 1, 6, -1, -1, -1, -1, -1, -1,
0, 1, 5, 6, -1, -1, -1, -1, -1,
0, 1, 5, 6, 7, -1, -1, -1, -1,
0, 1, 5, 7, -1, -1, -1, -1, -1,
0, 1, 5, -1, -1, -1, -1, -1, -1,
0, 1, 4, 5, -1, -1, -1, -1, -1,
0, 1, 4, 5, 7, -1, -1, -1, -1,
0, 1, 4, 5, 6, 7, -1, -1, -1,
0, 1, 4, 5, 6, -1, -1, -1, -1,
0, 1, 4, 6, -1, -1, -1, -1, -1,
0, 1, 4, 6, 7, -1, -1, -1, -1,
0, 1, 4, 7, -1, -1, -1, -1, -1,
0, 1, 4, -1, -1, -1, -1, -1, -1,
0, 1, 3, 4, -1, -1, -1, -1, -1,
0, 1, 3, 4, 7, -1, -1, -1, -1,
0, 1, 3, 4, 6, 7, -1, -1, -1,
0, 1, 3, 4, 6, -1, -1, -1, -1,
0, 1, 3, 4, 5, 6, -1, -1, -1,
0, 1, 3, 4, 5, 6, 7, -1, -1,
0, 1, 3, 4, 5, 7, -1, -1, -1,
0, 1, 3, 4, 5, -1, -1, -1, -1,
0, 1, 3, 5, -1, -1, -1, -1, -1,
0, 1, 3, 5, 7, -1, -1, -1, -1,
0, 1, 3, 5, 6, 7, -1, -1, -1,
0, 1, 3, 5, 6, -1, -1, -1, -1,
0, 1, 3, 6, -1, -1, -1, -1, -1,
0, 1, 3, 6, 7, -1, -1, -1, -1,
0, 1, 3, 7, -1, -1, -1, -1, -1,
0, 1, 3, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, -1, -1, -1, -1, -1,
0, 1, 2, 3, 7, -1, -1, -1, -1,
0, 1, 2, 3, 6, 7, -1, -1, -1,
0, 1, 2, 3, 6, -1, -1, -1, -1,
0, 1, 2, 3, 5, 6, -1, -1, -1,
0, 1, 2, 3, 5, 6, 7, -1, -1,
0, 1, 2, 3, 5, 7, -1, -1, -1,
0, 1, 2, 3, 5, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, -1, -1, -1,
0, 1, 2, 3, 4, 5, 7, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, -1,
0, 1, 2, 3, 4, 5, 6, -1, -1,
0, 1, 2, 3, 4, 6, -1, -1, -1,
0, 1, 2, 3, 4, 6, 7, -1, -1,
0, 1, 2, 3, 4, 7, -1, -1, -1,
0, 1, 2, 3, 4, -1, -1, -1, -1,
0, 1, 2, 4, -1, -1, -1, -1, -1,
0, 1, 2, 4, 7, -1, -1, -1, -1,
0, 1, 2, 4, 6, 7, -1, -1, -1,
0, 1, 2, 4, 6, -1, -1, -1, -1,
0, 1, 2, 4, 5, 6, -1, -1, -1,
0, 1, 2, 4, 5, 6, 7, -1, -1,
0, 1, 2, 4, 5, 7, -1, -1, -1,
0, 1, 2, 4, 5, -1, -1, -1, -1,
0, 1, 2, 5, -1, -1, -1, -1, -1,
0, 1, 2, 5, 7, -1, -1, -1, -1,
0, 1, 2, 5, 6, 7, -1, -1, -1,
0, 1, 2, 5, 6, -1, -1, -1, -1,
0, 1, 2, 6, -1, -1, -1, -1, -1,
0, 1, 2, 6, 7, -1, -1, -1, -1,
0, 1, 2, 7, -1, -1, -1, -1, -1,
0, 1, 2, -1, -1, -1, -1, -1, -1,
0, 2, -1, -1, -1, -1, -1, -1, -1,
0, 2, 7, -1, -1, -1, -1, -1, -1,
0, 2, 6, 7, -1, -1, -1, -1, -1,
0, 2, 6, -1, -1, -1, -1, -1, -1,
0, 2, 5, 6, -1, -1, -1, -1, -1,
0, 2, 5, 6, 7, -1, -1, -1, -1,
0, 2, 5, 7, -1, -1, -1, -1, -1,
0, 2, 5, -1, -1, -1, -1, -1, -1,
0, 2, 4, 5, -1, -1, -1, -1, -1,
0, 2, 4, 5, 7, -1, -1, -1, -1,
0, 2, 4, 5, 6, 7, -1, -1, -1,
0, 2, 4, 5, 6, -1, -1, -1, -1,
0, 2, 4, 6, -1, -1, -1, -1, -1,
0, 2, 4, 6, 7, -1, -1, -1, -1,
0, 2, 4, 7, -1, -1, -1, -1, -1,
0, 2, 4, -1, -1, -1, -1, -1, -1,
0, 2, 3, 4, -1, -1, -1, -1, -1,
0, 2, 3, 4, 7, -1, -1, -1, -1,
0, 2, 3, 4, 6, 7, -1, -1, -1,
0, 2, 3, 4, 6, -1, -1, -1, -1,
0, 2, 3, 4, 5, 6, -1, -1, -1,
0, 2, 3, 4, 5, 6, 7, -1, -1,
0, 2, 3, 4, 5, 7, -1, -1, -1,
0, 2, 3, 4, 5, -1, -1, -1, -1,
0, 2, 3, 5, -1, -1, -1, -1, -1,
0, 2, 3, 5, 7, -1, -1, -1, -1,
0, 2, 3, 5, 6, 7, -1, -1, -1,
0, 2, 3, 5, 6, -1, -1, -1, -1,
0, 2, 3, 6, -1, -1, -1, -1, -1,
0, 2, 3, 6, 7, -1, -1, -1, -1,
0, 2, 3, 7, -1, -1, -1, -1, -1,
0, 2, 3, -1, -1, -1, -1, -1, -1,
0, 3, -1, -1, -1, -1, -1, -1, -1,
0, 3, 7, -1, -1, -1, -1, -1, -1,
0, 3, 6, 7, -1, -1, -1, -1, -1,
0, 3, 6, -1, -1, -1, -1, -1, -1,
0, 3, 5, 6, -1, -1, -1, -1, -1,
0, 3, 5, 6, 7, -1, -1, -1, -1,
0, 3, 5, 7, -1, -1, -1, -1, -1,
0, 3, 5, -1, -1, -1, -1, -1, -1,
0, 3, 4, 5, -1, -1, -1, -1, -1,
0, 3, 4, 5, 7, -1, -1, -1, -1,
0, 3, 4, 5, 6, 7, -1, -1, -1,
0, 3, 4, 5, 6, -1, -1, -1, -1,
0, 3, 4, 6, -1, -1, -1, -1, -1,
0, 3, 4, 6, 7, -1, -1, -1, -1,
0, 3, 4, 7, -1, -1, -1, -1, -1,
0, 3, 4, -1, -1, -1, -1, -1, -1,
0, 4, -1, -1, -1, -1, -1, -1, -1,
0, 4, 7, -1, -1, -1, -1, -1, -1,
0, 4, 6, 7, -1, -1, -1, -1, -1,
0, 4, 6, -1, -1, -1, -1, -1, -1,
0, 4, 5, 6, -1, -1, -1, -1, -1,
0, 4, 5, 6, 7, -1, -1, -1, -1,
0, 4, 5, 7, -1, -1, -1, -1, -1,
0, 4, 5, -1, -1, -1, -1, -1, -1,
0, 5, -1, -1, -1, -1, -1, -1, -1,
0, 5, 7, -1, -1, -1, -1, -1, -1,
0, 5, 6, 7, -1, -1, -1, -1, -1,
0, 5, 6, -1, -1, -1, -1, -1, -1,
0, 6, -1, -1, -1, -1, -1, -1, -1,
0, 6, 7, -1, -1, -1, -1, -1, -1,
0, 7, -1, -1, -1, -1, -1, -1, -1,
0, -1, -1, -1, -1, -1, -1, -1, -1,
}; /* end of data for list of byte descriptors */
// Constants
#define NOALLOC 0
#define ALLOC 1
class TiffG4Compression
{
public:
TiffG4Compression();
~TiffG4Compression();
public:
int G4Compress(unsigned char *indata, int inbytes, int width, int height, unsigned char *outdata, int *outbytes);
private:
void control_compression(struct uncompressed_descriptor *uncompressed, struct compressed_descriptor *compressed);
void read_uncompressed_file_into_memory(struct uncompressed_descriptor *uncompressed);
void prepare_to_compress(struct uncompressed_descriptor* uncompressed,struct compressed_descriptor* compressed,struct parameters* params);
void compress_image(struct uncompressed_descriptor* uncompressed, struct compressed_descriptor* compressed, struct parameters* params);
void make_array_of_changing_elements(struct parameters *params, struct uncompressed_descriptor* uncompressed, SHORT line_number);
void set_up_first_and_last_changing_elements_c(struct parameters *params);
void prepare_to_compress_next_line(struct parameters *params);
void set_up_first_line_c(struct parameters *params);
void compress_line(struct parameters *params);
void initialize_b1(struct parameters *params);
void pass_mode_c(struct parameters *params);
void vertical_mode_c(struct parameters *params);
void horizontal_mode_c(struct parameters *params);
void prepare_to_write_bits_c(struct compressed_descriptor *compressed);
void write_bits_c(char *string_ptr);
unsigned int flush_buffer();
void write_run_length(SHORT length, SHORT color);
void process_char(unsigned char data_byte, struct parameters *params);
private:
const char* largest_colorless_code =
{
"000000011111"
};
int comp_alloc_flag = ALLOC;
int comp_write_init_flag;
char *output_area=nullptr;
int bit_place_mark;
int byte_place_mark;
SHORT A_0, A0_color, A_1, a2, b1, b2;
};

188
huagao/g4codec.c Normal file
View File

@ -0,0 +1,188 @@
/*
* main program to drive CCITT Group 4 decompression
*/
#include "g4codec.h"
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#define _BYTE_ASCII
#ifdef _BYTE_ASCII
#define _BYTE_ZERO 0x30
#define _BYTE_ONE 0x31
#else
#define _BYTE_ZERO 0x00 // _BYTE_BINARY
#define _BYTE_ONE 0x01 // _BYTE_BINARY
#endif
/*
* This Program extracts a compressed image from the file pointer passed,
* stripping the file header and loads it into memory. It gets the
* dimensions of the resultant pixrect image from the compressed header
* and allocates the pixrect structure. It reverses the bits in the
* compressed image and calls decompress4() for decompression. The
* pixrect structure is used so the image can be displayed.
*/
int convertFromByte(char *inData, char *outData, int total, int width, int height)
{
int in, out, maxOut;
char outByte;
int inVal;
maxOut = width * height;
outByte = 0;
out = 0;
for (in=0; in<total, out<maxOut; in++)
{
inVal = inData[in];
switch(inVal)
{
case _BYTE_ZERO: // 0
outByte = outByte<<1;
out ++;
if ((out % 8) == 0)
{
outData[(out/8)-1] = outByte;
outByte = 0;
}
break;
case _BYTE_ONE: // 1
outByte = (outByte<<1) + 1;
out ++;
if ((out % 8) == 0)
{
outData[(out/8)-1] = outByte;
outByte = 0;
}
break;
default: // don't care
break;
}
}
if ((out % 8) != 0)
{
outData[out/8] = outByte; // flush
return (out/8+1);
} else
{
return (out/8);
}
}
int main(int argc, char* argv[])
{
u_char *source; /* Pointer to compressed image in memory */
u_char *destination; /* Pointer to decompressed raster in memory */
char *infile; /* Pointer to compressed name (argv[1]) */
char *outfile; /* Pointer to uncompressed name (argv[2]) */
FILE *input; /* Compressed file pointer */
FILE *output; /* Decompressed file pointer */
int height; /* Raster image height in pixels */
int width; /* Raster image width in pixels */
u_int filesize; /* Size of compressed image in bytes */
int outbytes; /* Output length */
int iCodec;
if(argc < 6)
{
fprintf(stderr, "Usage: %s codec(0/1/2) srcFile destFile width height\n",
argv[0]);
fprintf(stderr, "Flag: 0 decode, 1 compress 1BPP, 2 compress 8BPP\n");
exit(-1);
}
iCodec = atoi(argv[1]); // 0 for decode, 1 for comp binary, 2 for comp byte
infile = argv[2];
outfile = argv[3];
width = atoi(argv[4]);
height = atoi(argv[5]);
/*
* Open input
*/
if ((input = fopen(infile,"rb")) == NULL)
{
fprintf(stderr,"%s: Can't open %s\n",argv[0], infile);
exit(-2);
}
/*
* Open output
*/
if ((output = fopen(outfile,"wb")) == NULL)
{
fprintf(stderr, "%s: Can't open %s\n", argv[0], outfile);
exit(-3);
}
// find out input size
if (iCodec == 1) // encoding binary, file can be larger than image
{
filesize = width*height/8;
if ((width*height%8) != 0)
filesize ++;
} else
{ // in other case we don't know the real size of input
filesize = _lseek(_fileno(input), 0L, SEEK_END); // seek to EOF
}
if( (source = (u_char *) malloc(filesize)) == NULL)
{
fprintf(stderr, "%s: Can't malloc %d bytes for %s.\n",
argv[0], filesize,infile);
exit(-4);
}
_lseek(_fileno(input), 62L, SEEK_SET); // seek to Beginning of file
/*
* Read input image
*/
if (fread(source, 1, filesize, input) != filesize)
{
fprintf(stderr, "%s: Error reading compressed file.\n", argv[0]);
exit(-6);
}
fclose(input);
// maximum size of destination, assuming binary image
destination = (u_char *) malloc(2*width*height/8);
if ( destination == NULL)
{
fprintf(stderr, "%s: Destination_create failed.\n",argv[0]);
exit(-5);
}
// special treatment to covert from byte per pixel to bit per pixel
if (iCodec == 2)
{
outbytes = convertFromByte(source, destination, filesize, width, height);
if (outbytes != width*height/8)
exit (-7);
else // store the raw data back at the source
memcpy(source, destination, outbytes);
filesize = outbytes;
}
// perform codec
if (iCodec == 0)
{
grp4decomp(source,filesize, width,height, destination, &outbytes);
} else
{
grp4comp(source,filesize, width,height, destination, &outbytes);
}
// the output as pbm for decoded image
if (iCodec == 0)
fprintf(output, "P4\n%d %d\n", width, height);
fwrite(destination, outbytes, 1, output);
fclose(output);
}

25
huagao/g4codec.h Normal file
View File

@ -0,0 +1,25 @@
//
// g4codec.h
//
#ifndef _G4DECOC_H
#define _G4DECOC_H
#define White 0
#define Black 1
#define Black_byte 255 // byte of all black bits: 11111111b
//int grp4decomp(unsigned char *indata,
// int inbytes,
// int width,
// int height,
// unsigned char *outdata,
// int *outbytes);
int grp4comp(unsigned char *indata,
int inbytes,
int width,
int height,
unsigned char *outdata,
int *outbytes);
#endif //#ifndef _G4DECOC_H

1420
huagao/grp4comp.c Normal file

File diff suppressed because it is too large Load Diff

133
huagao/grp4comp.h Normal file
View File

@ -0,0 +1,133 @@
/*********************************************************************/
/* grp4comp.h */
/* Originally compression.h */
/*********************************************************************/
#include <stdio.h>
/* WARNING */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/* !!!!!!!!!!!!!!!!!! Change Here. Redeclaration of Type. !!!!!!!!!!!!!!!! */
#define SHORT int /* this type was just a regular old C "short". */
/* In images with > 2^15 rows the 2 byte definition */
/* gave garbage output because short overflowed. */
/* Increasing all variables from 2 to 4 bytes seems */
/* to fix it. I have used the macro SHORT here to show */
/* where this change applies, so that it can be undone */
/* if desired. Some variables of type "int" existed in */
/* the code before this change, and the SHORT macro */
/* allows reversal of just the correct ones. */
/* Patrick Grother Dec 9 1994 */
/* !!!!!!!!!!!!!!!!!! Change Here. Redeclaration of Type. !!!!!!!!!!!!!!!! */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
#define Largest_code 2560
#define Size_of_make_up_code_increments 64
#define Max_terminating_length 63 /* longest terminating code*/
#define Number_of_different_bytes 256
#define Pixels_per_byte 8
#define Bits_per_byte 8
#define Last_bit_in_a_byte 7 /* assumes bits numbered from 0 - 7 */
#define Last_bit_mask 1 /* masks the last (low magnitude) bit */
#define Default_width_in_pixels 2560 /* default width of a scan line */
#define Default_number_of_lines 3300 /* default length of an image */
#define Invalid -1
#define None 0
#define Extra_positions 25 /* ensures extra room in allocations */
#define Not_done_yet 0
#define VL3 -3 /* Vertical Left 3 mode */
#define VL2 -2 /* Vertical Left 2 mode */
#define VL1 -1 /* Vertical Left 1 mode */
#define V0 0 /* Vertical mode */
#define VR1 1 /* Vertical Right 1 mode */
#define VR2 2 /* Vertical Right 2 mode */
#define VR3 3 /* Vertical Right 3 mode */
#define P 4 /* Pass mode */
#define H 5 /* Horizontal mode */
#define EOFB 6 /* End Of File Buffer */
#define No_offset 0 /* no offset during fseek() */
#define End_of_file 2 /* start at EOF during fseek() */
#define Start_of_file 0 /* start at SOF during fseek() */
/*
unsigned char *calloc();
SHORT *malloc();
*/
struct parameters {
SHORT previous_color; /* color of last run of pixels */
SHORT index; /* indicates current position in "coding_line" */
SHORT max_pixel; /* the number of pixels in a scan line */
SHORT pixel; /* pixel number of the last changing element */
SHORT *reference_line; /* array of changing elements on reference line */
SHORT *coding_line; /* array of changing elements on coding line */
};
struct compressed_descriptor {
unsigned char *data; /* pointer to compressed image */
SHORT pixels_per_line; /* the number of pixels in a scan line */
SHORT number_of_lines; /* the number of scan lines in the image */
int length_in_bytes; /* length of the compressed image in bytes */
};
struct uncompressed_descriptor {
unsigned char *data; /* pointer to uncompressed image */
SHORT pixels_per_line; /* the number of pixels in a scan line */
SHORT number_of_lines; /* the number of scan lines in the image */
};
/*****************************************************************************
declarations of all the procedures in the group4 compression routines
follow. The names of the files that contain the procedures are enclosed
in comments above the declarations.
******************************************************************************/
/* compress.c */
void control_compression();
struct uncompressed_descriptor process_arguments();
void set_up_first_and_last_changing_elements_c();
void set_up_first_and_last_changing_elements_d();
void read_uncompressed_file_into_memory();
void write_compressed_data_into_a_file();
void prepare_to_compress();
void compress_image();
void make_array_of_changing_elements();
void prepare_to_compress_next_line();
void set_up_first_line_c();
void set_up_first_line_d();
void crash_c();
/* table.c */
void process_char();
/* mode.c */
void compress_line();
void initialize_b1();
void pass_mode_c();
void pass_mode_d();
void vertical_mode_c();
void vertical_mode_d();
void horizontal_mode_c();
void horizontal_mode_d();
/* write_run.c */
void write_run_length();
/* write_bits.c */
void prepare_to_write_bits_c();
void prepare_to_write_bits_d();
void write_bits_c();
void write_bits_d();
unsigned int flush_buffer();

1356
huagao/grp4deco.c Normal file

File diff suppressed because it is too large Load Diff

118
huagao/grp4deco.h Normal file
View File

@ -0,0 +1,118 @@
/*********************************************************************/
/* grp4decomp.h */
/* Originally decompression.h */
/*********************************************************************/
#include <stdio.h>
#define SHORT int
/*
#define True 1
#define False 0
#define Debug True // False
#define White 0
#define Black 1
#define Black_byte 255 // byte of all black bits: 11111111b
*/
#define Max_terminating_length 63 /* longest terminating code*/
#define Pixels_per_byte 8
#define Bits_per_byte 8
#define Last_bit_in_a_byte 7 /* assumes bits numbered from 0 - 7 */
#define Last_bit_mask 1 /* masks the last (low magnitude) bit */
#define Default_width_in_pixels 1728 /* default width of a scan line */
#define Default_number_of_lines 2200 /* default length of an image */
#define Invalid -1
#define None 0
#define Extra_positions 25 /* ensures extra room in allocations */
#define Not_done_yet 0
#define VL3 -3 /* Vertical Left 3 mode */
#define VL2 -2 /* Vertical Left 2 mode */
#define VL1 -1 /* Vertical Left 1 mode */
#define V0 0 /* Vertical mode */
#define VR1 1 /* Vertical Right 1 mode */
#define VR2 2 /* Vertical Right 2 mode */
#define VR3 3 /* Vertical Right 3 mode */
#define P 4 /* Pass mode */
#define H 5 /* Horizontal mode */
#define EOFB 6 /* End Of File Buffer */
#define No_offset 0 /* no offset during fseek() */
#define End_of_file 2 /* start at EOF during fseek() */
#define Start_of_file 0 /* start at BOF during fseek() */
/*
char *calloc();
SHORT *malloc();
*/
struct parameters {
SHORT index; /* indicates current position in "coding_line" */
SHORT max_pixel; /* the number of pixels in a scan line */
SHORT *reference_line;/* array of changing elements on reference line */
SHORT *coding_line; /* array of changing elements on coding line */
};
struct decompressed_descriptor {
char *data; /* pointer to decompressed image */
SHORT pixels_per_line; /* the number of pixels in a scan line */
SHORT number_of_lines; /* the number of scan lines in the image */
};
struct compressed_descriptor {
char *data; /* pointer to compressed image */
SHORT pixels_per_line; /* the number of pixels in a scan line */
SHORT number_of_lines; /* the number of scan lines in the image */
int length_in_bytes; /* length of the compressed image in bytes */
};
/*****************************************************************************
declarations of all the procedures in the group4 decompression routines
follow. The names of the files that contain the procedures are enclosed
in comments above the declarations.
******************************************************************************/
/* decompress.c */
void control_decompression();
struct compressed_descriptor process_arguments();
void read_compressed_file_into_memory();
void write_decompressed_data_into_a_file();
void prepare_to_decompress();
void set_up_first_line_c();
void set_up_first_line_d();
void set_up_first_and_last_changing_elements_c();
void set_up_first_and_last_changing_elements_d();
void prepare_to_decompress_next_line();
void swap_the_reference_and_coding_lines();
void crash_d();
/* decomp.c */
SHORT decompress_line();
SHORT get_mode();
void pass_mode_c();
void pass_mode_d();
void vertical_mode_c();
void vertical_mode_d();
void horizontal_mode_c();
void horizontal_mode_d();
/* read.c */
void prepare_to_read_bits();
SHORT read_bit();
/* write.c */
void prepare_to_write_bits_c();
void prepare_to_write_bits_d();
void write_bits_c();
void write_bits_d();
/* tree.c */
SHORT find_run_length_code();