///|
fn pdf_decode_png_current(
data : BytesView,
row_start : Int,
available : Int,
index : Int,
) -> Int {
if index < available {
data[row_start + index].to_int()
} else {
0
}
}
///|
fn pdf_decode_png_decoded_length(data : BytesView, scanline_width : Int) -> Int {
let mut rows = 0
let mut index = 0
while index < data.length() {
rows += 1
index += 1
let available = if index + scanline_width > data.length() {
data.length() - index
} else {
scanline_width
}
index += available
}
rows * scanline_width
}
///|
fn pdf_decode_png_push_scanline(
output : Array[Byte],
position : Int,
predictor : Int,
prior_decoded : ArrayView[Int],
decoded : Array[Int],
data : BytesView,
row_start : Int,
available : Int,
bytes_per_pixel : Int,
) -> Int raise @core.PdfError {
let scanline_width = decoded.length()
let mut output_position = position
match predictor {
0 =>
for i in 0..
for i in 0..
for i in 0..
for i in 0..
for i in 0.. raise PredictorNotSupported(predictor)
}
output_position
}
///|
fn pdf_decode_png_predictor(
colors : Int,
bits_per_component : Int,
columns : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
let scanline_width = pdf_predictor_scanline_width(
colors, bits_per_component, columns,
)
let bytes_per_pixel = pdf_predictor_bytes_per_pixel(
colors, bits_per_component,
)
let output = Array::make(
pdf_decode_png_decoded_length(data, scanline_width),
b'\x00',
)
let mut position = 0
let mut prior_decoded : Array[Int] = [ for _ in 0.. 0 ]
let mut decoded : Array[Int] = [ for _ in 0.. 0 ]
let mut index = 0
while index < data.length() {
let predictor = data[index].to_int()
index += 1
let available = if index + scanline_width > data.length() {
data.length() - index
} else {
scanline_width
}
let row_start = index
index += available
position = pdf_decode_png_push_scanline(
output, position, predictor, prior_decoded, decoded, data, row_start, available,
bytes_per_pixel,
)
let previous = prior_decoded
prior_decoded = decoded
decoded = previous
}
Bytes::from_array(output[:position])
}