///|
fn pdf_ccitt_read_run_code(
input : @core.BitStream,
table : ArrayView[PdfCCITTCode],
) -> PdfCCITTRun raise @core.PdfError {
let mut bits = 0
for width in 1..<=13 {
bits = (bits << 1) | input.get_bit_int()
for code in table {
if code.width == width && code.bits == bits {
return { run: code.run, makeup: code.makeup, }
}
}
}
raise InvalidCCITTData
}
///|
fn pdf_ccitt_read_run(
input : @core.BitStream,
white : Bool,
) -> Int raise @core.PdfError {
let table = if white {
pdf_ccitt_white_codes[:]
} else {
pdf_ccitt_black_codes
}
let mut total = 0
while true {
let code = pdf_ccitt_read_run_code(input, table)
if code.run < 0 {
return code.run
}
total += code.run
if !code.makeup {
return total
}
}
raise InvalidCCITTData
}
///|
fn pdf_ccitt_read_mode(
input : @core.BitStream,
) -> PdfCCITTModeKind raise @core.PdfError {
let mut bits = 0
for width in 1..<=24 {
bits = (bits << 1) | input.get_bit_int()
for code in pdf_ccitt_mode_codes {
if code.width == width && code.bits == bits {
return code.mode
}
}
}
raise InvalidCCITTData
}
///|
fn pdf_ccitt_write_code(
output : @core.BitWriter,
table : ArrayView[PdfCCITTCode],
run : Int,
makeup : Bool,
) -> Unit raise @core.PdfError {
for code in table {
if code.run == run && code.makeup == makeup {
output.put_value_int(code.width, code.bits)
return
}
}
raise InvalidCCITTData
}
///|
fn pdf_ccitt_write_eol(output : @core.BitWriter) -> Unit raise @core.PdfError {
pdf_ccitt_write_code(output, pdf_ccitt_white_codes, -1, false)
}
///|
fn pdf_ccitt_write_mode(
output : @core.BitWriter,
mode : PdfCCITTModeKind,
) -> Unit raise @core.PdfError {
match mode {
CCITTPass => output.put_value_int(4, 0b0001)
CCITTHorizontal => output.put_value_int(3, 0b001)
CCITTVertical(0) => output.put_value_int(1, 0b1)
CCITTVertical(-1) => output.put_value_int(3, 0b011)
CCITTVertical(1) => output.put_value_int(3, 0b010)
CCITTVertical(-2) => output.put_value_int(6, 0b000011)
CCITTVertical(2) => output.put_value_int(6, 0b000010)
CCITTVertical(-3) => output.put_value_int(7, 0b0000011)
CCITTVertical(3) => output.put_value_int(7, 0b0000010)
CCITTEOFB => output.put_value_int(24, 0b000000000001000000000001)
CCITTUncompressed => raise CCITTNotSupported("CCITT Uncompressed")
CCITTVertical(_) => raise InvalidCCITTData
}
}
///|
fn pdf_ccitt_write_run(
output : @core.BitWriter,
white : Bool,
length : Int,
) -> Unit raise @core.PdfError {
if length < 0 {
raise InvalidCCITTData
}
let table = if white {
pdf_ccitt_white_codes[:]
} else {
pdf_ccitt_black_codes
}
let mut remaining = length
while remaining >= 64 {
let mut best = 0
for code in table {
if code.makeup && code.run <= remaining && code.run > best {
best = code.run
}
}
pdf_ccitt_write_code(output, table, best, true)
remaining -= best
}
pdf_ccitt_write_code(output, table, remaining, false)
}