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 + -
显示快捷键?