📄 lzwc.c
字号:
*
* To clear a bit you AND it with a 0.
* e.g. to clear bit 3 - AND with 1111 1011
*
* A. Based on the ith short and the condensing
* by 3/4th's, calculate the byte in the
* char buffer and the bit in that byte.
*
* B. Loop over the first 8 bits of the 16 bit short.
*
* C. Test the bit.
*
* D. If it is 1, set the corresponding bit in the
* byte in the output buffer.
*
* E. If it is 0, clear the corresponding bit in the
* byte in the output buffer.
*
* F. Repeat steps C., D., and E. for the next 4
* bits of the 16 bit short.
*
* G. Write the buffer to disk.
*
*****************************************************/
short_output(out_buffer, out_file_desc, out_counter)
int *out_counter, out_file_desc;
short out_buffer[];
{
int bit_in_byte, byte_in_buffer,
i, ii, j, written;
char buff3[LENGTH3],
mask,
temp_byte,
temp_char;
union sb{
short n;
char c[sizeof(short)];
} u;
/* A. */
for(i=0; i<*out_counter; i++){
ii = i * 2;
byte_in_buffer = (ii * 3)/4;
bit_in_byte = (ii * 3) % 4;
if(bit_in_byte == 2) bit_in_byte = 4;
u.n = out_buffer[i];
/* B. */
for(j=0; j<8; j++){
temp_char = u.c[0];
temp_char = temp_char >> j;
/* C. */
if((temp_char & 0x1) != 0){ /* 1 bit */
/* D. */
mask = 0x01;
mask = mask << bit_in_byte;
temp_byte = buff3[byte_in_buffer];
temp_byte = temp_byte | mask;
buff3[byte_in_buffer] = temp_byte;
} /* ends set bit */
/* E. */
else{ /* 0 bit */
mask = 0x01;
mask = mask << bit_in_byte;
mask = ~mask;
temp_byte = buff3[byte_in_buffer];
temp_byte = temp_byte & mask;
buff3[byte_in_buffer] = temp_byte;
} /* ends clear bit */
bit_in_byte++;
if(bit_in_byte > 7){
bit_in_byte = bit_in_byte % 8;
byte_in_buffer++;
}
} /* ends j loop over 8 */
/* F. */
for(j=0; j<4; j++){
temp_char = u.c[1];
temp_char = temp_char >> j;
if((temp_char & 0x1) != 0){
mask = 0x01;
mask = mask << bit_in_byte;
temp_byte = buff3[byte_in_buffer];
temp_byte = temp_byte | mask;
buff3[byte_in_buffer] = temp_byte;
}
else{
mask = 0x01;
mask = mask << bit_in_byte;
mask = ~mask;
temp_byte = buff3[byte_in_buffer];
temp_byte = temp_byte & mask;
buff3[byte_in_buffer] = temp_byte;
}
bit_in_byte++;
if(bit_in_byte > 7){
bit_in_byte = bit_in_byte % 8;
byte_in_buffer++;
}
}
} /* ends i loop over output_counter */
/* G. */
written = write(out_file_desc, buff3, byte_in_buffer);
LZWTEST( printf("\nLZW: TEST: wrote out %d bytes",
written); )
return(written);
}
/*****************************************************
*
* is_present(...
*
* Is the string w with character k appended to it
* in the string table?
*
* A. Search the string table from the end for
* the character k.
*
* B. If k = character in string table
* then build up that string w2 and compare it
* to w. If they match you found w in the
* table.
*
* C. If k != character in string table
* then keep looking.
*
*****************************************************/
is_present(w, k, string_table)
char w[], k;
struct item string_table[];
{
int i, result, searching;
char w2[100];
w2[0] = '\0';
result = 0;
i = TABLE - 1;
searching = 1;
/* A. */
while(searching){
/* B. */
if(k == string_table[i].code_char){
build_string(w2, string_table[i].code_num, string_table);
if(strcmp(w, w2) == 0){
result = 1;
searching = 0;
} /* ends if w2 == w */
else{
i--;
w2[0] = '\0';
} /* ends else w != w2 */
} /* ends if found a match for k */
/* C. */
else{
i--;
if(i < 0){
searching = 0;
}
}
}
return(result);
}
/*****************************************************
*
* build_string(...
*
* Use the number representing a string and build
* the string of characters.
*
* A. If there is a character in the string table,
* then put that character into the front of
* the string you are building.
*
* B. If that string points to another place in the
* string table, then recusively call yourself
* to continue building the string.
*
*****************************************************/
build_string(w, number, string_table)
char w[];
short number;
struct item string_table[];
{
/* A. */
if(string_table[number].code_char != '\0'){
insert_in_front(w, string_table[number].code_char);
/* B. */
if(string_table[number].code_num != 0)
build_string(w,
string_table[number].code_num,
string_table);
}
}
/*****************************************************
*
* insert_in_front(...
*
* Insert character x into the front of string w.
*
* A. Find the end of the string w.
*
* B. Shift all of w over 1.
*
* C. Put x at the front of w.
*
*****************************************************/
insert_in_front(w, x)
char w[], x;
{
char temp;
int i, j, not_finished;
/* A. */
i = 0;
not_finished = 1;
while(not_finished){
if(w[i] == '\0')
not_finished = 0;
else
i++;
}
/* B. */
w[i+1] = '\0';
for(j=i; j>0; j--)
w[j] = w[j-1];
/* C. */
w[0] = x;
}
/*****************************************************
*
* append_to_end(...
*
* Append the character k onto the end of string w.
*
* A. Find the end of w.
*
* B. Put k onto the end.
*
*****************************************************/
append_to_end(w, k)
char w[], k;
{
int i, searching;
i = 0;
/* A. */
searching = 1;
while(searching){
if(w[i] == '\0')
searching = 0;
else
i++;
}
/* B. */
w[i] = k;
w[i+1] = '\0';
}
/*****************************************************
*
* insert_into_table
*
* Insert the string w and character k into the string
* table.
*
* A. Find the first open place in the string table.
*
* B. Find the number s in the string table which
* represents the string w.
*
* C. In the first open place in the string table
* set the character to k and the number to s.
*
*****************************************************/
insert_into_table(w, k, string_table)
char w[], k;
struct item string_table[];
{
int i, j, searching;
short s;
i = TABLE - 1;
searching = 1;
/* A. */
while(searching){
if(string_table[i].code_char != '\0')
searching = 0;
else{
i--;
if(i < 0)
printf("\nLZW: ERROR- Table full ",
"- cannot insert");
}
}
/* B. */
find_string(w, string_table, &s);
/* C. */
string_table[i+1].code_num = s;
string_table[i+1].code_char = k;
LZWTEST( printf("\nLZW: TEST: inserted string %d",s);)
LZWTEST( printf(" and char %c into table", k); )
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -