///|
fn pdf_image_cmyk_component(channel : Int, black : Int) -> Int {
let channel = channel.to_double()
let black = black.to_double()
(255.0 - double_min(255.0, channel / 255.0 * (255.0 - black) + black)).to_int()
}
///|
fn pdf_image_rgb_of_cmyk(c : Int, m : Int, y : Int, k : Int) -> (Int, Int, Int) {
(
pdf_image_cmyk_component(c, k),
pdf_image_cmyk_component(m, k),
pdf_image_cmyk_component(y, k),
)
}
///|
fn pdf_image_gray_8bpp_as_rgb24(
width : Int,
height : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
let pixels = width * height
pdf_image_require_size(data, pixels)
let output = Array::make(pixels * 3, b'\x00')
let mut position = 0
for index in 0.. @core.PdfBytes raise @core.PdfError {
let pixels = width * height
pdf_image_require_size(data, pixels * 4)
let output = Array::make(pixels * 3, b'\x00')
let mut position = 0
for index in 0.. @core.PdfBytes raise @core.PdfError {
let bytes_per_row = (width + 7) / 8
pdf_image_require_size(data, bytes_per_row * height)
let output = Array::make(width * height * 3, b'\x00')
let mut position = 0
for row in 0..> (7 - column % 8)) & 1
let value : Byte = if bit == 1 { 255 } else { 0 }
output[position] = value
output[position + 1] = value
output[position + 2] = value
position += 3
}
}
Bytes::from_array(output)
}
///|
fn pdf_image_packed_bytes_per_row(width : Int, bits_per_component : Int) -> Int {
let row_bits = width * bits_per_component
if row_bits % 8 == 0 {
row_bits / 8
} else {
row_bits / 8 + 1
}
}
///|
fn pdf_image_packed_sample(
data : BytesView,
row_offset : Int,
column : Int,
bits_per_component : Int,
) -> Int {
let bit_offset = column * bits_per_component
let byte = data[row_offset + bit_offset / 8].to_int()
let shift = 8 - bits_per_component - bit_offset % 8
let mask = (1 << bits_per_component) - 1
(byte >> shift) & mask
}
///|
fn pdf_image_gray_packed_bpp_as_rgb24(
width : Int,
height : Int,
bits_per_component : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
let bytes_per_row = pdf_image_packed_bytes_per_row(width, bits_per_component)
pdf_image_require_size(data, bytes_per_row * height)
let max_sample = (1 << bits_per_component) - 1
let output = Array::make(width * height * 3, b'\x00')
let mut position = 0
for row in 0.. @core.PdfBytes raise @core.PdfError {
pdf_image_gray_packed_bpp_as_rgb24(width, height, 2, data)
}
///|
fn pdf_image_gray_4bpp_as_rgb24(
width : Int,
height : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
pdf_image_gray_packed_bpp_as_rgb24(width, height, 4, data)
}
///|
fn pdf_image_rgb_packed_bpp_as_rgb24(
width : Int,
height : Int,
bits_per_component : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
let samples_per_row = width * 3
let bytes_per_row = pdf_image_packed_bytes_per_row(
samples_per_row, bits_per_component,
)
pdf_image_require_size(data, bytes_per_row * height)
let max_sample = (1 << bits_per_component) - 1
let output = Array::make(width * height * 3, b'\x00')
let mut position = 0
for row in 0.. @core.PdfBytes raise @core.PdfError {
pdf_image_rgb_packed_bpp_as_rgb24(width, height, 1, data)
}
///|
fn pdf_image_rgb_2bpp_as_rgb24(
width : Int,
height : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
pdf_image_rgb_packed_bpp_as_rgb24(width, height, 2, data)
}
///|
fn pdf_image_rgb_4bpp_as_rgb24(
width : Int,
height : Int,
data : BytesView,
) -> @core.PdfBytes raise @core.PdfError {
pdf_image_rgb_packed_bpp_as_rgb24(width, height, 4, data)
}