photo_dec.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 967 行 · 第 1/2 页

C
967
字号
/* decode.c - the generic photo decoder */#ifndef	lintstatic char *rcsid = "$Header: /xtel/isode/isode/dsap/common/RCS/photo_dec.c,v 9.0 1992/06/16 12:12:39 isode Rel $";#endif/*  * $Header: /xtel/isode/isode/dsap/common/RCS/photo_dec.c,v 9.0 1992/06/16 12:12:39 isode Rel $ * * * $Log: photo_dec.c,v $ * Revision 9.0  1992/06/16  12:12:39  isode * Release 8.0 * *//* *				  NOTICE * *    Acquisition, use, and distribution of this module and related *    materials are subject to the restrictions of a license agreement. *    Consult the Preface in the User's Manual for the full terms of *    this agreement. * */#include <stdio.h>#include <signal.h>#include "quipu/photo.h"#include "psap.h"#define UNCOMPRESSED_1D	0x0e#define ERR_RUN		0x0f/* this file contains the main routines for decoding X400 */extern int PIC_LINESIZE, STOP, NUMLINES;/* variables for top of the code word trees */node * bl_tree_top;node * wt_tree_top;node * two_tree_top;unsigned int position;static char ref_colour;static char colour;char *bitmap;static void  resync ();static int seqerrs = 0;int decode_t4 (data, name, size)char *data;char *name;int   size;{    PE    member;    PE    pe;    PS    ps;    PE    seq;    PE    set;    int   twoDimensional = 0;    int   res;    /*     *  If the first byte does not indicate that the data is an ASN.1-encoded     *  SET or BIT STRING, attempt to convert the data as a non-ASN.1 image.     */    if ((unsigned char)*data != 0xa3 && *data != 0x03) {	if (((unsigned char)*data == 0x05) && 		((unsigned char)*(data + 1) == 0x00)) {		(void) fprintf (stderr, "NULL photo !?!");		return (-1);	}	return decode_t4_aux (data, name, (int)size, twoDimensional);    }    /* attempt to decode the source */    if ((ps = ps_alloc (str_open)) == NULLPS) {	(void) fprintf (stderr, "ps_alloc: unable to allocate presentation stream\n");	return (-1);    }    if (str_setup (ps, data, (int)size, 0) == NOTOK) {	ps_free (ps);	return -1;    }    if ((pe = ps2pe (ps)) == NULLPE) { /* maybe it's a non-ASN.1 image */	ps_free (ps);	return decode_t4_aux (data, name, (int)size, 1);    }    if (pe->pe_class == PE_CLASS_UNIV && pe->pe_form == PE_FORM_PRIM &&	pe->pe_id == PE_PRIM_BITS) { /* old  BIT STRING-like form */	if (pe_pullup (pe) == NOTOK) {	    pe_free (pe);	    ps_free (ps);	    return -1;        }	res = decode_t4_aux ((char *)pe -> pe_prim, name, ps_get_abs (pe), 1);    }    else if (pe->pe_class == PE_CLASS_CONT && pe->pe_form == PE_FORM_CONS &&	     pe->pe_id == 3) {	/* first member must be SET which describes G3-Fax options */	set = first_member (pe);	if (!set || set->pe_class != PE_CLASS_UNIV ||	    set->pe_form != PE_FORM_CONS || set->pe_id != PE_CONS_SET) {	    (void) fprintf (stderr, "decode_fax: %s is not a fax image\n", name);	    pe_free (pe);	    ps_free (ps);	    return -1;	}	for (member = first_member (set); member; member = next_member (set, member)) {	    if (member->pe_class == PE_CLASS_CONT &&		member->pe_form == PE_FORM_PRIM && member->pe_id == 1) {	        twoDimensional = bit_test (prim2bit (member), 8);		if (twoDimensional == -1) {		    pe_free (pe);		    ps_free (ps);		    return -1;	        }	    }	}	/* SEQUENCE of BIT STRING should follow SET */	seq = next_member (pe, set);	if (!seq || seq->pe_class != PE_CLASS_UNIV ||	    seq->pe_form != PE_FORM_CONS || seq->pe_id != PE_CONS_SEQ) {	    (void) fprintf (stderr, "%s: is not a fax image\n", name);	    pe_free (pe);	    ps_free (ps);	    return -1;	}	for (member = first_member (seq); member; member = next_member (seq, member)) {	    if (member->pe_class != PE_CLASS_UNIV ||		member->pe_form != PE_FORM_PRIM ||		member->pe_id != PE_PRIM_BITS) {		(void) fprintf (stderr, "%s: is not a fax image\n", name);		pe_free (pe);		ps_free (ps);		return -1;	    }	    res = decode_t4_aux ((char *)((member->pe_prim) + 1), name,			   ps_get_abs (member) - 1, twoDimensional);	}    }    else  /* maybe its a non-ASN.1 image */	res = decode_t4_aux (data, name, (int)size, 1);    pe_free (pe);    ps_free (ps);    return res;}/* *  Uncompressed mode black and white pel count tables.  These tables *  are indexed by the count of leading zeros in the uncompressed mode *  code word. */#define UC_EXIT 6static int uc_white_pels [] = {	/* image pattern     code word   */    0,	/*     1             1           */    1,	/*     01            01          */    2,	/*     001           001         */    3,	/*     0001          0001        */    4,	/*     00001         00001       */    5,	/*     00000         000001      */    0,	/*                   0000001     */    1,	/*     0             00000001    */    2,	/*     00            000000001   */    3,	/*     000           0000000001  */    4,	/*     0000          00000000001 */};static int uc_black_pels [] = {	/* image pattern     code word    */    1,	/*     1              1           */    1,	/*     01             01          */    1,	/*     001            001         */    1,	/*     0001           0001        */    1,	/*     00001          00001       */    0,	/*     00000          000001      */    0,	/*                    0000001     */    0,	/*     0              00000001    */    0,	/*     00             000000001   */    0,	/*     000            0000000001  */    0,	/*     0000           00000000001 */};/* ROUTINE:     Decode_t4/*/* SYNOPSIS:    Decodes a bit map stored in format T4 as recommended/*              by CCITT./*/* DESCRIPTION: After setting up the buffers, a line at a time is dealt with./* Each line is recognised as being one or two dimensionally coded, depending/* upon the tag bit./* The run change buffers for each line are kept incase the next line is two/* dimensionally, when it will be used as a reference./**/int decode_t4_aux (inbuf, winname, length, twoDimensional)char *inbuf;char *winname;int   length;int   twoDimensional;{   bit_string code_line,      /* output line */              ref_line,       /* reference line */              t4_line;        /* input line  */   int       done;   int	    *buffer1, *buffer2;   int      *run_buf1, *run_buf2;   char      oneDtag, tag;   seqerrs = 0;   if (photo_start (winname) == -1)	return (-1);   if (build_trees () == -1)	return (-1);   buffer1      = (int *) malloc (LINEBUF * sizeof(int));   buffer2      = (int *) malloc (LINEBUF * sizeof(int));   buffer1[0]   = 0;   /* to halt backtracting if needed at start of line */   buffer2[0]   = 0;   run_buf1     = buffer1;   run_buf2     = buffer2;   ref_line.run_top  = ++run_buf1;   code_line.run_top = ++run_buf2;   code_line.dbuf_top = malloc (BUFSIZ);   t4_line.dbuf_top = inbuf;   if (set_dinput (&t4_line, length) == -1)	return (-1);   set_doutput (&code_line);   /* images must always start with a 1-d encoded line */   position = 1;   NUMLINES = 1;   done = decode_one (&code_line, &t4_line);   if (done < 0) return (-1);   if ( !done ) { /* no leading EOL */       flush_doutput (&code_line);       set_doutput (&code_line);       photo_line_end (&code_line);   }   else { /* leading EOL */       NUMLINES = 0;       done = 0;   }   if (twoDimensional)       oneDtag = tag = get_bit(&t4_line);   while ( done != 1 ) {      ++NUMLINES;      position = 1;      if ( twoDimensional && tag != oneDtag ) {	  if (code_line.run_top  == run_buf1) {	      ref_line.run_top  = run_buf1;	      code_line.run_top = run_buf2;	  }	  else {	      ref_line.run_top  = run_buf2;	      code_line.run_top = run_buf1;	  }	  done = decode_two (&ref_line, &code_line, &t4_line);      }      else {	  done = decode_one (&code_line, &t4_line);      }      if (done == -1) return (-1);      flush_doutput (&code_line);      set_doutput (&code_line);      photo_line_end (&code_line);      if ( twoDimensional && done != 1 )	  tag = get_bit (&t4_line);      if ( done == -2 && twoDimensional ) {	  while ( tag != oneDtag ) {	      resync (&t4_line);	      tag = get_bit (&t4_line);	  }      }   }   bitmap = code_line.dbuf_top;   (void) free ((char *)buffer1);   (void) free ((char *)buffer2);	   return (photo_end (winname));}/* ROUTINE:     find_node * * SYNOPSIS:    Reads a sequence of bits from a source line and traverses *              a code word tree to find a matching code word. */static node *find_node (lineptr, tree_top)bit_string * lineptr;node * tree_top;{   node * ptr;   ptr = tree_top;   do {      if (get_bit (lineptr) == 0) {	  ptr = ptr->zero;      }      else {	  ptr = ptr->one;      }      if (ptr == NULL) {	  (void) fprintf (stderr,			  "decode_fax: WARNING - sequencing error in line %d\n",			  NUMLINES);	  return (NULL);      }   } while (ptr->n_type == INTERNAL);   return (ptr);}/* ROUTINE:     next_run * * SYNOPSIS:    Reads the next run length from the input file. * * DESCRIPTION: As each bit is read, it is used to move down the decode tree, * when a node is found that contains a value, the value is returned. * The code is assumed to be one dimensional.*/run_typenext_run (lineptr,xcolour)bit_string * lineptr;char    xcolour;{   node *   ptr;   run_type result;   result.run_length = 0;   if (xcolour == BLACK)      ptr = find_node (lineptr, bl_tree_top);   else      ptr = find_node (lineptr, wt_tree_top);         if (ptr == NULL) {       result.r_type = ERR_RUN;       return (result);   }   /* if the above value was a make up code, now read the terminal code */   if (ptr->n_type == MAKE) {        if (ptr->value == -1) {	    result.r_type = UNCOMPRESSED_1D;	    return (result);	}	result.run_length = ptr->value;	if (xcolour == BLACK)	    ptr = find_node (lineptr, bl_tree_top);	else	    ptr = find_node (lineptr, wt_tree_top);	if (ptr == NULL) {	    result.r_type = ERR_RUN;	    return (result);        }    }    result.run_length += ptr->value;    result.r_type = ptr->n_type;    return (result);}/* ROUTINE:     decode_one/*/* SYNOPSIS:    decodes one line of t4./*/* DESCRIPTION: reads a run, then writes that many bits of the appropiate/* colour to the output./*/* RETURNS:     0 if successful/*              1 if successful and end of page detected/*             -1 if line could not be decoded/*             -2 if error detected and resync succeeded*/decode_one (lineptr, t4_lineptr)bit_string * lineptr;bit_string * t4_lineptr;{   run_type run;   char xcolour = WHITE;   int  done;   int  savelinesize;   lineptr->run_pos = lineptr->run_top;   savelinesize = PIC_LINESIZE;   PIC_LINESIZE = 0;   for (;;) {       run = next_run (t4_lineptr, xcolour);       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);           }       }       else if (run.r_type == UNCOMPRESSED_1D) {	   xcolour = undo_uncompressed_mode (lineptr, t4_lineptr, xcolour, 0);	   if (xcolour == -1) return (-1);       }       else if (run.r_type == EOLN) {	   break;       }       else {	   PIC_LINESIZE += run.run_length;	   put_run (lineptr, run.run_length, xcolour);	   xcolour = 1 - xcolour;       }   }   while (get_bit(t4_lineptr) != 01)       ; /* skip fill characters */   if (lineptr->run_pos == lineptr->run_top){	done = 1;	PIC_LINESIZE = savelinesize;   }   else	done = 0;   STOP = PIC_LINESIZE + 1;   *lineptr->run_pos++ = STOP;   *lineptr->run_pos   = STOP;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?