encode.c
来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 673 行 · 第 1/2 页
C
673 行
/* encode.c - implement encoding routines */#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/quipu/photo/RCS/encode.c,v 9.0 1992/06/16 12:43:35 isode Rel $";#endif/* * $Header: /xtel/isode/isode/others/quipu/photo/RCS/encode.c,v 9.0 1992/06/16 12:43:35 isode Rel $ * * * $Log: encode.c,v $ * Revision 9.0 1992/06/16 12:43:35 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 "quipu/photo.h"#include "general.h"extern int PIC_LINESIZE,STOP,NUMLINES;int a0, a1, b1, b2; /* markers */int optlen;/* * G3-Fax nonbasic parameters. */int twoDimensional = 0;int fineResolution = 1;int unlimitedLength = 0;int b4Length = 0;int a3Width = 0;int b4Width = 0;int uncompressed = 0;int standardwidth = 0;int forcesize = 0;/* encoding format options */int nopreamble = 0;int oldformat = 0;/* ROUTINE: encode_t4/*/* SYNOPSIS: Implements CCITT recommendation T.4./* This recomendation is concerned with compressing of bit maps./*/* DESCRIPTION:/* This routine sets up the data buffers, then calls routines/* to encode one line of the bit map. A line can be encoded either one/* dimensionally or two dimensionally depending upon the 'k parameter'./*/* When a line is encoded two dimensionally, the line before is used as a/* reference. For each line encoded, a record of where the run changes occur/* are kept. This is the used as the reference./**/char * encode_t4 (k_param, inbuf, eolnskip)int k_param;char * inbuf;int eolnskip;{ bit_string ref_line; /* Reference line */ bit_string t4_line; /* Output encoded line */ bit_string code_line; /* Line we are codeing */ short i,j; /* Loop variable */ int run_buf [LINEBUF], run_buf2 [LINEBUF]; if (a3Width) forcesize = 2432; if (b4Width) forcesize = 2048; if (standardwidth) forcesize = 1728; if (k_param > 1) twoDimensional = 1; ref_line.run_top = run_buf; code_line.run_top = run_buf2; code_line.dbuf_top = inbuf; t4_line.dbuf_top = malloc ((unsigned int)((PIC_LINESIZE * NUMLINES) + 28)); set_input (&code_line); set_output (&t4_line); /* Repeat this loop once for every input line expected */ for (i = 0; i < NUMLINES; i++) { if (code_line.run_top == run_buf) { /*swap buffers*/ ref_line.run_top = run_buf; code_line.run_top = run_buf2; } else { ref_line.run_top = run_buf2; code_line.run_top = run_buf; } /* reset pointers */ code_line.run_pos = code_line.run_top; ref_line.run_pos = ref_line.run_top; /* fill buffer for coding line */ get_runs (&code_line); code_line.run_pos = code_line.run_top; put_eoln (&t4_line); if (k_param > 1) { if (i % k_param == 0) { set_bit (&t4_line); /* tag bit, 1-d line follows */ code_one (&code_line, &t4_line); } else { clr_bit (&t4_line); /* tag bit, 2-d line follows */ code_two (&ref_line, &code_line, &t4_line); } } else code_one (&code_line, &t4_line); /* skip any extra eoln bit in orig data */ for (j = 0; j < eolnskip; j++) (void) get_bit (&code_line); } /* now finish with 6 EOL's, as per T.4 */ for (i = 0; i < 5; ++i) { put_eoln (&t4_line); if (k_param > 1) set_bit (&t4_line); } /* flush buffers, write preamble */ flush_output (&t4_line); return (t4_line.dbuf_top);}/* ROUTINE: code_one/*/* SYNOPSIS: codes one line of a bit map into t4/*/* DESCRIPTION:/* To encode a line one dimensionally, bits are read in until/* a change is noticed, when this happens, the run_length code for the number/* of bits read in is found, and written to the output file./*/* A run_length code may consist of two parts if the run is large, a make up/* and a terminal code.*/code_one (lineptr,t4_lineptr)bit_string * lineptr; /* input line */bit_string * t4_lineptr; /* output line */{ char colour = WHITE; /* the colour of the current bit */ full_code code; /* the code for the characters run_length */ int old_pos = 1; /* the number of bits of the same colur read in */ int len = 0; int tlen; if (forcesize) { len = (forcesize - PIC_LINESIZE)/ 2; code = get_code ( len, WHITE); if (code.make.length != 0) put_code (t4_lineptr,code.make); /* the make code */ put_code (t4_lineptr, code.term); /* the terminal code */ code = get_code (0,BLACK); put_code (t4_lineptr, code.term); } do { /* get code for next run = pos of current change - pos of last change */ tlen = *++lineptr->run_pos - old_pos; len += tlen; code = get_code (tlen,colour); if (code.make.length != 0) put_code (t4_lineptr,code.make); /* the make code */ put_code (t4_lineptr, code.term); /* the terminal code */ colour = 1 - colour; old_pos = *lineptr->run_pos; } while (*lineptr->run_pos <= PIC_LINESIZE); if (forcesize) { if (colour == BLACK) { code = get_code (0,colour); put_code (t4_lineptr, code.term); } colour = 1 - colour; code = get_code ( forcesize - len, colour); if (code.make.length != 0) put_code (t4_lineptr,code.make); /* the make code */ put_code (t4_lineptr, code.term); /* the terminal code */ }}/* ROUTINE: code_two/*/* SYNOPSIS: Codes one line of a bit map two dimensionally as/* described by CCITT T.4./*/* DESCRIPTION: Two lines are compared by looking at the list of run changes./* In order to do this, this list has to be created for the line we are about/* to encode. The encoding procedure then follows the flow chart in the CCITT/* recommendation. This is summarised as follows:/*/* 1. Find the positions a0, a1, b1, b2./* 2. Compare to see which mode is required./*/* The positions of a1, b1, b2 are found from the run change list. a0 is known/* in advance.*/code_two (ref_lineptr,code_lineptr,t4_lineptr)bit_string * ref_lineptr; /* reference line */bit_string * code_lineptr; /* line to encode */bit_string * t4_lineptr; /* output line */{ char colour = WHITE; char ref_colour = WHITE; a0 = 0; code_lineptr->run_pos = code_lineptr->run_top; do { /* find a1 */ while (*code_lineptr->run_pos > a0) --code_lineptr->run_pos; while (*code_lineptr->run_pos <= a0 && *code_lineptr->run_pos < STOP) ++code_lineptr->run_pos; a1 = *code_lineptr->run_pos; /* find b1 and b2 */ while (*ref_lineptr->run_pos > a0) { ref_colour = 1 - ref_colour; --ref_lineptr->run_pos; } while (*ref_lineptr->run_pos <= a0 && *ref_lineptr->run_pos < STOP ) { ref_colour = 1 - ref_colour; ++ref_lineptr->run_pos; } if (ref_colour == colour && *ref_lineptr->run_pos < STOP) { ref_lineptr->run_pos++; ref_colour = 1 - ref_colour; } b1 = *ref_lineptr->run_pos; if (b1 >= STOP) b2 = STOP; else b2 = *(ref_lineptr->run_pos + 1); /* select mode and code it */ if (a1 > b2) { pass_mode (t4_lineptr); } else if (abs (a1 - b1) <= 3) { vertical_mode (t4_lineptr); colour = 1 - colour; } else horizontal_mode (code_lineptr,t4_lineptr,colour); } while (a0 < STOP);}/* ROUTINE: Pass_mode/*/* SYNOPSIS: Encodes pass_mode/*/* DESCRIPTION: When pass mode is detected, the pass mode code is written to/* the output, and a0 is moved to underneath b2.*/pass_mode (t4_lineptr)bit_string * t4_lineptr;{ static code_word code = {4,0x0200}; put_code (t4_lineptr,code); a0 = b2;}/* ROUTINE: Vertical_mode/*/* SYNOPSIS: Encodes vertical mode./*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?