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