///|
fn pdf_ccitt_decode_g3_1d(
input : @core.BitStream,
output : @core.BitWriter,
params : PdfCCITTParams,
whiteval : Int,
blackval : Int,
) -> @core.PdfBytes raise @core.PdfError {
let mut row = 0
let mut column = 0
let mut line = pdf_ccitt_blank_line(params.columns, whiteval)
let mut white = true
let mut finished = false
try {
while !finished {
if params.rows > 0 && row >= params.rows {
finished = true
}
if !finished && column >= params.columns {
pdf_ccitt_output_line(output, line)
row += 1
column = 0
line = pdf_ccitt_blank_line(params.columns, whiteval)
white = true
if params.encoded_byte_align {
input.align()
}
} else if !finished {
let run = pdf_ccitt_read_run(input, white)
if run < 0 {
if column > 0 {
column = pdf_ccitt_output_span(
line,
column,
params.columns - column,
whiteval,
)
}
} else {
column = pdf_ccitt_output_span(
line,
column,
run,
if white {
whiteval
} else {
blackval
},
)
white = !white
}
}
}
output.to_bytes()
} catch {
EndOfInput => output.to_bytes()
InvalidCCITTData => raise InvalidCCITTData
_ => raise InvalidCCITTData
}
}
///|
fn pdf_ccitt_decode_g4(
input : @core.BitStream,
output : @core.BitWriter,
params : PdfCCITTParams,
whiteval : Int,
blackval : Int,
) -> @core.PdfBytes raise @core.PdfError {
let mut row = 0
let mut column = 0
let mut reference = pdf_ccitt_blank_line(params.columns, whiteval)
let mut line = pdf_ccitt_blank_line(params.columns, whiteval)
let mut white = true
let mut finished = false
try {
while !finished {
if params.rows > 0 && row >= params.rows {
finished = true
}
if !finished && column >= params.columns {
pdf_ccitt_output_line(output, line)
reference = line.copy()
line = pdf_ccitt_blank_line(params.columns, whiteval)
row += 1
column = 0
white = true
if params.encoded_byte_align {
input.align()
}
} else if !finished {
match pdf_ccitt_read_mode(input) {
CCITTPass =>
column = pdf_ccitt_output_span(
line,
column,
pdf_ccitt_find_b2(reference, column, white, whiteval, blackval) -
column,
if white {
whiteval
} else {
blackval
},
)
CCITTHorizontal =>
if white {
column = pdf_ccitt_output_span(
line,
column,
pdf_ccitt_read_run(input, true),
whiteval,
)
column = pdf_ccitt_output_span(
line,
column,
pdf_ccitt_read_run(input, false),
blackval,
)
} else {
column = pdf_ccitt_output_span(
line,
column,
pdf_ccitt_read_run(input, false),
blackval,
)
column = pdf_ccitt_output_span(
line,
column,
pdf_ccitt_read_run(input, true),
whiteval,
)
}
CCITTVertical(delta) => {
column = pdf_ccitt_output_span(
line,
column,
pdf_ccitt_find_b1(reference, column, white, whiteval, blackval) -
column -
delta,
if white {
whiteval
} else {
blackval
},
)
white = !white
}
CCITTEOFB => finished = true
CCITTUncompressed =>
raise @core.PdfError::CCITTNotSupported("CCITT Uncompressed")
}
}
}
output.to_bytes()
} catch {
EndOfInput => output.to_bytes()
CCITTNotSupported(reason) => raise CCITTNotSupported(reason)
InvalidCCITTData => raise InvalidCCITTData
_ => raise InvalidCCITTData
}
}
///|
fn pdf_ccitt_decode_view(
data : BytesView,
params : PdfCCITTParams,
) -> @core.PdfBytes raise @core.PdfError {
if params.columns <= 0 ||
params.rows < 0 ||
params.damaged_rows_before_error < 0 {
raise InvalidCCITTData
}
ignore(params.end_of_line)
ignore(params.end_of_block)
let whiteval = if params.black_is_1 { 0 } else { 1 }
let blackval = if params.black_is_1 { 1 } else { 0 }
let input = @core.bitstream_of_view(data)
let output = @core.bit_writer_new()
if params.k > 0 {
raise CCITTNotSupported("CCITTFax K > 0")
} else if params.k < 0 {
pdf_ccitt_decode_g4(input, output, params, whiteval, blackval)
} else {
pdf_ccitt_decode_g3_1d(input, output, params, whiteval, blackval)
}
}