photo_dec.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 967 行 · 第 1/2 页
C
967 行
return (done);}/* ROUTINE: decode_two/*/* SYNOPSIS: decodes a two dim line./*/* DESCRIPTION: The binary codes read in are looked up in the decode tree,/* and the appropiate routine called to decode that mode./*/* RETURNS: 0 if successful/* -1 if too many sequencing errors/* -2 if resynch performed*/decode_two (ref_lineptr, code_lineptr, t4_lineptr)bit_string * ref_lineptr;bit_string * code_lineptr;bit_string * t4_lineptr;{ int length; node * ptr; int status; ref_lineptr->run_pos = ref_lineptr->run_top; code_lineptr->run_pos = code_lineptr->run_top; colour = WHITE; ref_colour = BLACK; do { ptr = find_node (t4_lineptr, two_tree_top); if (ptr == NULL) { if (++seqerrs < 10) { resync (t4_lineptr); return (-2); } else { (void) fputs ("decode_fax: too many sequencing errors\n", stderr); return (-1); } } switch (ptr->value) { case -1: colour = undo_uncompressed_mode (code_lineptr, t4_lineptr, colour, 1); if (colour < 0) return (colour); break; case P: undo_pass_mode (ref_lineptr, code_lineptr); break; case H: status = undo_horiz_mode (t4_lineptr, code_lineptr); if (status < 0) return (status); break; case EOLN: break; default: undo_vert_mode (ref_lineptr, code_lineptr, ptr->value); break; } } while (ptr->n_type != EOLN); /* fill to end of line with current colour */ length = (int)(PIC_LINESIZE - position + 1); if (length != 0) put_run (code_lineptr, length, colour); while (get_bit (t4_lineptr) != 1) ; /* skip fill characters */ *code_lineptr->run_pos++ = STOP; *code_lineptr->run_pos = STOP; return (0);}/* ROUTINE: undo_uncompressed_mode/*/* SYNOPSIS: decodes a section recognised as uncompressed mode./*/* DESCRIPTION: Process uncompressed code words until a terminating/* code word is found./*/* RETURNS: -1 if too many sequencing errors/* -2 if resynch performed/* else next colour*/undo_uncompressed_mode (lineptr, t4_lineptr, xcolour, twoD)bit_string * lineptr;bit_string * t4_lineptr;int xcolour;int twoD;{ int black_length; int next_colour; int white_length; int zeros; for (;;) { zeros = 0; while (get_bit(t4_lineptr) != 01) ++zeros; if (zeros > 10) { (void) fputs ("decode_fax: bad code word in uncompressed mode string\n", stderr); if (++seqerrs < 10) { resync (t4_lineptr); return (-2); } else { (void) fputs ("decode_fax: too many sequencing errors\n", stderr); return (-1); } } white_length = uc_white_pels[zeros]; black_length = uc_black_pels[zeros]; if (white_length > 0) { if (xcolour == BLACK) --lineptr->run_pos; put_run (lineptr, white_length, WHITE); xcolour = BLACK; } if (black_length > 0) { if (xcolour == WHITE) --lineptr->run_pos; put_run (lineptr, black_length, BLACK); xcolour = WHITE; } if (!twoD) PIC_LINESIZE += white_length + black_length; if (zeros >= UC_EXIT) { next_colour = (get_bit(t4_lineptr) == 01) ? BLACK : WHITE; if (next_colour != xcolour) --lineptr->run_pos; return (next_colour); } }}/* ROUTINE: undo_pass_mode/*/* SYNOPSIS: decodes a section recognised as pass mode./*/* DESCRIPTION: find b2, then write to output the same colour as before/* up until position b2.*/undo_pass_mode (ref_lineptr, code_lineptr)bit_string * ref_lineptr;bit_string * code_lineptr;{ int length; goto_b1 (ref_lineptr); if (*ref_lineptr->run_pos < STOP) { ++ref_lineptr->run_pos; ref_colour = 1 - ref_colour; } length = (int)(*ref_lineptr->run_pos - position); put_run (code_lineptr, length, colour); --code_lineptr->run_pos; /* don't count this as a change */}/* ROUTINE: undo_horiz_mode/*/* SYNOPSIS: decodes a section recognised as horizontal mode./*/* DESCRIPTION: Read two run lengths for the input, and write the appropiate/* number of 1's or 0's to the output./*/* RETURNS: 0 if successful/* -1 if too many sequencing errors/* -2 if resynch performed*/undo_horiz_mode (t4_lineptr, code_lineptr)bit_string * t4_lineptr;bit_string * code_lineptr;{ run_type run; run = next_run (t4_lineptr, colour); if (run.r_type == ERR_RUN) { if (++seqerrs < 10) { resync (t4_lineptr); return (-2); } else { (void) fputs ("decode_fax: too many sequencing errors\n", stderr); return (-1); } } put_run (code_lineptr, run.run_length, colour); run = next_run (t4_lineptr, 1 - colour); if (run.r_type == ERR_RUN) { if (++seqerrs < 10) { resync (t4_lineptr); return (-2); } else { (void) fputs ("decode_fax: too many sequencing errors\n", stderr); return (-1); } } put_run (code_lineptr, run.run_length, 1 - colour); return (0);}/* ROUTINE: undo_vert_mode/*/* SYNOPSIS: decodes vertical mode/*/* DESCRIPTION: Find b1, the write 1's or 0's upto it allowing for the offset.*/undo_vert_mode (ref_lineptr, code_lineptr, offset)bit_string * ref_lineptr;bit_string * code_lineptr;char offset;{ int length; goto_b1 (ref_lineptr); length = (*ref_lineptr->run_pos - position) + offset - FIXED_OFFSET; put_run (code_lineptr, length , colour); colour = 1 - colour;}/* ROUTINE: goto_b1 * * SYNOPSIS: move the pointer in the reference line to b1 * * DESCRIPTION: b1 is the first changing bit in the reference line * of a different colour to a0. May need to move backwards or forwards * */goto_b1 (lineptr)bit_string * lineptr;{ while (*lineptr->run_pos > position) { --lineptr->run_pos; ref_colour = 1 - ref_colour; } while (*lineptr->run_pos < position) { ++lineptr->run_pos; ref_colour = 1 - ref_colour; } if (ref_colour == colour) { ++lineptr->run_pos; ref_colour = 1 - ref_colour; } else if (*lineptr->run_pos < STOP) /* special case when b1 = a0, and the colours are different, move b1 to the next change of same colour, this must be allowed at the beginning of a line to get a run of zero, as every line must start with a white element */ if ((*lineptr->run_pos == position) && (*lineptr->run_pos > 1)) lineptr->run_pos += 2;}/* ROUTINE: resync/*/* SYNOPSIS: resynchronizes sequencing by locating the next EOL/**/static voidresync (lineptr)bit_string * lineptr;{ int i; for (;;) { while (get_bit (lineptr) == 1) ; i = 1; while (get_bit (lineptr) == 0) ++i; if (i > 10) return; }}/* ROUTINE: put_run *//* *//* SYNOPSIS: writes a run_length to the indicated bit_string. *//* */put_run (lineptr, length, xcolour)bit_string * lineptr;int length;char xcolour;{ register i; register l;/* if ( length < 0 ) { (void) fprintf (stderr, "decode_fax: WARNING - negative run length (%d) detected in line %d\n", length, NUMLINES); }*/ if ( xcolour == WHITE) photo_white (length); else photo_black (length); /* now fill line buffer for purpose of decoding 2-d lines */ if (length > 16) { l = length; if (lineptr->mask != BIT_MASK) { /* fill current byte */ if (xcolour == WHITE) do { clr_bit (lineptr); --l; } while (lineptr->mask != BIT_MASK); else do { set_bit (lineptr); --l; } while (lineptr->mask != BIT_MASK); } /* write out the bytes */ if (xcolour == WHITE) for (i = 0; i < l / 8; i++) *lineptr->dbuf++ = 0; else for (i = 0; i < l / 8; i++) *lineptr->dbuf++ = 0xff; /* put the last few bits into the next byte */ if (xcolour == WHITE) for (i = 0; i < l % 8; i++) clr_bit (lineptr); else for (i = 0; i < l % 8; i++) set_bit (lineptr); } /* length < 16 - can't optimise, so deal with bits */ else { if (xcolour == WHITE) { for (i = 0; i < length; i++) clr_bit (lineptr); } else { for (i = 0; i < length; i++) set_bit (lineptr); } } position += length; *lineptr->run_pos++ = position;}/* ROUTINE: set_doutput;/*/* SYNOPSIS: Initialises the output buffers*/set_doutput (lineptr)bit_string * lineptr;{ lineptr->dbuf = lineptr->dbuf_top; lineptr->mask = BIT_MASK;}/* ROUTINE: flush_doutput;/*/* SYNOPSIS: flush the output buffer;*/flush_doutput (lineptr)bit_string * lineptr;{int count = 0; while ( lineptr->mask != BIT_MASK ) { clr_bit (lineptr); count++; } photo_white (count);}/* ROUTINE: set_dinput;/*/* SYNOPSIS: Initialises the input buffers*/set_dinput (lineptr, length)bit_string * lineptr;int length;{ unsigned char cbyte; int count; int i; lineptr->dbuf = lineptr->dbuf_top; if (length == 0) { if (*lineptr->dbuf++ != 0x03) { (void) fputs ("decode_fax: input stream is not a BIT STRING\n", stderr); return (-1); } cbyte = *lineptr->dbuf++; if (cbyte & 0x80) { /* long form */ count = cbyte & 0x7f; if (count > 4) { (void) fputs ("decode_fax: length error\n", stderr); return (-1); } for (i = 0; i < count; ++i) ++lineptr->dbuf; } } lineptr->pos = *lineptr->dbuf++; lineptr->mask = BIT_MASK; return (0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?