// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:generate go run gen.go

// Package ccitt implements a CCITT (fax) image decoder.
package ccitt import ( ) var ( errIncompleteCode = errors.New("ccitt: incomplete code") errInvalidBounds = errors.New("ccitt: invalid bounds") errInvalidCode = errors.New("ccitt: invalid code") errInvalidMode = errors.New("ccitt: invalid mode") errInvalidOffset = errors.New("ccitt: invalid offset") errMissingEOL = errors.New("ccitt: missing End-of-Line") errRunLengthOverflowsWidth = errors.New("ccitt: run length overflows width") errRunLengthTooLong = errors.New("ccitt: run length too long") errUnsupportedMode = errors.New("ccitt: unsupported mode") errUnsupportedSubFormat = errors.New("ccitt: unsupported sub-format") errUnsupportedWidth = errors.New("ccitt: unsupported width") ) // Order specifies the bit ordering in a CCITT data stream. type Order uint32 const ( // LSB means Least Significant Bits first. LSB Order = iota // MSB means Most Significant Bits first. MSB ) // SubFormat represents that the CCITT format consists of a number of // sub-formats. Decoding or encoding a CCITT data stream requires knowing the // sub-format context. It is not represented in the data stream per se. type SubFormat uint32 const ( Group3 SubFormat = iota Group4 ) // AutoDetectHeight is passed as the height argument to NewReader to indicate // that the image height (the number of rows) is not known in advance. const AutoDetectHeight = -1 // Options are optional parameters. type Options struct { // Align means that some variable-bit-width codes are byte-aligned. Align bool // Invert means that black is the 1 bit or 0xFF byte, and white is 0. Invert bool } // maxWidth is the maximum (inclusive) supported width. This is a limitation of // this implementation, to guard against integer overflow, and not anything // inherent to the CCITT format. const maxWidth = 1 << 20 func invertBytes( []byte) { for , := range { [] = ^ } } func reverseBitsWithinBytes( []byte) { for , := range { [] = bits.Reverse8() } } // highBits writes to dst (1 bit per pixel, most significant bit first) the // high (0x80) bits from src (1 byte per pixel). It returns the number of bytes // written and read such that dst[:d] is the packed form of src[:s]. // // For example, if src starts with the 8 bytes [0x7D, 0x7E, 0x7F, 0x80, 0x81, // 0x82, 0x00, 0xFF] then 0x1D will be written to dst[0]. // // If src has (8 * len(dst)) or more bytes then only len(dst) bytes are // written, (8 * len(dst)) bytes are read, and invert is ignored. // // Otherwise, if len(src) is not a multiple of 8 then the final byte written to // dst is padded with 1 bits (if invert is true) or 0 bits. If inverted, the 1s // are typically temporary, e.g. they will be flipped back to 0s by an // invertBytes call in the highBits caller, reader.Read. func highBits( []byte, []byte, bool) ( int, int) { // Pack as many complete groups of 8 src bytes as we can. := len() / 8 if > len() { = len() } := [:] for := range { := [*8 : *8+8] [] = (([0] & 0x80) >> 0) | (([1] & 0x80) >> 1) | (([2] & 0x80) >> 2) | (([3] & 0x80) >> 3) | (([4] & 0x80) >> 4) | (([5] & 0x80) >> 5) | (([6] & 0x80) >> 6) | (([7] & 0x80) >> 7) } , = , 8* , = [:], [:] // Pack up to 7 remaining src bytes, if there's room in dst. if (len() > 0) && (len() > 0) { := byte(0) if { = 0xFF >> uint(len()) } for , := range { |= ( & 0x80) >> uint() } [0] = , = +1, +len() } return , } type bitReader struct { r io.Reader // readErr is the error returned from the most recent r.Read call. As the // io.Reader documentation says, when r.Read returns (n, err), "always // process the n > 0 bytes returned before considering the error err". readErr error // order is whether to process r's bytes LSB first or MSB first. order Order // The high nBits bits of the bits field hold upcoming bits in MSB order. bits uint64 nBits uint32 // bytes[br:bw] holds bytes read from r but not yet loaded into bits. br uint32 bw uint32 bytes [1024]uint8 } func ( *bitReader) () { := .nBits & 7 .bits <<= .nBits -= } // nextBitMaxNBits is the maximum possible value of bitReader.nBits after a // bitReader.nextBit call, provided that bitReader.nBits was not more than this // value before that call. // // Note that the decode function can unread bits, which can temporarily set the // bitReader.nBits value above nextBitMaxNBits. const nextBitMaxNBits = 31 func ( *bitReader) () (uint64, error) { for { if .nBits > 0 { := .bits >> 63 .bits <<= 1 .nBits-- return , nil } if := .bw - .br; >= 4 { // Read 32 bits, even though b.bits is a uint64, since the decode // function may need to unread up to maxCodeLength bits, putting // them back in the remaining (64 - 32) bits. TestMaxCodeLength // checks that the generated maxCodeLength constant fits. // // If changing the Uint32 call, also change nextBitMaxNBits. .bits = uint64(binary.BigEndian.Uint32(.bytes[.br:])) << 32 .br += 4 .nBits = 32 continue } else if > 0 { .bits = uint64(.bytes[.br]) << (7 * 8) .br++ .nBits = 8 continue } if .readErr != nil { return 0, .readErr } , := .r.Read(.bytes[:]) .br = 0 .bw = uint32() .readErr = if .order != MSB { reverseBitsWithinBytes(.bytes[:.bw]) } } } func decode( *bitReader, [][2]int16) (uint32, error) { , , := uint32(0), uint64(0), int32(1) for { , := .nextBit() if != nil { if == io.EOF { = errIncompleteCode } return 0, } |= << (63 - ) ++ // The "&1" is redundant, but can eliminate a bounds check. = int32([][&1]) if < 0 { return uint32(^), nil } else if == 0 { // Unread the bits we've read, then return errInvalidCode. .bits = (.bits >> ) | .nBits += return 0, errInvalidCode } } } // decodeEOL decodes the 12-bit EOL code 0000_0000_0001. func decodeEOL( *bitReader) error { , := uint32(0), uint64(0) for { , := .nextBit() if != nil { if == io.EOF { = errMissingEOL } return } |= << (63 - ) ++ if < 12 { if &1 == 0 { continue } } else if &1 != 0 { return nil } // Unread the bits we've read, then return errMissingEOL. .bits = (.bits >> ) | .nBits += return errMissingEOL } } type reader struct { br bitReader subFormat SubFormat // width is the image width in pixels. width int // rowsRemaining starts at the image height in pixels, when the reader is // driven through the io.Reader interface, and decrements to zero as rows // are decoded. Alternatively, it may be negative if the image height is // not known in advance at the time of the NewReader call. // // When driven through DecodeIntoGray, this field is unused. rowsRemaining int // curr and prev hold the current and previous rows. Each element is either // 0x00 (black) or 0xFF (white). // // prev may be nil, when processing the first row. curr []byte prev []byte // ri is the read index. curr[:ri] are those bytes of curr that have been // passed along via the Read method. // // When the reader is driven through DecodeIntoGray, instead of through the // io.Reader interface, this field is unused. ri int // wi is the write index. curr[:wi] are those bytes of curr that have // already been decoded via the decodeRow method. // // What this implementation calls wi is roughly equivalent to what the spec // calls the a0 index. wi int // These fields are copied from the *Options (which may be nil). align bool invert bool // atStartOfRow is whether we have just started the row. Some parts of the // spec say to treat this situation as if "wi = -1". atStartOfRow bool // penColorIsWhite is whether the next run is black or white. penColorIsWhite bool // seenStartOfImage is whether we've called the startDecode method. seenStartOfImage bool // truncated is whether the input is missing the final 6 consecutive EOL's // (for Group3) or 2 consecutive EOL's (for Group4). Omitting that trailer // (but otherwise padding to a byte boundary, with either all 0 bits or all // 1 bits) is invalid according to the spec, but happens in practice when // exporting from Adobe Acrobat to TIFF + CCITT. This package silently // ignores the format error for CCITT input that has been truncated in that // fashion, returning the full decoded image. // // Detecting trailer truncation (just after the final row of pixels) // requires knowing which row is the final row, and therefore does not // trigger if the image height is not known in advance. truncated bool // readErr is a sticky error for the Read method. readErr error } func ( *reader) ( []byte) (int, error) { if .readErr != nil { return 0, .readErr } := for len() > 0 { // Allocate buffers (and decode any start-of-image codes), if // processing the first or second row. if .curr == nil { if !.seenStartOfImage { if .readErr = .startDecode(); .readErr != nil { break } .atStartOfRow = true } .curr = make([]byte, .width) } // Decode the next row, if necessary. if .atStartOfRow { if .rowsRemaining < 0 { // We do not know the image height in advance. See if the next // code is an EOL. If it is, it is consumed. If it isn't, the // bitReader shouldn't advance along the bit stream, and we // simply decode another row of pixel data. // // For the Group4 subFormat, we may need to align to a byte // boundary. For the Group3 subFormat, the previous z.decodeRow // call (or z.startDecode call) has already consumed one of the // 6 consecutive EOL's. The next EOL is actually the second of // 6, in the middle, and we shouldn't align at that point. if .align && (.subFormat == Group4) { .br.alignToByteBoundary() } if := .decodeEOL(); == errMissingEOL { // No-op. It's another row of pixel data. } else if != nil { .readErr = break } else { if .readErr = .finishDecode(true); .readErr != nil { break } .readErr = io.EOF break } } else if .rowsRemaining == 0 { // We do know the image height in advance, and we have already // decoded exactly that many rows. if .readErr = .finishDecode(false); .readErr != nil { break } .readErr = io.EOF break } else { .rowsRemaining-- } if .readErr = .decodeRow(.rowsRemaining == 0); .readErr != nil { break } } // Pack from z.curr (1 byte per pixel) to p (1 bit per pixel). , := highBits(, .curr[.ri:], .invert) = [:] .ri += // Prepare to decode the next row, if necessary. if .ri == len(.curr) { .ri, .curr, .prev = 0, .prev, .curr .atStartOfRow = true } } := len() - len() if .invert { invertBytes([:]) } return , .readErr } func ( *reader) () byte { if .penColorIsWhite { return 0xFF } return 0x00 } func ( *reader) () error { switch .subFormat { case Group3: if := .decodeEOL(); != nil { return } case Group4: // No-op. default: return errUnsupportedSubFormat } .seenStartOfImage = true return nil } func ( *reader) ( bool) error { := 0 switch .subFormat { case Group3: if .truncated { return nil } // The stream ends with a RTC (Return To Control) of 6 consecutive // EOL's, but we should have already just seen an EOL, either in // z.startDecode (for a zero-height image) or in z.decodeRow. = 5 case Group4: := .rowsRemaining < 0 if { // Aligning to a byte boundary was already handled by reader.Read. } else if .align { .br.alignToByteBoundary() } // The stream ends with two EOL's. If the first one is missing, and we // had an explicit image height, we just assume that the trailing two // EOL's were truncated and return a nil error. if := .decodeEOL(); != nil { if ( == errMissingEOL) && ! { .truncated = true return nil } return } = 1 default: return errUnsupportedSubFormat } if { -- } for ; > 0; -- { if := .decodeEOL(); != nil { return } } return nil } func ( *reader) () error { return decodeEOL(&.br) } func ( *reader) ( bool) error { .wi = 0 .atStartOfRow = true .penColorIsWhite = true if .align { .br.alignToByteBoundary() } switch .subFormat { case Group3: for ; .wi < len(.curr); .atStartOfRow = false { if := .decodeRun(); != nil { return } } := .decodeEOL() if && ( == errMissingEOL) { .truncated = true return nil } return case Group4: for ; .wi < len(.curr); .atStartOfRow = false { , := decode(&.br, modeDecodeTable[:]) if != nil { return } := readerMode{} if < uint32(len(readerModes)) { = readerModes[] } if .function == nil { return errInvalidMode } if := .function(, .arg); != nil { return } } return nil } return errUnsupportedSubFormat } func ( *reader) () error { := blackDecodeTable[:] if .penColorIsWhite { = whiteDecodeTable[:] } := 0 for { , := decode(&.br, ) if != nil { return } if > maxWidth { panic("unreachable") } += int() if > maxWidth { return errRunLengthTooLong } // Anything 0x3F or below is a terminal code. if <= 0x3F { break } } if > (len(.curr) - .wi) { return errRunLengthOverflowsWidth } := .curr[.wi : .wi+] := .penColor() for := range { [] = } .wi += .penColorIsWhite = !.penColorIsWhite return nil } // The various modes' semantics are based on determining a row of pixels' // "changing elements": those pixels whose color differs from the one on its // immediate left. // // The row above the first row is implicitly all white. Similarly, the column // to the left of the first column is implicitly all white. // // For example, here's Figure 1 in "ITU-T Recommendation T.6", where the // current and previous rows contain black (B) and white (w) pixels. The a? // indexes point into curr, the b? indexes point into prev. // // b1 b2 // v v // prev: BBBBBwwwwwBBBwwwww // curr: BBBwwwwwBBBBBBwwww // ^ ^ ^ // a0 a1 a2 // // a0 is the "reference element" or current decoder position, roughly // equivalent to what this implementation calls reader.wi. // // a1 is the next changing element to the right of a0, on the "coding line" // (the current row). // // a2 is the next changing element to the right of a1, again on curr. // // b1 is the first changing element on the "reference line" (the previous row) // to the right of a0 and of opposite color to a0. // // b2 is the next changing element to the right of b1, again on prev. // // The various modes calculate a1 (and a2, for modeH): // - modePass calculates that a1 is at or to the right of b2. // - modeH calculates a1 and a2 without considering b1 or b2. // - modeV* calculates a1 to be b1 plus an adjustment (between -3 and +3). const ( findB1 = false findB2 = true ) // findB finds either the b1 or b2 value. func ( *reader) ( bool) int { // The initial row is a special case. The previous row is implicitly all // white, so that there are no changing pixel elements. We return b1 or b2 // to be at the end of the row. if len(.prev) != len(.curr) { return len(.curr) } := .wi if .atStartOfRow { // a0 is implicitly at -1, on a white pixel. b1 is the first black // pixel in the previous row. b2 is the first white pixel after that. for ; ( < len(.prev)) && (.prev[] == 0xFF); ++ { } if == findB2 { for ; ( < len(.prev)) && (.prev[] == 0x00); ++ { } } return } // As per figure 1 above, assume that the current pen color is white. // First, walk past every contiguous black pixel in prev, starting at a0. := ^.penColor() for ; ( < len(.prev)) && (.prev[] == ); ++ { } // Then walk past every contiguous white pixel. := ^ for ; ( < len(.prev)) && (.prev[] == ); ++ { } // We're now at a black pixel (or at the end of the row). That's b1. if == findB2 { // If we're looking for b2, walk past every contiguous black pixel // again. := ^ for ; ( < len(.prev)) && (.prev[] == ); ++ { } } return } type readerMode struct { function func(z *reader, arg int) error arg int } var readerModes = [...]readerMode{ modePass: {function: readerModePass}, modeH: {function: readerModeH}, modeV0: {function: readerModeV, arg: +0}, modeVR1: {function: readerModeV, arg: +1}, modeVR2: {function: readerModeV, arg: +2}, modeVR3: {function: readerModeV, arg: +3}, modeVL1: {function: readerModeV, arg: -1}, modeVL2: {function: readerModeV, arg: -2}, modeVL3: {function: readerModeV, arg: -3}, modeExt: {function: readerModeExt}, } func readerModePass( *reader, int) error { := .findB(findB2) if ( < .wi) || (len(.curr) < ) { return errInvalidOffset } := .curr[.wi:] := .penColor() for := range { [] = } .wi = return nil } func readerModeH( *reader, int) error { // The first iteration finds a1. The second finds a2. for := 0; < 2; ++ { if := .decodeRun(); != nil { return } } return nil } func readerModeV( *reader, int) error { := .findB(findB1) + if ( < .wi) || (len(.curr) < ) { return errInvalidOffset } := .curr[.wi:] := .penColor() for := range { [] = } .wi = .penColorIsWhite = !.penColorIsWhite return nil } func readerModeExt( *reader, int) error { return errUnsupportedMode } // DecodeIntoGray decodes the CCITT-formatted data in r into dst. // // It returns an error if dst's width and height don't match the implied width // and height of CCITT-formatted data. func ( *image.Gray, io.Reader, Order, SubFormat, *Options) error { := .Bounds() if (.Dx() < 0) || (.Dy() < 0) { return errInvalidBounds } if .Dx() > maxWidth { return errUnsupportedWidth } := reader{ br: bitReader{r: , order: }, subFormat: , align: ( != nil) && .Align, invert: ( != nil) && .Invert, width: .Dx(), } if := .startDecode(); != nil { return } := .Dx() for := .Min.Y; < .Max.Y; ++ { := ( - .Min.Y) * .Stride .curr = .Pix[ : +] if := .decodeRow(+1 == .Max.Y); != nil { return } .curr, .prev = nil, .curr } if := .finishDecode(false); != nil { return } if .invert { for := .Min.Y; < .Max.Y; ++ { := ( - .Min.Y) * .Stride invertBytes(.Pix[ : +]) } } return nil } // NewReader returns an io.Reader that decodes the CCITT-formatted data in r. // The resultant byte stream is one bit per pixel (MSB first), with 1 meaning // white and 0 meaning black. Each row in the result is byte-aligned. // // A negative height, such as passing AutoDetectHeight, means that the image // height is not known in advance. A negative width is invalid. func ( io.Reader, Order, SubFormat, int, int, *Options) io.Reader { := error(nil) if < 0 { = errInvalidBounds } else if > maxWidth { = errUnsupportedWidth } return &reader{ br: bitReader{r: , order: }, subFormat: , align: ( != nil) && .Align, invert: ( != nil) && .Invert, width: , rowsRemaining: , readErr: , } }