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