twain3.0/huagao/g4codec.c

189 lines
4.3 KiB
C

/*
* 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);
}