2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * COMPONENT_NAME: austext
26 * FUNCTIONS: convert_str_2_char
35 * (C) COPYRIGHT International Business Machines Corp. 1990,1995
37 * Licensed Materials - Property of IBM
38 * US Government Users Restricted Rights - Use, duplication or
39 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
41 /********************** HENCODE.C ***********************
42 * $XConsortium: hencode.c /main/9 1996/11/21 19:50:29 drk $
43 * Huffman encoder program.
46 * Revision 2.3 1996/03/13 22:56:39 miker
47 * Changed char to UCHAR several places.
49 * Revision 2.2 1995/10/26 15:11:42 miker
52 * Revision 2.1 1995/09/22 20:50:40 miker
53 * Freeze DtSearch 0.1, AusText 2.1.8
55 * Revision 1.3 1995/09/05 18:07:00 miker
56 * Name changes for DtSearch.
62 #define X_INCLUDE_STRING_H
63 #define XOS_USE_NO_LOCKING
64 #include <X11/Xos_r.h>
66 #define PROGNAME "HENCODE"
67 #define MS_huff 30 /* message catalog set number */
68 #define DELIMITERS "\t\n"
70 #define LITERAL_NUM 256
74 /*------------------------ GLOBALS ---------------------------*/
75 long gen_vec_hufid = 0L;
77 static struct or_blobrec blobrec;
78 static char *huff_code[257];
79 static int code_length[257];
80 static char coded_bits_str[9];
81 static char bit_pos = 0;
82 static char bits_left;
83 static int total_num_chars = 0;
84 static int num_char_coded = 0;
85 static char zero_str[] = "00000000";
87 #define MAX_NUM_CHAR (sizeof(blobrec.or_blob) - 1)
88 #define MAX_NUM_BITS (8 * MAX_NUM_CHAR)
90 /****************************************/
92 /* GENERATE VECTORS */
94 /****************************************/
95 void gen_vec (char *fname_huffcode_tab)
99 char tab_filebuf[128];
102 _Xstrtokparams strtok_buf;
104 if ((tab_stream = fopen (fname_huffcode_tab, "r")) == NULL) {
105 printf (catgets(dtsearch_catd, MS_huff, 1,
106 "%s: Cannot open huffman encode file '%s':\n"
107 " %s\n Exit Code = 2\n"),
108 PROGNAME"222", fname_huffcode_tab, strerror (errno));
111 memset (huff_code, 0, sizeof(huff_code));
112 memset (code_length, 0, sizeof(code_length));
114 * First line in the file contains time stamp. We have to read
115 * it separately. First token on first line is hufid. Save it
116 * in a global for optional use by caller.
118 fgets (tab_filebuf, sizeof (tab_filebuf) - 1, tab_stream);
119 gen_vec_hufid = atol (tab_filebuf);
121 /*-------------- READ IN HUFFMAN FILE ------------*/
123 * We are only interested in the character itself (index) and
126 while (fgets (tab_filebuf, sizeof (tab_filebuf) - 1, tab_stream)
128 i = atoi (_XStrtok (tab_filebuf, DELIMITERS, strtok_buf)); /* char */
129 /* read current huff code */
130 strcpy (temp, _XStrtok (NULL, DELIMITERS, strtok_buf));
131 if (temp[0] == ' ') {
132 /* Empty huffcode associated with LITERAL CODE.
133 * Either this is literal char itself and literal
134 * encodeing has been turned off, or this char is
135 * so rare that it is coded using the literal char.
140 /* current character has LITERAL CODE */
141 snprintf(temp, sizeof(temp), "%s", huff_code[LITERAL_NUM]);
142 *(code_length + i) = *(code_length + LITERAL_NUM) + 8;
143 ch = (unsigned char) i;
144 for (j = 0; j < 8; j++) {
146 temp[*(code_length + LITERAL_NUM) + j] =
150 temp[*(code_length + LITERAL_NUM) + j] =
155 temp[*(code_length + LITERAL_NUM) + 8] = '\0';
157 (char *) malloc (*(code_length + i) + 1);
158 strcpy (huff_code[i], temp);
161 /* regular HUFFMAN code */
162 *(code_length + i) = strlen (temp);
164 (char *) malloc (*(code_length + i) + 1);
165 strcpy (huff_code[i], temp);
169 } /* end of function gen_vec */
171 /********************************************************/
173 /* Convert Coded String to Coded Character */
175 /********************************************************/
176 void convert_str_2_char (char *code)
182 for (i = 0; i < 8; i++) {
183 if (*(coded_bits_str + (7 - i)) == '1') {
192 /****************************************/
194 /* Process Current Character */
196 /****************************************/
197 int process_char (UCHAR ch, char *bitstr)
202 int num_of_bits_in_code;
205 num_of_bits_in_code = *(code_length + i);
206 if ((MAX_NUM_BITS - total_num_chars * 8 - bit_pos) <
207 num_of_bits_in_code) {
210 strcpy (temp_code, huff_code[i]);
212 /* fill new character with Huffman Code */
214 if (num_of_bits_in_code == 8) {
215 strcpy (coded_bits_str, temp_code);
216 convert_str_2_char (&coded_char);
217 bitstr[total_num_chars - 1] = coded_char;
220 if (num_of_bits_in_code < 8) {
221 strcpy (coded_bits_str, temp_code);
222 bit_pos = num_of_bits_in_code;
223 bits_left = 8 - bit_pos;
226 if (num_of_bits_in_code > 8) {
227 strncpy (coded_bits_str, temp_code, 8);
228 coded_bits_str[8] = '\0';
229 convert_str_2_char (&coded_char);
230 bitstr[total_num_chars - 1] = coded_char;
231 num_of_bits_in_code -= 8;
232 strcpy (temp_code, &temp_code[8]);
234 } /* end of bit_pos == 0 loop */
236 j = bit_pos + num_of_bits_in_code;
239 strcat (coded_bits_str, temp_code);
240 convert_str_2_char (&coded_char);
241 bitstr[total_num_chars - 1] = coded_char;
245 strcat (coded_bits_str, temp_code);
247 bits_left = 8 - bit_pos;
251 strncat (coded_bits_str, temp_code,
253 convert_str_2_char (&coded_char);
254 bitstr[total_num_chars - 1] = coded_char;
255 num_of_bits_in_code -= bits_left;
256 strcpy (temp_code, &huff_code[i][bits_left]);
259 } /* end of else loop */
260 } /* end of while(TRUE) loop */
263 /************************************************/
267 /************************************************/
268 int hc_encode (struct or_blobrec * targblobrec,
273 /********** replaced by blobrec above...
279 static char temp1 [MAX_NUM_CHAR+1]; ...repl by blobrec;
284 char ret_code = TRUE;
286 char last_call = FALSE;
288 if (charcount == 0) {
292 for (i = 0; i < charcount; i++) {
294 ret_code = process_char (charbuf[i], (char *) blobrec.or_blob);
296 if ((ret_code == NO_SPACE) ||
297 (file_pos && (i == (charcount - 1)))) {
299 if (file_pos && (i == (charcount - 1))) {
304 strncat (coded_bits_str, zero_str,
306 convert_str_2_char (&temp);
307 blobrec.or_blob[total_num_chars - 1][0] = temp;
311 un1.orig_char_count = num_char_coded;
312 bitstring[0] = un1.ch[0];
313 bitstring[1] = un1.ch[1];
314 for (j = 0; j <= total_num_chars; j++) {
315 *(bitstring + j + 2) = *(temp1 + j);
318 targblobrec->or_bloblen = num_char_coded;
319 targ = (char *) targblobrec->or_blob;
320 src = (char *) blobrec.or_blob;
321 for (j = 0; j < total_num_chars; j++)
327 if (file_pos && (i == (charcount - 1))) {
340 /****************************************/
344 /****************************************/
345 main (int argc, char *argv[])
348 char bitstring[MAX_NUM_CHAR + 2];
349 char charbuf[MAX_NUM_CHAR + 1];
354 fprintf (stderr, "Usage: try filename\n");
357 if ((stream = fopen (argv[1], "rb")) == NULL) {
358 fprintf (stderr, "Could not open input file '%s'\n", argv[1]);
361 fp = fopen ("codefile.dat", "wb");
363 while ((mychar = getc (stream)) != EOF) {
364 charbuf[charcount] = mychar;
366 if (charcount == MAX_NUM_CHAR) {
367 hc_encode (bitstring, charbuf, charcount, 0);
369 * for (j = 0; j < charcount; j++) {
370 * fputc(bitstring[j], fp); }
375 hc_encode (bitstring, charbuf, charcount, 1);
376 printf ("Total Number of Characters = %ld\n", total_num_chars);
383 /********************** HENCODE.C ***********************/