837 lines
31 KiB
Odin
837 lines
31 KiB
Odin
package pdf
|
|||
|
|
|
||
|
|
// CCITTFaxDecode -- ITU-T T.4 (Group 3) and T.6 (Group 4) facsimile coding.
|
||
|
|
//
|
||
|
|
// ISO 32000-2, 7.4.6. The filter reconstructs a bi-level image that was
|
||
|
|
// encoded with the one-dimensional modified Huffman code (MH), the
|
||
|
|
// two-dimensional modified READ code (MR), or the pure two-dimensional
|
||
|
|
// modified modified READ code (MMR / Group 4).
|
||
|
|
//
|
||
|
|
// OUTPUT CONVENTION -- image.odin depends on this, so it is stated precisely:
|
||
|
|
//
|
||
|
|
// * One bit per pixel, most significant bit first within each byte, so
|
||
|
|
// pixel `x` of a row lives in bit `7 - (x & 7)` of byte `x >> 3`.
|
||
|
|
// * Each row starts on a byte boundary; the trailing bits of the last byte
|
||
|
|
// of a row are padding and are set to the white value.
|
||
|
|
// * With `black_is_1 == false` (the default, /BlackIs1 false) a black pixel
|
||
|
|
// is a 0 bit and a white pixel is a 1 bit. With `black_is_1 == true` the
|
||
|
|
// two are exchanged.
|
||
|
|
//
|
||
|
|
// That is exactly the 1-bit-per-component sample array an image XObject
|
||
|
|
// expects *before* /Decode is applied, which is why /BlackIs1 lives in the
|
||
|
|
// filter's parameters rather than in the image dictionary.
|
||
|
|
//
|
||
|
|
// The returned buffer holds `len(out) / ((columns + 7) / 8)` rows. That may be
|
||
|
|
// fewer than `p.rows` when the data runs out early: the filter returns the
|
||
|
|
// rows it managed to decode rather than failing, so a truncated fax still
|
||
|
|
// shows what was received. Callers that need exactly `p.rows` rows must pad.
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Limits
|
||
|
|
//
|
||
|
|
// Every one of these bounds a quantity that came out of the file.
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
// A row wider than this is not an image anyone scanned. T.4 defines paper
|
||
|
|
// widths up to 2432 pixels and its make-up codes stop at 2560; a 600 dpi A3
|
||
|
|
// scan reaches ~10000. 65536 is far past all of them and still keeps the two
|
||
|
|
// `columns + 8` changing-element lines to about a megabyte.
|
||
|
|
@(private)
|
||
|
|
MAX_CCITT_COLUMNS :: 1 << 16
|
||
|
|
// Rows decoded before the filter gives up. A2 at 400 dpi is ~9000 rows, so
|
||
|
|
// this is only ever reached by a stream designed to be reached.
|
||
|
|
@(private)
|
||
|
|
MAX_CCITT_ROWS :: 1 << 20
|
||
|
|
// Total decoded bytes. Matches MAX_BITMAP_PIXELS at one bit per pixel, so an
|
||
|
|
// image this filter accepts is one the rasteriser would also accept.
|
||
|
|
@(private)
|
||
|
|
MAX_CCITT_BYTES :: MAX_BITMAP_PIXELS / 8
|
||
|
|
// Fill bits tolerated before an EOL. T.4 allows fill of any length; a real
|
||
|
|
// encoder uses it to pad a line out to the minimum transmission time, which
|
||
|
|
// at 2400 baud is a few hundred bits, never tens of thousands.
|
||
|
|
@(private)
|
||
|
|
MAX_CCITT_FILL_BITS :: 1 << 16
|
||
|
|
// Make-up codes chained before a terminating code. T.4 needs at most one for
|
||
|
|
// widths up to 2623 and the extended codes let an encoder chain more for
|
||
|
|
// wider images; 64 of them already codes a run of 163840.
|
||
|
|
@(private)
|
||
|
|
MAX_CCITT_MAKEUP_CHAIN :: 64
|
||
|
|
|
||
|
|
// Ccitt_Params mirrors the CCITTFaxDecode parameter dictionary
|
||
|
|
// (ISO 32000-2, table 12). The zero value is *not* the PDF default: use
|
||
|
|
// `ccitt_default_params` or set `columns` and `end_of_block` yourself.
|
||
|
|
Ccitt_Params :: struct {
|
||
|
|
// /K. Negative: pure two-dimensional (Group 4, MMR). Zero: pure
|
||
|
|
// one-dimensional (Group 3 1-D, MH). Positive: mixed, each line tagged
|
||
|
|
// one- or two-dimensional after its EOL.
|
||
|
|
k: int,
|
||
|
|
// /Columns, pixels per row. Default 1728.
|
||
|
|
columns: int,
|
||
|
|
// /Rows. Zero means "unknown": decode until the data runs out or an RTC.
|
||
|
|
rows: int,
|
||
|
|
// /BlackIs1. False (the default) means a 0 bit is black.
|
||
|
|
black_is_1: bool,
|
||
|
|
// /EncodedByteAlign: every encoded line begins on a byte boundary.
|
||
|
|
byte_align: bool,
|
||
|
|
// /EndOfLine: the encoded data is expected to carry EOL codes. EOLs are
|
||
|
|
// accepted whether or not this is set -- producers set it inconsistently
|
||
|
|
// and an EOL is unambiguous in the bit stream -- so it only records the
|
||
|
|
// producer's intent.
|
||
|
|
end_of_line: bool,
|
||
|
|
// /EndOfBlock. Default true. When false the caller is asserting that
|
||
|
|
// `rows` is authoritative and that whatever follows the image is not
|
||
|
|
// ours to interpret. An RTC/EOFB still ends decoding either way, because
|
||
|
|
// no valid image data can follow one.
|
||
|
|
end_of_block: bool,
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_default_params returns the parameter defaults of ISO 32000-2 table 12.
|
||
|
|
ccitt_default_params :: proc() -> Ccitt_Params {
|
||
|
|
return Ccitt_Params{k = 0, columns = 1728, rows = 0, black_is_1 = false,
|
||
|
|
byte_align = false, end_of_line = false, end_of_block = true}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Bit reader
|
||
|
|
//
|
||
|
|
// Reads MSB-first and pads with zero bits past the end of the data, so a
|
||
|
|
// peek near the end never has to be special-cased; `ccitt_bits_left` is what
|
||
|
|
// decides whether a code is really there.
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
Ccitt_Bits :: struct {
|
||
|
|
data: []byte,
|
||
|
|
pos: int, // bit offset from the start of `data`
|
||
|
|
end: int, // len(data) * 8
|
||
|
|
}
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
ccitt_bits_make :: proc(data: []byte) -> Ccitt_Bits {
|
||
|
|
return Ccitt_Bits{data = data, pos = 0, end = len(data) * 8}
|
||
|
|
}
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
ccitt_bits_left :: proc(b: ^Ccitt_Bits) -> int {
|
||
|
|
return b.end - b.pos
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_bits_peek returns the next `n` bits (n <= 24) without consuming them.
|
||
|
|
@(private)
|
||
|
|
ccitt_bits_peek :: proc(b: ^Ccitt_Bits, n: int) -> u32 {
|
||
|
|
if n <= 0 {
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
n := n
|
||
|
|
if n > 24 {
|
||
|
|
n = 24
|
||
|
|
}
|
||
|
|
// Four bytes cover any 24-bit read starting at any bit offset.
|
||
|
|
i := b.pos >> 3
|
||
|
|
acc: u32 = 0
|
||
|
|
for k in 0 ..< 4 {
|
||
|
|
v: u32 = 0
|
||
|
|
if i + k < len(b.data) {
|
||
|
|
v = u32(b.data[i + k])
|
||
|
|
}
|
||
|
|
acc = acc << 8 | v
|
||
|
|
}
|
||
|
|
acc <<= uint(b.pos & 7)
|
||
|
|
return acc >> uint(32 - n)
|
||
|
|
}
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
ccitt_bits_skip :: proc(b: ^Ccitt_Bits, n: int) {
|
||
|
|
b.pos += n
|
||
|
|
if b.pos > b.end {
|
||
|
|
b.pos = b.end
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_bits_align moves to the next byte boundary (/EncodedByteAlign).
|
||
|
|
@(private)
|
||
|
|
ccitt_bits_align :: proc(b: ^Ccitt_Bits) {
|
||
|
|
b.pos = min((b.pos + 7) & ~int(7), b.end)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Run-length codes
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
Ccitt_Code :: struct {
|
||
|
|
bits: u8, // code length
|
||
|
|
code: u16, // the code, right-aligned in `bits` bits
|
||
|
|
run: u16, // run length it stands for
|
||
|
|
}
|
||
|
|
|
||
|
|
// White run lengths: T.4 tables 1 and 3, plus the shared extended make-up codes of table 3.
|
||
|
|
@(private, rodata)
|
||
|
|
CCITT_WHITE := [104]Ccitt_Code{
|
||
|
|
{bits = 4, code = 0b0111, run = 2},
|
||
|
|
{bits = 4, code = 0b1000, run = 3},
|
||
|
|
{bits = 4, code = 0b1011, run = 4},
|
||
|
|
{bits = 4, code = 0b1100, run = 5},
|
||
|
|
{bits = 4, code = 0b1110, run = 6},
|
||
|
|
{bits = 4, code = 0b1111, run = 7},
|
||
|
|
{bits = 5, code = 0b00111, run = 10},
|
||
|
|
{bits = 5, code = 0b01000, run = 11},
|
||
|
|
{bits = 5, code = 0b10010, run = 128},
|
||
|
|
{bits = 5, code = 0b10011, run = 8},
|
||
|
|
{bits = 5, code = 0b10100, run = 9},
|
||
|
|
{bits = 5, code = 0b11011, run = 64},
|
||
|
|
{bits = 6, code = 0b000011, run = 13},
|
||
|
|
{bits = 6, code = 0b000111, run = 1},
|
||
|
|
{bits = 6, code = 0b001000, run = 12},
|
||
|
|
{bits = 6, code = 0b010111, run = 192},
|
||
|
|
{bits = 6, code = 0b011000, run = 1664},
|
||
|
|
{bits = 6, code = 0b101010, run = 16},
|
||
|
|
{bits = 6, code = 0b101011, run = 17},
|
||
|
|
{bits = 6, code = 0b110100, run = 14},
|
||
|
|
{bits = 6, code = 0b110101, run = 15},
|
||
|
|
{bits = 7, code = 0b0000011, run = 22},
|
||
|
|
{bits = 7, code = 0b0000100, run = 23},
|
||
|
|
{bits = 7, code = 0b0001000, run = 20},
|
||
|
|
{bits = 7, code = 0b0001100, run = 19},
|
||
|
|
{bits = 7, code = 0b0010011, run = 26},
|
||
|
|
{bits = 7, code = 0b0010111, run = 21},
|
||
|
|
{bits = 7, code = 0b0011000, run = 28},
|
||
|
|
{bits = 7, code = 0b0100100, run = 27},
|
||
|
|
{bits = 7, code = 0b0100111, run = 18},
|
||
|
|
{bits = 7, code = 0b0101000, run = 24},
|
||
|
|
{bits = 7, code = 0b0101011, run = 25},
|
||
|
|
{bits = 7, code = 0b0110111, run = 256},
|
||
|
|
{bits = 8, code = 0b00000010, run = 29},
|
||
|
|
{bits = 8, code = 0b00000011, run = 30},
|
||
|
|
{bits = 8, code = 0b00000100, run = 45},
|
||
|
|
{bits = 8, code = 0b00000101, run = 46},
|
||
|
|
{bits = 8, code = 0b00001010, run = 47},
|
||
|
|
{bits = 8, code = 0b00001011, run = 48},
|
||
|
|
{bits = 8, code = 0b00010010, run = 33},
|
||
|
|
{bits = 8, code = 0b00010011, run = 34},
|
||
|
|
{bits = 8, code = 0b00010100, run = 35},
|
||
|
|
{bits = 8, code = 0b00010101, run = 36},
|
||
|
|
{bits = 8, code = 0b00010110, run = 37},
|
||
|
|
{bits = 8, code = 0b00010111, run = 38},
|
||
|
|
{bits = 8, code = 0b00011010, run = 31},
|
||
|
|
{bits = 8, code = 0b00011011, run = 32},
|
||
|
|
{bits = 8, code = 0b00100100, run = 53},
|
||
|
|
{bits = 8, code = 0b00100101, run = 54},
|
||
|
|
{bits = 8, code = 0b00101000, run = 39},
|
||
|
|
{bits = 8, code = 0b00101001, run = 40},
|
||
|
|
{bits = 8, code = 0b00101010, run = 41},
|
||
|
|
{bits = 8, code = 0b00101011, run = 42},
|
||
|
|
{bits = 8, code = 0b00101100, run = 43},
|
||
|
|
{bits = 8, code = 0b00101101, run = 44},
|
||
|
|
{bits = 8, code = 0b00110010, run = 61},
|
||
|
|
{bits = 8, code = 0b00110011, run = 62},
|
||
|
|
{bits = 8, code = 0b00110100, run = 63},
|
||
|
|
{bits = 8, code = 0b00110101, run = 0},
|
||
|
|
{bits = 8, code = 0b00110110, run = 320},
|
||
|
|
{bits = 8, code = 0b00110111, run = 384},
|
||
|
|
{bits = 8, code = 0b01001010, run = 59},
|
||
|
|
{bits = 8, code = 0b01001011, run = 60},
|
||
|
|
{bits = 8, code = 0b01010010, run = 49},
|
||
|
|
{bits = 8, code = 0b01010011, run = 50},
|
||
|
|
{bits = 8, code = 0b01010100, run = 51},
|
||
|
|
{bits = 8, code = 0b01010101, run = 52},
|
||
|
|
{bits = 8, code = 0b01011000, run = 55},
|
||
|
|
{bits = 8, code = 0b01011001, run = 56},
|
||
|
|
{bits = 8, code = 0b01011010, run = 57},
|
||
|
|
{bits = 8, code = 0b01011011, run = 58},
|
||
|
|
{bits = 8, code = 0b01100100, run = 448},
|
||
|
|
{bits = 8, code = 0b01100101, run = 512},
|
||
|
|
{bits = 8, code = 0b01100111, run = 640},
|
||
|
|
{bits = 8, code = 0b01101000, run = 576},
|
||
|
|
{bits = 9, code = 0b010011000, run = 1472},
|
||
|
|
{bits = 9, code = 0b010011001, run = 1536},
|
||
|
|
{bits = 9, code = 0b010011010, run = 1600},
|
||
|
|
{bits = 9, code = 0b010011011, run = 1728},
|
||
|
|
{bits = 9, code = 0b011001100, run = 704},
|
||
|
|
{bits = 9, code = 0b011001101, run = 768},
|
||
|
|
{bits = 9, code = 0b011010010, run = 832},
|
||
|
|
{bits = 9, code = 0b011010011, run = 896},
|
||
|
|
{bits = 9, code = 0b011010100, run = 960},
|
||
|
|
{bits = 9, code = 0b011010101, run = 1024},
|
||
|
|
{bits = 9, code = 0b011010110, run = 1088},
|
||
|
|
{bits = 9, code = 0b011010111, run = 1152},
|
||
|
|
{bits = 9, code = 0b011011000, run = 1216},
|
||
|
|
{bits = 9, code = 0b011011001, run = 1280},
|
||
|
|
{bits = 9, code = 0b011011010, run = 1344},
|
||
|
|
{bits = 9, code = 0b011011011, run = 1408},
|
||
|
|
{bits = 11, code = 0b00000001000, run = 1792},
|
||
|
|
{bits = 11, code = 0b00000001100, run = 1856},
|
||
|
|
{bits = 11, code = 0b00000001101, run = 1920},
|
||
|
|
{bits = 12, code = 0b000000010010, run = 1984},
|
||
|
|
{bits = 12, code = 0b000000010011, run = 2048},
|
||
|
|
{bits = 12, code = 0b000000010100, run = 2112},
|
||
|
|
{bits = 12, code = 0b000000010101, run = 2176},
|
||
|
|
{bits = 12, code = 0b000000010110, run = 2240},
|
||
|
|
{bits = 12, code = 0b000000010111, run = 2304},
|
||
|
|
{bits = 12, code = 0b000000011100, run = 2368},
|
||
|
|
{bits = 12, code = 0b000000011101, run = 2432},
|
||
|
|
{bits = 12, code = 0b000000011110, run = 2496},
|
||
|
|
{bits = 12, code = 0b000000011111, run = 2560},
|
||
|
|
}
|
||
|
|
|
||
|
|
// Black run lengths: T.4 tables 2 and 3, plus the shared extended make-up codes.
|
||
|
|
@(private, rodata)
|
||
|
|
CCITT_BLACK := [104]Ccitt_Code{
|
||
|
|
{bits = 2, code = 0b10, run = 3},
|
||
|
|
{bits = 2, code = 0b11, run = 2},
|
||
|
|
{bits = 3, code = 0b010, run = 1},
|
||
|
|
{bits = 3, code = 0b011, run = 4},
|
||
|
|
{bits = 4, code = 0b0010, run = 6},
|
||
|
|
{bits = 4, code = 0b0011, run = 5},
|
||
|
|
{bits = 5, code = 0b00011, run = 7},
|
||
|
|
{bits = 6, code = 0b000100, run = 9},
|
||
|
|
{bits = 6, code = 0b000101, run = 8},
|
||
|
|
{bits = 7, code = 0b0000100, run = 10},
|
||
|
|
{bits = 7, code = 0b0000101, run = 11},
|
||
|
|
{bits = 7, code = 0b0000111, run = 12},
|
||
|
|
{bits = 8, code = 0b00000100, run = 13},
|
||
|
|
{bits = 8, code = 0b00000111, run = 14},
|
||
|
|
{bits = 9, code = 0b000011000, run = 15},
|
||
|
|
{bits = 10, code = 0b0000001000, run = 18},
|
||
|
|
{bits = 10, code = 0b0000001111, run = 64},
|
||
|
|
{bits = 10, code = 0b0000010111, run = 16},
|
||
|
|
{bits = 10, code = 0b0000011000, run = 17},
|
||
|
|
{bits = 10, code = 0b0000110111, run = 0},
|
||
|
|
{bits = 11, code = 0b00000001000, run = 1792},
|
||
|
|
{bits = 11, code = 0b00000001100, run = 1856},
|
||
|
|
{bits = 11, code = 0b00000001101, run = 1920},
|
||
|
|
{bits = 11, code = 0b00000010111, run = 24},
|
||
|
|
{bits = 11, code = 0b00000011000, run = 25},
|
||
|
|
{bits = 11, code = 0b00000101000, run = 23},
|
||
|
|
{bits = 11, code = 0b00000110111, run = 22},
|
||
|
|
{bits = 11, code = 0b00001100111, run = 19},
|
||
|
|
{bits = 11, code = 0b00001101000, run = 20},
|
||
|
|
{bits = 11, code = 0b00001101100, run = 21},
|
||
|
|
{bits = 12, code = 0b000000010010, run = 1984},
|
||
|
|
{bits = 12, code = 0b000000010011, run = 2048},
|
||
|
|
{bits = 12, code = 0b000000010100, run = 2112},
|
||
|
|
{bits = 12, code = 0b000000010101, run = 2176},
|
||
|
|
{bits = 12, code = 0b000000010110, run = 2240},
|
||
|
|
{bits = 12, code = 0b000000010111, run = 2304},
|
||
|
|
{bits = 12, code = 0b000000011100, run = 2368},
|
||
|
|
{bits = 12, code = 0b000000011101, run = 2432},
|
||
|
|
{bits = 12, code = 0b000000011110, run = 2496},
|
||
|
|
{bits = 12, code = 0b000000011111, run = 2560},
|
||
|
|
{bits = 12, code = 0b000000100100, run = 52},
|
||
|
|
{bits = 12, code = 0b000000100111, run = 55},
|
||
|
|
{bits = 12, code = 0b000000101000, run = 56},
|
||
|
|
{bits = 12, code = 0b000000101011, run = 59},
|
||
|
|
{bits = 12, code = 0b000000101100, run = 60},
|
||
|
|
{bits = 12, code = 0b000000110011, run = 320},
|
||
|
|
{bits = 12, code = 0b000000110100, run = 384},
|
||
|
|
{bits = 12, code = 0b000000110101, run = 448},
|
||
|
|
{bits = 12, code = 0b000000110111, run = 53},
|
||
|
|
{bits = 12, code = 0b000000111000, run = 54},
|
||
|
|
{bits = 12, code = 0b000001010010, run = 50},
|
||
|
|
{bits = 12, code = 0b000001010011, run = 51},
|
||
|
|
{bits = 12, code = 0b000001010100, run = 44},
|
||
|
|
{bits = 12, code = 0b000001010101, run = 45},
|
||
|
|
{bits = 12, code = 0b000001010110, run = 46},
|
||
|
|
{bits = 12, code = 0b000001010111, run = 47},
|
||
|
|
{bits = 12, code = 0b000001011000, run = 57},
|
||
|
|
{bits = 12, code = 0b000001011001, run = 58},
|
||
|
|
{bits = 12, code = 0b000001011010, run = 61},
|
||
|
|
{bits = 12, code = 0b000001011011, run = 256},
|
||
|
|
{bits = 12, code = 0b000001100100, run = 48},
|
||
|
|
{bits = 12, code = 0b000001100101, run = 49},
|
||
|
|
{bits = 12, code = 0b000001100110, run = 62},
|
||
|
|
{bits = 12, code = 0b000001100111, run = 63},
|
||
|
|
{bits = 12, code = 0b000001101000, run = 30},
|
||
|
|
{bits = 12, code = 0b000001101001, run = 31},
|
||
|
|
{bits = 12, code = 0b000001101010, run = 32},
|
||
|
|
{bits = 12, code = 0b000001101011, run = 33},
|
||
|
|
{bits = 12, code = 0b000001101100, run = 40},
|
||
|
|
{bits = 12, code = 0b000001101101, run = 41},
|
||
|
|
{bits = 12, code = 0b000011001000, run = 128},
|
||
|
|
{bits = 12, code = 0b000011001001, run = 192},
|
||
|
|
{bits = 12, code = 0b000011001010, run = 26},
|
||
|
|
{bits = 12, code = 0b000011001011, run = 27},
|
||
|
|
{bits = 12, code = 0b000011001100, run = 28},
|
||
|
|
{bits = 12, code = 0b000011001101, run = 29},
|
||
|
|
{bits = 12, code = 0b000011010010, run = 34},
|
||
|
|
{bits = 12, code = 0b000011010011, run = 35},
|
||
|
|
{bits = 12, code = 0b000011010100, run = 36},
|
||
|
|
{bits = 12, code = 0b000011010101, run = 37},
|
||
|
|
{bits = 12, code = 0b000011010110, run = 38},
|
||
|
|
{bits = 12, code = 0b000011010111, run = 39},
|
||
|
|
{bits = 12, code = 0b000011011010, run = 42},
|
||
|
|
{bits = 12, code = 0b000011011011, run = 43},
|
||
|
|
{bits = 13, code = 0b0000001001010, run = 640},
|
||
|
|
{bits = 13, code = 0b0000001001011, run = 704},
|
||
|
|
{bits = 13, code = 0b0000001001100, run = 768},
|
||
|
|
{bits = 13, code = 0b0000001001101, run = 832},
|
||
|
|
{bits = 13, code = 0b0000001010010, run = 1280},
|
||
|
|
{bits = 13, code = 0b0000001010011, run = 1344},
|
||
|
|
{bits = 13, code = 0b0000001010100, run = 1408},
|
||
|
|
{bits = 13, code = 0b0000001010101, run = 1472},
|
||
|
|
{bits = 13, code = 0b0000001011010, run = 1536},
|
||
|
|
{bits = 13, code = 0b0000001011011, run = 1600},
|
||
|
|
{bits = 13, code = 0b0000001100100, run = 1664},
|
||
|
|
{bits = 13, code = 0b0000001100101, run = 1728},
|
||
|
|
{bits = 13, code = 0b0000001101100, run = 512},
|
||
|
|
{bits = 13, code = 0b0000001101101, run = 576},
|
||
|
|
{bits = 13, code = 0b0000001110010, run = 896},
|
||
|
|
{bits = 13, code = 0b0000001110011, run = 960},
|
||
|
|
{bits = 13, code = 0b0000001110100, run = 1024},
|
||
|
|
{bits = 13, code = 0b0000001110101, run = 1088},
|
||
|
|
{bits = 13, code = 0b0000001110110, run = 1152},
|
||
|
|
{bits = 13, code = 0b0000001110111, run = 1216},
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_lookup reads one run-length code. The tables are sorted by code
|
||
|
|
// length, so peeking once per distinct length and walking them in order
|
||
|
|
// decodes the shortest matching code -- which, the code being prefix-free, is
|
||
|
|
// the only matching code.
|
||
|
|
@(private)
|
||
|
|
ccitt_lookup :: proc(b: ^Ccitt_Bits, table: []Ccitt_Code) -> (run: int, ok: bool) {
|
||
|
|
peeked_len := -1
|
||
|
|
peeked: u32 = 0
|
||
|
|
for e in table {
|
||
|
|
n := int(e.bits)
|
||
|
|
if n != peeked_len {
|
||
|
|
peeked_len = n
|
||
|
|
peeked = ccitt_bits_peek(b, n)
|
||
|
|
}
|
||
|
|
if u32(e.code) == peeked {
|
||
|
|
// The zero padding past the end of the data can complete a code
|
||
|
|
// that was never written; refuse it rather than invent pixels.
|
||
|
|
if ccitt_bits_left(b) < n {
|
||
|
|
return 0, false
|
||
|
|
}
|
||
|
|
b.pos += n
|
||
|
|
return int(e.run), true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 0, false
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_run reads a complete run: zero or more make-up codes followed by one
|
||
|
|
// terminating code. The total is clamped to `limit`, which is the row width:
|
||
|
|
// a run longer than the row is malformed and clamping it is cheaper than
|
||
|
|
// carrying an overflowing position around.
|
||
|
|
@(private)
|
||
|
|
ccitt_run :: proc(b: ^Ccitt_Bits, black: bool, limit: int) -> (run: int, ok: bool) {
|
||
|
|
table := CCITT_WHITE[:]
|
||
|
|
if black {
|
||
|
|
table = CCITT_BLACK[:]
|
||
|
|
}
|
||
|
|
total := 0
|
||
|
|
for _ in 0 ..< MAX_CCITT_MAKEUP_CHAIN {
|
||
|
|
r, got := ccitt_lookup(b, table)
|
||
|
|
if !got {
|
||
|
|
return 0, false
|
||
|
|
}
|
||
|
|
total += r
|
||
|
|
if total > limit {
|
||
|
|
total = limit
|
||
|
|
}
|
||
|
|
if r < 64 {
|
||
|
|
return total, true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 0, false
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Two-dimensional coding modes (T.4 table 4 / T.6)
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
Ccitt_Mode :: enum u8 {
|
||
|
|
Pass, // 0001
|
||
|
|
Horizontal, // 001
|
||
|
|
V0, // 1
|
||
|
|
VR1, // 011
|
||
|
|
VR2, // 000011
|
||
|
|
VR3, // 0000011
|
||
|
|
VL1, // 010
|
||
|
|
VL2, // 000010
|
||
|
|
VL3, // 0000010
|
||
|
|
Extension, // 0000001 + 3 bits
|
||
|
|
Error,
|
||
|
|
}
|
||
|
|
|
||
|
|
@(private, rodata)
|
||
|
|
CCITT_VERTICAL_DELTA := [Ccitt_Mode]int{
|
||
|
|
.Pass = 0, .Horizontal = 0, .Extension = 0, .Error = 0,
|
||
|
|
.V0 = 0, .VR1 = 1, .VR2 = 2, .VR3 = 3, .VL1 = -1, .VL2 = -2, .VL3 = -3,
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_mode reads one 2-D mode code. All of them fit in seven bits, and no
|
||
|
|
// mode code has more than six leading zeros, so seven zero bits mean either an
|
||
|
|
// EOL or garbage -- either way, not a mode.
|
||
|
|
@(private)
|
||
|
|
ccitt_mode :: proc(b: ^Ccitt_Bits) -> (mode: Ccitt_Mode, ok: bool) {
|
||
|
|
v := ccitt_bits_peek(b, 7)
|
||
|
|
m: Ccitt_Mode
|
||
|
|
n: int
|
||
|
|
switch {
|
||
|
|
case v & 0b1000000 != 0: m, n = .V0, 1
|
||
|
|
case v >> 4 == 0b011: m, n = .VR1, 3
|
||
|
|
case v >> 4 == 0b010: m, n = .VL1, 3
|
||
|
|
case v >> 4 == 0b001: m, n = .Horizontal, 3
|
||
|
|
case v >> 3 == 0b0001: m, n = .Pass, 4
|
||
|
|
case v >> 1 == 0b000011: m, n = .VR2, 6
|
||
|
|
case v >> 1 == 0b000010: m, n = .VL2, 6
|
||
|
|
case v == 0b0000011: m, n = .VR3, 7
|
||
|
|
case v == 0b0000010: m, n = .VL3, 7
|
||
|
|
case v == 0b0000001: m, n = .Extension, 7
|
||
|
|
case: return .Error, false
|
||
|
|
}
|
||
|
|
if ccitt_bits_left(b) < n {
|
||
|
|
return .Error, false
|
||
|
|
}
|
||
|
|
b.pos += n
|
||
|
|
return m, true
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_try_eol consumes an EOL (eleven or more zero bits then a one) together
|
||
|
|
// with any fill that precedes it, and reports whether it found one. On failure
|
||
|
|
// the reader is left exactly where it was: no code in either run-length table
|
||
|
|
// has eight leading zeros, so a genuine code can never be mistaken for fill.
|
||
|
|
@(private)
|
||
|
|
ccitt_try_eol :: proc(b: ^Ccitt_Bits) -> bool {
|
||
|
|
save := b.pos
|
||
|
|
zeros := 0
|
||
|
|
for zeros < MAX_CCITT_FILL_BITS && ccitt_bits_left(b) > 0 && ccitt_bits_peek(b, 1) == 0 {
|
||
|
|
b.pos += 1
|
||
|
|
zeros += 1
|
||
|
|
}
|
||
|
|
if zeros >= 11 && ccitt_bits_left(b) > 0 && ccitt_bits_peek(b, 1) == 1 {
|
||
|
|
b.pos += 1
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
b.pos = save
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Rows
|
||
|
|
//
|
||
|
|
// A row is decoded into its changing elements: the positions, ascending, at
|
||
|
|
// which the colour changes, starting from white at pixel 0. Element 0, 2, 4 …
|
||
|
|
// are white-to-black transitions and 1, 3, 5 … are black-to-white ones. That
|
||
|
|
// is the form the 2-D coder needs for the *next* row's reference line, and it
|
||
|
|
// turns painting into a walk over black spans.
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
// ccitt_find_b locates b1, the first changing element on the reference line to
|
||
|
|
// the right of a0 whose colour is opposite to the current colour, and b2, the
|
||
|
|
// element after it. `cursor` is carried between calls within a row: a0 never
|
||
|
|
// decreases, so the scan never has to restart.
|
||
|
|
@(private)
|
||
|
|
ccitt_find_b :: proc(ref: []int, ref_n, columns, a0, color: int, cursor: ^int) -> (b1: int, b2: int) {
|
||
|
|
i := cursor^
|
||
|
|
if i < 0 {
|
||
|
|
i = 0
|
||
|
|
}
|
||
|
|
for i < ref_n && ref[i] <= a0 {
|
||
|
|
i += 1
|
||
|
|
}
|
||
|
|
cursor^ = i
|
||
|
|
// ref[i] has colour black for even i, white for odd i; we want the
|
||
|
|
// opposite of `color`, which is the same parity as `color` itself.
|
||
|
|
if (i & 1) != (color & 1) {
|
||
|
|
i += 1
|
||
|
|
}
|
||
|
|
b1 = columns
|
||
|
|
if i < ref_n {
|
||
|
|
b1 = ref[i]
|
||
|
|
}
|
||
|
|
b2 = columns
|
||
|
|
if i + 1 < ref_n {
|
||
|
|
b2 = ref[i + 1]
|
||
|
|
}
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_row_1d decodes one modified-Huffman row. `ok` is false when a code was
|
||
|
|
// unreadable, in which case the elements decoded so far are still returned.
|
||
|
|
@(private)
|
||
|
|
ccitt_row_1d :: proc(b: ^Ccitt_Bits, cur: []int, columns: int) -> (n: int, ok: bool) {
|
||
|
|
a0 := 0
|
||
|
|
black := false
|
||
|
|
// A row cannot hold more than `columns` runs of non-zero length, and a
|
||
|
|
// zero-length run costs at least eight bits, so this only ever fires on
|
||
|
|
// deliberately hostile data.
|
||
|
|
fuel := 2 * columns + 64
|
||
|
|
for a0 < columns && n < len(cur) && fuel > 0 {
|
||
|
|
fuel -= 1
|
||
|
|
run, got := ccitt_run(b, black, columns)
|
||
|
|
if !got {
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
a0 = min(a0 + run, columns)
|
||
|
|
cur[n] = a0
|
||
|
|
n += 1
|
||
|
|
black = !black
|
||
|
|
}
|
||
|
|
return n, true
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_row_2d decodes one modified-READ row against reference line `ref`.
|
||
|
|
@(private)
|
||
|
|
ccitt_row_2d :: proc(b: ^Ccitt_Bits, cur: []int, ref: []int, ref_n, columns: int) -> (n: int, ok: bool) {
|
||
|
|
a0 := -1 // an imaginary white element just left of the row
|
||
|
|
black := false
|
||
|
|
cursor := 0
|
||
|
|
fuel := 2 * columns + 64
|
||
|
|
for a0 < columns && fuel > 0 {
|
||
|
|
fuel -= 1
|
||
|
|
color := 0
|
||
|
|
if black {
|
||
|
|
color = 1
|
||
|
|
}
|
||
|
|
mode, got := ccitt_mode(b)
|
||
|
|
if !got {
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
switch mode {
|
||
|
|
case .Pass:
|
||
|
|
// The run continues past b2; no changing element is created.
|
||
|
|
_, b2 := ccitt_find_b(ref, ref_n, columns, a0, color, &cursor)
|
||
|
|
a0 = b2
|
||
|
|
|
||
|
|
case .Horizontal:
|
||
|
|
start := max(a0, 0)
|
||
|
|
r1, ok1 := ccitt_run(b, black, columns)
|
||
|
|
if !ok1 {
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
r2, ok2 := ccitt_run(b, !black, columns)
|
||
|
|
if !ok2 {
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
if n + 2 > len(cur) {
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
a1 := min(start + r1, columns)
|
||
|
|
a2 := min(a1 + r2, columns)
|
||
|
|
cur[n] = a1
|
||
|
|
cur[n + 1] = a2
|
||
|
|
n += 2
|
||
|
|
a0 = a2
|
||
|
|
|
||
|
|
case .V0, .VR1, .VR2, .VR3, .VL1, .VL2, .VL3:
|
||
|
|
b1, _ := ccitt_find_b(ref, ref_n, columns, a0, color, &cursor)
|
||
|
|
a1 := clamp(b1 + CCITT_VERTICAL_DELTA[mode], 0, columns)
|
||
|
|
// A VL that would step left of a0 is malformed; pinning it to a0
|
||
|
|
// keeps the element list sorted, which the next row relies on.
|
||
|
|
a1 = max(a1, a0)
|
||
|
|
if n >= len(cur) {
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
cur[n] = a1
|
||
|
|
n += 1
|
||
|
|
a0 = a1
|
||
|
|
black = !black
|
||
|
|
|
||
|
|
case .Extension:
|
||
|
|
// 2-D extensions (T.4 4.2.1.3.5) carry uncompressed mode, which
|
||
|
|
// no PDF producer emits. Stop here rather than desynchronise.
|
||
|
|
return n, false
|
||
|
|
|
||
|
|
case .Error:
|
||
|
|
return n, false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return n, true
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_paint sets pixels [from, to) of a packed 1-bpp row.
|
||
|
|
@(private)
|
||
|
|
ccitt_paint :: proc(row: []byte, from, to: int, one: bool) {
|
||
|
|
lo := max(from, 0)
|
||
|
|
hi := min(to, len(row) * 8)
|
||
|
|
fill: u8 = one ? 0xFF : 0x00
|
||
|
|
x := lo
|
||
|
|
for x < hi {
|
||
|
|
i := x >> 3
|
||
|
|
off := uint(x & 7)
|
||
|
|
if off == 0 && hi - x >= 8 {
|
||
|
|
last := i + (hi - x) / 8
|
||
|
|
for ; i < last; i += 1 {
|
||
|
|
row[i] = fill
|
||
|
|
}
|
||
|
|
x = last * 8
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
n := min(8 - int(off), hi - x)
|
||
|
|
mask := u8(0xFF >> off) & u8(0xFF << uint(8 - int(off) - n))
|
||
|
|
if one {
|
||
|
|
row[i] |= mask
|
||
|
|
} else {
|
||
|
|
row[i] &~= mask
|
||
|
|
}
|
||
|
|
x += n
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_emit_row paints one row of packed output from its changing elements.
|
||
|
|
// A colour that never changes back runs to the end of the row -- which is what
|
||
|
|
// pass mode at the right margin means, and also the least surprising way to
|
||
|
|
// pad a row whose data ran out early.
|
||
|
|
@(private)
|
||
|
|
ccitt_emit_row :: proc(row: []byte, cur: []int, n, columns: int, black_is_1: bool) {
|
||
|
|
white: u8 = black_is_1 ? 0x00 : 0xFF
|
||
|
|
for i in 0 ..< len(row) {
|
||
|
|
row[i] = white
|
||
|
|
}
|
||
|
|
for i := 0; i < n; i += 2 {
|
||
|
|
start := cur[i]
|
||
|
|
stop := columns
|
||
|
|
if i + 1 < n {
|
||
|
|
stop = cur[i + 1]
|
||
|
|
}
|
||
|
|
ccitt_paint(row, start, stop, black_is_1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Entry point
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
// ccitt_columns is the width `ccitt_decode` actually decodes at, and
|
||
|
|
// ccitt_row_bytes the stride it lays its output rows out at.
|
||
|
|
//
|
||
|
|
// /Columns comes out of a file, so it cannot be used as written: a
|
||
|
|
// non-positive value means the format's own default -- 1728, the width of a
|
||
|
|
// fax page -- and anything past MAX_CCITT_COLUMNS is clamped to what this
|
||
|
|
// decoder will allocate for. Both are exposed because the image layer has to
|
||
|
|
// read the buffer back at exactly this stride, and deriving it there from the
|
||
|
|
// raw /Columns instead is how the two silently disagree and every row after
|
||
|
|
// the first starts at the wrong byte.
|
||
|
|
@(private)
|
||
|
|
ccitt_columns :: proc(p: Ccitt_Params) -> int {
|
||
|
|
columns := p.columns
|
||
|
|
if columns <= 0 {
|
||
|
|
columns = 1728
|
||
|
|
}
|
||
|
|
return min(columns, MAX_CCITT_COLUMNS)
|
||
|
|
}
|
||
|
|
|
||
|
|
@(private)
|
||
|
|
ccitt_row_bytes :: proc(p: Ccitt_Params) -> int {
|
||
|
|
return (ccitt_columns(p) + 7) / 8
|
||
|
|
}
|
||
|
|
|
||
|
|
// ccitt_decode decodes CCITTFaxDecode data to packed 1-bit-per-pixel rows.
|
||
|
|
// See the convention described at the top of this file.
|
||
|
|
//
|
||
|
|
// The result is allocated with `allocator` and belongs to the caller; free it
|
||
|
|
// with `delete`. So is the row buffer it grows out of, which is sized from
|
||
|
|
// /Rows -- a claim rather than a measurement -- and released again when not
|
||
|
|
// one row decodes. Give it scratch, not a Document arena, whose `delete` is a
|
||
|
|
// silent no-op that would keep the whole claim until `close`; `apply_filter`
|
||
|
|
// in filters.odin is where that is arranged.
|
||
|
|
//
|
||
|
|
// An error is returned only when not a single row could be
|
||
|
|
// decoded -- anything less is reported by returning fewer rows than `p.rows`.
|
||
|
|
ccitt_decode :: proc(data: []byte, p: Ccitt_Params, allocator := context.allocator) -> (out: []byte, err: Error) {
|
||
|
|
columns := ccitt_columns(p)
|
||
|
|
row_bytes := ccitt_row_bytes(p)
|
||
|
|
|
||
|
|
max_rows := MAX_CCITT_ROWS
|
||
|
|
if p.rows > 0 {
|
||
|
|
max_rows = min(max_rows, p.rows)
|
||
|
|
}
|
||
|
|
max_rows = min(max_rows, MAX_CCITT_BYTES / row_bytes)
|
||
|
|
// Every row consumes at least one bit (a lone V0), so the data itself caps
|
||
|
|
// the row count when /Rows is absent.
|
||
|
|
max_rows = min(max_rows, len(data) * 8)
|
||
|
|
if max_rows <= 0 {
|
||
|
|
return nil, .Bad_Ccitt_Data
|
||
|
|
}
|
||
|
|
|
||
|
|
// Two changing-element lines. `columns + 8` slots leave room for the
|
||
|
|
// zero-length runs a horizontal code may legally contain without the
|
||
|
|
// pushes ever running off the end.
|
||
|
|
slots := columns + 8
|
||
|
|
scratch, serr := make([]int, 2 * slots, context.allocator)
|
||
|
|
if serr != nil {
|
||
|
|
return nil, .Out_Of_Memory
|
||
|
|
}
|
||
|
|
defer delete(scratch, context.allocator)
|
||
|
|
ref := scratch[:slots]
|
||
|
|
cur := scratch[slots:]
|
||
|
|
ref_n := 0
|
||
|
|
|
||
|
|
init_rows := 8
|
||
|
|
if p.rows > 0 {
|
||
|
|
init_rows = min(p.rows, max_rows)
|
||
|
|
}
|
||
|
|
buf, berr := make([dynamic]byte, 0, init_rows * row_bytes, allocator)
|
||
|
|
if berr != nil {
|
||
|
|
return nil, .Out_Of_Memory
|
||
|
|
}
|
||
|
|
|
||
|
|
b := ccitt_bits_make(data)
|
||
|
|
two_d := p.k < 0
|
||
|
|
rows_done := 0
|
||
|
|
|
||
|
|
for rows_done < max_rows {
|
||
|
|
if p.byte_align {
|
||
|
|
ccitt_bits_align(&b)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fill, EOLs, and the 1-D/2-D tag bit that follows each EOL when
|
||
|
|
// /K > 0. Two EOLs with nothing between them are an RTC (G3) or an
|
||
|
|
// EOFB (G4): the image is over.
|
||
|
|
eols := 0
|
||
|
|
for eols < 2 {
|
||
|
|
if !ccitt_try_eol(&b) {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
eols += 1
|
||
|
|
if p.k > 0 {
|
||
|
|
if ccitt_bits_left(&b) < 1 {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
two_d = ccitt_bits_peek(&b, 1) == 0
|
||
|
|
b.pos += 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if eols >= 2 || ccitt_bits_left(&b) <= 0 {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
|
||
|
|
n, ok := 0, false
|
||
|
|
if two_d {
|
||
|
|
n, ok = ccitt_row_2d(&b, cur, ref, ref_n, columns)
|
||
|
|
} else {
|
||
|
|
n, ok = ccitt_row_1d(&b, cur, columns)
|
||
|
|
}
|
||
|
|
if n == 0 {
|
||
|
|
// Not even one changing element: an unknown code or the end of
|
||
|
|
// the data, not a row.
|
||
|
|
break
|
||
|
|
}
|
||
|
|
|
||
|
|
rerr := resize(&buf, len(buf) + row_bytes)
|
||
|
|
if rerr != nil {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
ccitt_emit_row(buf[len(buf) - row_bytes:], cur, n, columns, p.black_is_1)
|
||
|
|
rows_done += 1
|
||
|
|
|
||
|
|
ref, cur = cur, ref
|
||
|
|
ref_n = n
|
||
|
|
|
||
|
|
if !ok {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if rows_done == 0 {
|
||
|
|
delete(buf)
|
||
|
|
return nil, .Bad_Ccitt_Data
|
||
|
|
}
|
||
|
|
_, _ = shrink(&buf)
|
||
|
|
return buf[:], .None
|
||
|
|
}
|