1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/cde/lib/DtSearch/hencode.c
2012-03-10 18:58:32 +00:00

382 lines
10 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* COMPONENT_NAME: austext
*
* FUNCTIONS: convert_str_2_char
* gen_vec
* hc_encode
* main
* process_char
*
* ORIGINS: 27
*
*
* (C) COPYRIGHT International Business Machines Corp. 1990,1995
* All Rights Reserved
* Licensed Materials - Property of IBM
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/********************** HENCODE.C ***********************
* $XConsortium: hencode.c /main/9 1996/11/21 19:50:29 drk $
* Huffman encoder program.
*
* $Log$
* Revision 2.3 1996/03/13 22:56:39 miker
* Changed char to UCHAR several places.
*
* Revision 2.2 1995/10/26 15:11:42 miker
* Added prolog.
*
* Revision 2.1 1995/09/22 20:50:40 miker
* Freeze DtSearch 0.1, AusText 2.1.8
*
* Revision 1.3 1995/09/05 18:07:00 miker
* Name changes for DtSearch.
*/
#include "SearchP.h"
#include <errno.h>
#define X_INCLUDE_STRING_H
#define XOS_USE_NO_LOCKING
#include <X11/Xos_r.h>
#define PROGNAME "HENCODE"
#define MS_huff 30 /* message catalog set number */
#define DELIMITERS "\t\n"
#define LAST_BIT '-'
#define LITERAL_NUM 256
#define NO_SPACE 0
/*------------------------ GLOBALS ---------------------------*/
long gen_vec_hufid = 0L;
static struct or_blobrec blobrec;
static char *huff_code[257];
static int code_length[257];
static char coded_bits_str[9];
static char bit_pos = 0;
static char bits_left;
static int total_num_chars = 0;
static int num_char_coded = 0;
static char zero_str[] = "00000000";
#define MAX_NUM_CHAR (sizeof(blobrec.or_blob) - 1)
#define MAX_NUM_BITS (8 * MAX_NUM_CHAR)
/****************************************/
/* */
/* GENERATE VECTORS */
/* */
/****************************************/
void gen_vec (char *fname_huffcode_tab)
{
char temp[40];
int i, j;
char tab_filebuf[128];
unsigned char ch;
FILE *tab_stream;
_Xstrtokparams strtok_buf;
if ((tab_stream = fopen (fname_huffcode_tab, "r")) == NULL) {
printf (catgets(dtsearch_catd, MS_huff, 1,
"%s: Cannot open huffman encode file '%s':\n"
" %s\n Exit Code = 2\n"),
PROGNAME"222", fname_huffcode_tab, strerror (errno));
DtSearchExit (2);
}
memset (huff_code, 0, sizeof(huff_code));
memset (code_length, 0, sizeof(code_length));
/*
* First line in the file contains time stamp. We have to read
* it separately. First token on first line is hufid. Save it
* in a global for optional use by caller.
*/
fgets (tab_filebuf, sizeof (tab_filebuf) - 1, tab_stream);
gen_vec_hufid = atol (tab_filebuf);
/*-------------- READ IN HUFFMAN FILE ------------*/
/*
* We are only interested in the character itself (index) and
* its Huffman Code
*/
while (fgets (tab_filebuf, sizeof (tab_filebuf) - 1, tab_stream)
!= NULL) {
i = atoi (_XStrtok (tab_filebuf, DELIMITERS, strtok_buf)); /* char */
/* read current huff code */
strcpy (temp, _XStrtok (NULL, DELIMITERS, strtok_buf));
if (temp[0] == ' ') {
/* Empty huffcode associated with LITERAL CODE.
* Either this is literal char itself and literal
* encodeing has been turned off, or this char is
* so rare that it is coded using the literal char.
*/
if (i == 256)
continue;
/* current character has LITERAL CODE */
strcpy (temp, huff_code[LITERAL_NUM]);
*(code_length + i) = *(code_length + LITERAL_NUM) + 8;
ch = (unsigned char) i;
for (j = 0; j < 8; j++) {
if (ch & 0x80) {
temp[*(code_length + LITERAL_NUM) + j] =
'1';
}
else {
temp[*(code_length + LITERAL_NUM) + j] =
'0';
}
ch = ch << 1;
}
temp[*(code_length + LITERAL_NUM) + 8] = '\0';
huff_code[i] =
(char *) malloc (*(code_length + i) + 1);
strcpy (huff_code[i], temp);
}
else {
/* regular HUFFMAN code */
*(code_length + i) = strlen (temp);
huff_code[i] =
(char *) malloc (*(code_length + i) + 1);
strcpy (huff_code[i], temp);
}
}
fclose (tab_stream);
} /* end of function gen_vec */
/********************************************************/
/* */
/* Convert Coded String to Coded Character */
/* */
/********************************************************/
void convert_str_2_char (char *code)
{
int i, j;
*code = 0;
j = 1;
for (i = 0; i < 8; i++) {
if (*(coded_bits_str + (7 - i)) == '1') {
*code += j;
}
j = j * 2;
}
total_num_chars++;
return;
}
/****************************************/
/* */
/* Process Current Character */
/* */
/****************************************/
int process_char (UCHAR ch, char *bitstr)
{
char temp_code[40];
char coded_char;
int i, j;
int num_of_bits_in_code;
i = (int) ch;
num_of_bits_in_code = *(code_length + i);
if ((MAX_NUM_BITS - total_num_chars * 8 - bit_pos) <
num_of_bits_in_code) {
return NO_SPACE;
}
strcpy (temp_code, huff_code[i]);
while (TRUE) {
/* fill new character with Huffman Code */
if (bit_pos == 0) {
if (num_of_bits_in_code == 8) {
strcpy (coded_bits_str, temp_code);
convert_str_2_char (&coded_char);
bitstr[total_num_chars - 1] = coded_char;
return TRUE;
}
if (num_of_bits_in_code < 8) {
strcpy (coded_bits_str, temp_code);
bit_pos = num_of_bits_in_code;
bits_left = 8 - bit_pos;
return TRUE;
}
if (num_of_bits_in_code > 8) {
strncpy (coded_bits_str, temp_code, 8);
coded_bits_str[8] = '\0';
convert_str_2_char (&coded_char);
bitstr[total_num_chars - 1] = coded_char;
num_of_bits_in_code -= 8;
strcpy (temp_code, &temp_code[8]);
}
} /* end of bit_pos == 0 loop */
else {
j = bit_pos + num_of_bits_in_code;
if (j == 8) {
bit_pos = 0;
strcat (coded_bits_str, temp_code);
convert_str_2_char (&coded_char);
bitstr[total_num_chars - 1] = coded_char;
return TRUE;
}
if (j < 8) {
strcat (coded_bits_str, temp_code);
bit_pos = j;
bits_left = 8 - bit_pos;
return TRUE;
}
if (j > 8) {
strncat (coded_bits_str, temp_code,
(size_t) bits_left);
convert_str_2_char (&coded_char);
bitstr[total_num_chars - 1] = coded_char;
num_of_bits_in_code -= bits_left;
strcpy (temp_code, &huff_code[i][bits_left]);
bit_pos = 0;
}
} /* end of else loop */
} /* end of while(TRUE) loop */
}
/************************************************/
/* */
/* HC Encode */
/* */
/************************************************/
int hc_encode (struct or_blobrec * targblobrec,
UCHAR *charbuf,
int charcount,
int file_pos)
{
/********** replaced by blobrec above...
union charint
{
char ch[2];
INT orig_char_count;
} un1;
static char temp1 [MAX_NUM_CHAR+1]; ...repl by blobrec;
************/
char *ptr, *targ, *src;
int i, j;
char temp;
char ret_code = TRUE;
char write = FALSE;
char last_call = FALSE;
if (charcount == 0) {
last_call = TRUE;
charcount = 1;
}
for (i = 0; i < charcount; i++) {
if (!last_call) {
ret_code = process_char (charbuf[i], (char *) blobrec.or_blob);
}
if ((ret_code == NO_SPACE) ||
(file_pos && (i == (charcount - 1)))) {
if (!last_call) {
if (file_pos && (i == (charcount - 1))) {
num_char_coded++;
}
}
if (bit_pos) {
strncat (coded_bits_str, zero_str,
(size_t) bits_left);
convert_str_2_char (&temp);
blobrec.or_blob[total_num_chars - 1][0] = temp;
}
write = TRUE;
/**********
un1.orig_char_count = num_char_coded;
bitstring[0] = un1.ch[0];
bitstring[1] = un1.ch[1];
for (j = 0; j <= total_num_chars; j++) {
*(bitstring + j + 2) = *(temp1 + j);
};
**************/
targblobrec->or_bloblen = num_char_coded;
targ = (char *) targblobrec->or_blob;
src = (char *) blobrec.or_blob;
for (j = 0; j < total_num_chars; j++)
*targ++ = *src++;
num_char_coded = 0;
bit_pos = 0;
total_num_chars = 0;
if (file_pos && (i == (charcount - 1))) {
return write;
}
i--;
}
else {
num_char_coded++;
}
}
return write;
}
#ifdef DEBUG_HENCODE
/****************************************/
/* */
/* Main */
/* */
/****************************************/
main (int argc, char *argv[])
{
FILE *stream;
char bitstring[MAX_NUM_CHAR + 2];
char charbuf[MAX_NUM_CHAR + 1];
int charcount = 0;
int mychar;
if (argc < 2) {
fprintf (stderr, "Usage: try filename\n");
exit (1);
}
if ((stream = fopen (argv[1], "rb")) == NULL) {
fprintf (stderr, "Could not open input file '%s'\n", argv[1]);
exit (2);
}
fp = fopen ("codefile.dat", "wb");
gen_vec ();
while ((mychar = getc (stream)) != EOF) {
charbuf[charcount] = mychar;
charcount++;
if (charcount == MAX_NUM_CHAR) {
hc_encode (bitstring, charbuf, charcount, 0);
/*
* for (j = 0; j < charcount; j++) {
* fputc(bitstring[j], fp); }
*/
charcount = 0;
}
}
hc_encode (bitstring, charbuf, charcount, 1);
printf ("Total Number of Characters = %ld\n", total_num_chars);
fclose (fp);
fclose (stream);
return;
}
#endif
/********************** HENCODE.C ***********************/