📄 fconvert.cpp
字号:
// ******************************************************************** //
// //
// FCONVERT.CPP //
// Copyright (c) 1993, Michael Holmes and Bob Flanders //
// C++ Communication Utilities //
// //
// This file contains the routines for converting to and //
// from the G3 fax format. //
// //
// ******************************************************************** //
//
// Conversion Routine Globals
//
int f_handle = -1, // G3 file handle
f_pgcnt, // maximum page count
f_write_flag, // write_out bit buffer flag
f_write_cnt; // write_out global counter
char *f_buffer, // work buffer
*f_ptr, // ..and current pointer
f_filename[MAX_PATH]; // fax filename
long f_page; // current G3 page size
#define HDR_LEN 128 // header length
#define BUF_SIZE 256 // buffer size
/* ******************************************************************** *
*
* f_locate() -- find a G3 formatted file and check its integrity
*
* returns: 0 = file opened
* 1 = file not found
*
* ******************************************************************** */
int f_locate(char *s) // source filename
{
long file_size, // file size
pos; // current file position
if (f_handle != -1) // q. already open?
{
close(f_handle); // a. yes .. close file
f_handle = -1; // ..and clear flag
}
if (NOT first_nonblank(s)) // q. empty string?
return(1); // a. yes .. just return
if ((f_handle = open(s, // q. find and open file ok?
O_RDONLY | O_BINARY)) == -1)
return(1); // a. no .. return w/error
file_size = lseek(f_handle, 0L, SEEK_END); // get file size
lseek(f_handle, 0L, SEEK_SET); // ..and back to file start
if ((read(f_handle, page, 128) != 128) || // q. file header available
strncmp((char *) page, "G3", 2)) // ..and our format?
{
close(f_handle); // a. no .. just close file
f_handle = -1; // ..clear flag
return(1); // ..and return to caller
}
pos = lseek(f_handle, 0L, SEEK_CUR); // get starting position
for (f_pgcnt = 0;;) // count available fax pages
{
if (read(f_handle, (char *) &f_page, // q. read in enough to cover
sizeof(long)) != sizeof(long)) // ..the page length field?
break; // a. no .. exit loop
if ((f_page < 1) || // q. page size non-positive?
((f_page + pos + 4) > file_size)) // ..or bigger than the file?
break; // a. yes .. exit loop
if ((pos = lseek(f_handle, f_page, // q. properly position to the
SEEK_CUR)) == -1L) // ..start of the next page?
break; // a. no .. exit loop
f_pgcnt++; // count this page
}
strcpy(f_filename, s); // save filename ..
return(0); // ..then return all ok
}
/* ******************************************************************** *
*
* f_get_next_byte() -- get the next byte from the G3 file
*
* returns: -1 = end of data or error
* n = next byte
*
* ******************************************************************** */
int f_get_next_byte(void)
{
static
int rb; // remaining buffer count
if (f_ptr == 0 || rb == 0) // q. 1st call or out of data?
{ // a. yes .. get the next blk
if (f_page == 0) // q. out of data to read?
return(-1); // a. yes .. return all done
if (f_buffer == 0) // q. buffer allocated?
f_buffer = (char *) // a. no .. get a buffer
malloc_chk(BUF_SIZE);
rb = (int)((f_page > BUF_SIZE) ? // set count to smaller of
BUF_SIZE : f_page); // ..what's left or buffer size
if (read(f_handle, f_buffer, rb) != rb) // q. file read ok?
quit_with(read_error); // a. no .. give error message
f_page -= rb; // deduct what was read
f_ptr = f_buffer; // set up character pointer
}
rb--; // decriment remaining count
return(*(unsigned char *) f_ptr++); // ..and return character
}
/* ******************************************************************** *
*
* f_get_byte() -- get the next value from the G3 file handling DLEs
*
* returns: -1 = end of data or error
* n = next byte
*
* ******************************************************************** */
int f_get_byte(void)
{
int v; // work value
while (1)
{
if ((v = f_get_next_byte()) == -1) // q. out of data?
return(-1); // a. yes .. return EOF
if (v == DLE) // q. DLE character?
{ // a. yes .. get another
if ((v = f_get_next_byte()) == -1) // q. get another char ok?
return(-1); // a. no .. return EOF
if (v == DLE) // q. another DLE?
return(v); // a. yes .. return the goods
}
else
return(v); // else .. return w/character
}
}
/* ******************************************************************** *
*
* f_get_bit() -- get the next bit from the G3 file
*
* returns: -1 = end of data or error
* 0 = zero bit found
* 1 = one bit found
*
* ******************************************************************** */
int f_get_bit(void)
{
static
int w, // work byte
c = 0; // bit count
w >>= 1; // move next bit into place
if (f_ptr == 0 || c == 0) // q. 1st call or out of data?
{ // a. yes .. get a byte
if ((w = f_get_byte()) == -1) // q. out of data?
return(-1); // a. yes .. return EOF
c = 8; // number of available bits
}
c--; // show another one used
return(w & 1); // ..then rtn a bit to caller
}
/* ******************************************************************** *
*
* f_search() -- search for a codeword match
*
* returns: -2 = end of line or error
* -1 = no match found
* n = match found, n is nbr of bits in codeword
*
* ******************************************************************** */
int f_search(int type, // type of code
// 0 = white space
// 1 = black space
int l, // length in bits
int a) // accumulator
{
struct code_entry *e; // codeword table entries
if (l == 12 && a == 1) // q. end of line found?
return(-2); // a. yes .. return to caller
if ((e = code_table[l - 1][type]) != 0) // q. table entry found?
{ // a. yes .. check table
for (; e->code; e++) // scan a codeword table
if (e->code == a) // q. find a codeword match?
return(e->value); // a. yes .. return
}
if (l == 13) // q. reach max codeword size?
return(-2); // a. yes .. return w/error
else
return(-1); // else .. rtn nothing found
}
/* ******************************************************************** *
*
* f_get_code() -- get the next codeword from the G3 stream
*
* returns: 0 = converted next word ok
* 1 = error or end of line
*
* ******************************************************************** */
int f_get_code(int type, // type of code
// 0 = white space
// 1 = black space
int *len) // length in bits
{
int a = 0, // accumulator
b, // one bit work area
l = 0; // working length
while (1)
{
if ((b = f_get_bit()) == -1) // q. get a bit successfully?
return(1); // a. no .. must be out of data
a = (a << 1) | b; // shift in a new bit
l++; // ..tally up bits received
switch (*len = f_search(type, l, a)) // check for match
{
case -2: // end of line or error
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -