1 /*	$Id$ */
2 /*
3  * Copyright (c) 1994-1996 Sam Leffler
4  * Copyright (c) 1994-1996 Silicon Graphics, Inc.
5  * HylaFAX is a trademark of Silicon Graphics
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  *
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  */
26 #ifndef _G3Decoder_
27 #define _G3Decoder_
28 /*
29  * Group 3 Facsimile Decoder Support.
30  */
31 #include "Types.h"
32 extern "C" {
33 #include <setjmp.h>
34 }
35 #include "tiffio.h"
36 
37 class G3Decoder {
38 private:
39     bool	is2D;		// whether or not data is 2d-encoded
40     bool	isG4;		// whether or not data is MMR
41     uint32	data;		// current input/output byte
42     int		bit;		// current bit in input/output byte
43     int		EOLcnt;		// EOL code recognized during decoding (1/0)
44     int		RTCrun;		// count of consecutive zero-length rows
45     int		rowref;		// reference count of rows decoded
46     int		RTCrow;		// row number of start of RTC
47     int		decoderFd;	// file descriptor for decoding pipe (ECM)
48     bool	isECM;		// whether to read input data from the modem or the pipe
49     tiff_runlen_t*	refruns;	// runs for reference line
50     tiff_runlen_t*	curruns;	// runs for current line
51     const u_char* bitmap;	// bit reversal table
52 protected:
53     G3Decoder();
54 
55     void	raiseEOF();
56     void	raiseRTC();
57 
58     const u_char* getBitmap();
59 
60     virtual int nextByte();
61     virtual int decodeNextByte();
62 
63     virtual void invalidCode(const char* type, int x);
64     virtual void badPixelCount(const char* type, int got, int expected);
65     virtual void badDecodingState(const char* type, int x);
66 public:
67     // XXX these should be private; see below for why they're public
68     sigjmp_buf	jmpEOF;		// non-local goto on EOF
69     sigjmp_buf	jmpRTC;		// non-local goto on RTC
70 
71     virtual ~G3Decoder();
72 
73     void	setupDecoder(u_int fillorder, bool is2D, bool isG4);
74     void	setRuns(tiff_runlen_t*, tiff_runlen_t*, int);
75     tiff_runlen_t*	lastRuns();
76 
77     void	decode(void* raster, u_int w, u_int h);
78     bool	decodeRow(void* scanline, u_int w);
79     bool	isNextRow1D();
80 
81     int		getPendingBits() const;
82 
83     bool	seenRTC() const;
84     int		getRTCRow() const;
85     int		getReferenceRow() const;
86 
87     int		getDecoderFd() const;
88     void	setDecoderFd(int);
89     bool	getIsECM() const;
90     void	setIsECM(bool);
91 };
92 
93 /*
94  * NB: These should be inline public methods but because we
95  *     cannot depend on the compiler actually doing the inline
96  *     we use #defines instead--if the sigsetjmp is done in
97  *     the context of an out-of-line routine, then the saved
98  *     frame pointer, pc, etc. will be wrong.
99  */
100 #define	EOFraised()		(sigsetjmp(jmpEOF, 0) != 0)
101 #define	RTCraised()		(sigsetjmp(jmpRTC, 0) != 0)
102 
lastRuns()103 inline tiff_runlen_t* G3Decoder::lastRuns()	{ return is2D ? refruns : curruns; }
getBitmap()104 inline const u_char* G3Decoder::getBitmap()	{ return bitmap; }
getPendingBits()105 inline int G3Decoder::getPendingBits() const	{ return bit; }
seenRTC()106 inline bool G3Decoder::seenRTC() const		{ return (RTCrow != -1); }
getRTCRow()107 inline int G3Decoder::getRTCRow() const		{ return RTCrow; }
getReferenceRow()108 inline int G3Decoder::getReferenceRow() const	{ return rowref; }
getDecoderFd()109 inline int G3Decoder::getDecoderFd() const	{ return decoderFd; }
setDecoderFd(int fd)110 inline void G3Decoder::setDecoderFd(int fd)	{ decoderFd = fd; }
getIsECM()111 inline bool G3Decoder::getIsECM() const		{ return isECM; }
setIsECM(bool ecm)112 inline void G3Decoder::setIsECM(bool ecm)	{ isECM = ecm; }
113 #endif /* _G3Decoder_ */
114