/* * Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiffiop.h" #ifdef CCITT_SUPPORT /* * TIFF Library. * * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support. * * This file contains support for decoding and encoding TIFF * compression algorithms 2, 3, 4, and 32771. * * Decoder support is derived, with permission, from the code * in Frank Cringle's viewfax program; * Copyright (C) 1990, 1995 Frank D. Cringle. */ #include "tif_fax3.h" #define G3CODES #include "t4.h" #include <stdio.h> /* * Compression+decompression state blocks are * derived from this ``base state'' block. */ Fax3BaseState; #define Fax3State(tif) … Ttag; Fax3CodecState; #define DecoderState(tif) … #define EncoderState(tif) … #define is2DEncoding(sp) … #define isAligned(p, t) … /* * Group 3 and Group 4 Decoding. */ /* * These macros glue the TIFF library state to * the state expected by Frank's decoder. */ #define DECLARE_STATE(tif, sp, mod) … #define DECLARE_STATE_2D(tif, sp, mod) … #define CACHE_STATE(tif, sp) … /* * Save state possibly changed during decoding. */ #define UNCACHE_STATE(tif, sp) … /* * Setup state for decoding a strip. */ static int Fax3PreDecode(TIFF *tif, uint16_t s) { … } /* * Routine for handling various errors/conditions. * Note how they are "glued into the decoder" by * overriding the definitions used by the decoder. */ static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line, uint32_t a0) { … } #define unexpected(table, a0) … static void Fax3Extension(const char *module, TIFF *tif, uint32_t line, uint32_t a0) { … } #define extension(a0) … static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line, uint32_t a0, uint32_t lastx) { … } #define badlength(a0, lastx) … static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line, uint32_t a0) { … } #define prematureEOF(a0) … #define Nop /** * Decode the requested amount of G3 1D-encoded data. * @param buf destination buffer * @param occ available bytes in destination buffer * @param s number of planes (ignored) * @returns 1 for success, -1 in case of error */ static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { … } #define SWAP … /* * Decode the requested amount of G3 2D-encoded data. */ static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { … } #undef SWAP #define FILL … #define ZERO … /* * Bit-fill a row according to the white/black * runs generated during G3/G4 decoding. */ void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, uint32_t lastx) { … } #undef ZERO #undef FILL static int Fax3FixupTags(TIFF *tif) { … } /* * Setup G3/G4-related compression/decompression state * before data is processed. This routine is called once * per image -- it sets up different state based on whether * or not decoding or encoding is being done and whether * 1D- or 2D-encoded data is involved. */ static int Fax3SetupState(TIFF *tif) { … } /* * CCITT Group 3 FAX Encoding. */ #define Fax3FlushBits(tif, sp) … #define _FlushBits(tif) … static const int _msbmask[9] = …; #define _PutBits(tif, bits, length) … /* * Write a variable-length bit-value to * the output stream. Values are * assumed to be at most 16 bits. */ static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length) { … } /* * Write a code to the output stream. */ #define putcode(tif, te) … #ifdef FAX3_DEBUG #define DEBUG_COLOR … #define DEBUG_PRINT … #endif /* * Write the sequence of codes that describes * the specified span of zero's or one's. The * appropriate table that holds the make-up and * terminating codes is supplied. */ static int putspan(TIFF *tif, int32_t span, const tableentry *tab) { … } /* * Write an EOL code to the output stream. The zero-fill * logic for byte-aligning encoded scanlines is handled * here. We also handle writing the tag bit for the next * scanline when doing 2d encoding. */ static int Fax3PutEOL(TIFF *tif) { … } /* * Reset encoding state at the start of a strip. */ static int Fax3PreEncode(TIFF *tif, uint16_t s) { … } static const unsigned char zeroruns[256] = …; static const unsigned char oneruns[256] = …; /* * Find a span of ones or zeros using the supplied * table. The ``base'' of the bit string is supplied * along with the start+end bit indices. */ static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be) { … } static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be) { … } /* * Return the offset of the next bit in the range * [bs..be] that is different from the specified * color. The end, be, is returned if no such bit * exists. */ #define finddiff(_cp, _bs, _be, _color) … /* * Like finddiff, but also check the starting bit * against the end in case start > end. */ #define finddiff2(_cp, _bs, _be, _color) … /* * 1d-encode a row of pixels. The encoding is * a sequence of all-white or all-black spans * of pixels encoded with Huffman codes. */ static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits) { … } static const tableentry horizcode = …; /* 001 */ static const tableentry passcode = …; /* 0001 */ static const tableentry vcodes[7] = …; /* * 2d-encode a row of pixels. Consult the CCITT * documentation for the algorithm. */ static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp, uint32_t bits) { … } /* * Encode a buffer of pixels. */ static int Fax3Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { … } static int Fax3PostEncode(TIFF *tif) { … } static int _Fax3Close(TIFF *tif) { … } static void Fax3Close(TIFF *tif) { … } static void Fax3Cleanup(TIFF *tif) { … } #define FIELD_BADFAXLINES … #define FIELD_CLEANFAXDATA … #define FIELD_BADFAXRUN … #define FIELD_OPTIONS … static const TIFFField faxFields[] = …; static const TIFFField fax3Fields[] = …; static const TIFFField fax4Fields[] = …; static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap) { … } static int Fax3VGetField(TIFF *tif, uint32_t tag, va_list ap) { … } static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags) { … } static int InitCCITTFax3(TIFF *tif) { … } int TIFFInitCCITTFax3(TIFF *tif, int scheme) { … } /* * CCITT Group 4 (T.6) Facsimile-compatible * Compression Scheme Support. */ #define SWAP … /* * Decode the requested amount of G4-encoded data. */ static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { … } #undef SWAP /* * Encode the requested amount of data. */ static int Fax4Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { … } static int Fax4PostEncode(TIFF *tif) { … } int TIFFInitCCITTFax4(TIFF *tif, int scheme) { … } /* * CCITT Group 3 1-D Modified Huffman RLE Compression Support. * (Compression algorithms 2 and 32771) */ /* * Decode the requested amount of RLE-encoded data. */ static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { … } int TIFFInitCCITTRLE(TIFF *tif, int scheme) { … } int TIFFInitCCITTRLEW(TIFF *tif, int scheme) { … } #endif /* CCITT_SUPPORT */