///|
fn pdf_space_read_indexed_table(
data : BytesView,
hival : Int,
components : Int,
) -> Array[(Int, Array[Int])] raise @core.PdfError {
if hival < 0 {
raise InvalidReadLength(hival)
}
let count = hival + 1
let required = count * components
if data.length() < required {
raise EndOfInput
}
let table : Array[(Int, Array[Int])] = []
for index in 0.. BytesView? raise @core.PdfError {
match self.direct(lookup_data) {
PdfString(data) => Some(data)
PdfStreamObject(stream) =>
Some(
@syntax.pdf_stream_data_view(
self.pdf_decode_stream_value_direct(stream).data,
),
)
_ => None
}
}
///|
fn PdfDocument::pdf_space_read_icc_based(
self : PdfDocument,
resources : @syntax.PdfObject,
stream_object : @syntax.PdfObject,
) -> PdfColourSpace? raise @core.PdfError {
match self.direct(stream_object) {
PdfStreamObject(stream) =>
match self.lookup_direct(pdf_space_n_key(), stream.dictionary) {
Some(PdfInteger(n)) =>
match pdf_space_default_icc_alternate(n) {
Some(default_alternate) => {
let alternate = match
self.lookup_direct(pdf_space_alternate_key(), stream.dictionary) {
Some(alternate) => self.read_colour_space(resources, alternate)
None => Some(default_alternate)
}
match alternate {
Some(alternate) => {
let range = self.pdf_space_read_number_array(
stream.dictionary,
pdf_space_range_key(),
n * 2,
pdf_space_default_icc_range(n),
)
Some(
PdfICCBased(
n,
alternate,
range,
self.lookup_direct(
pdf_space_metadata_key(),
stream.dictionary,
),
stream_object,
),
)
}
None => None
}
}
None => None
}
_ => None
}
_ => None
}
}
///|
fn PdfDocument::pdf_space_read_indexed(
self : PdfDocument,
resources : @syntax.PdfObject,
base_object : @syntax.PdfObject,
hival_object : @syntax.PdfObject,
lookup_data : @syntax.PdfObject,
) -> PdfColourSpace? raise @core.PdfError {
let hival = match hival_object {
PdfInteger(hival) => hival
_ => raise NumberExpected
}
match self.read_colour_space(resources, base_object) {
Some(base) =>
match
(
pdf_space_indexed_component_count(base),
self.pdf_space_indexed_lookup_data(lookup_data),
) {
(Some(components), Some(data)) =>
Some(
PdfIndexed(
base,
pdf_space_read_indexed_table(data, hival, components),
),
)
_ => None
}
None => None
}
}
///|
fn pdf_space_read_names(
values : ArrayView[@syntax.PdfObject],
) -> Array[@core.PdfName]? {
let names : Array[@core.PdfName] = []
let mut valid = true
for value in values {
match value {
PdfNameObject(name) => names.push(name)
_ => valid = false
}
}
if valid {
Some(names)
} else {
None
}
}
///|
fn PdfDocument::pdf_space_read_device_n(
self : PdfDocument,
resources : @syntax.PdfObject,
names : ArrayView[@syntax.PdfObject],
alternate : @syntax.PdfObject,
tint : @syntax.PdfObject,
attributes? : @syntax.PdfObject = @syntax.pdf_dictionary([]),
) -> PdfColourSpace? raise @core.PdfError {
match
(pdf_space_read_names(names), self.read_colour_space(resources, alternate)) {
(Some(names), Some(alternate)) =>
Some(PdfDeviceN(names, alternate, tint, attributes))
_ => None
}
}
///|
/// Parse a colour-space object using the document and resource dictionary.
///
/// The parser resolves resource colour-space names and supports device spaces,
/// pattern spaces with a base space, calibrated Gray/RGB/Lab spaces, ICCBased
/// spaces, Indexed spaces, Separation spaces, and DeviceN spaces. Unsupported
/// or malformed colour spaces return `None`; malformed numeric fields may raise
/// `@core.PdfError`.
pub fn PdfDocument::read_colour_space(
self : PdfDocument,
resources : @syntax.PdfObject,
object : @syntax.PdfObject,
) -> PdfColourSpace? raise @core.PdfError {
match self.direct(object) {
PdfNameObject(name) =>
match pdf_colour_space_of_device_name(name) {
Some(space) => Some(space)
None =>
match self.lookup_direct(pdf_space_colorspace_key(), resources) {
Some(colour_spaces) =>
match self.lookup_direct(name, colour_spaces) {
Some(resolved) => self.read_colour_space(resources, resolved)
None => None
}
None => None
}
}
PdfArray([PdfNameObject(name), base]) if name == pdf_space_pattern_name =>
match self.read_colour_space(resources, base) {
Some(base) => Some(PdfPatternWithBaseColourSpace(base))
None => None
}
PdfArray([PdfNameObject(name), dictionary]) if name ==
pdf_space_calgray_name =>
Some(
PdfCalGray(
self.pdf_space_read_point(dictionary, pdf_space_whitepoint_key()),
self.pdf_space_read_point(dictionary, pdf_space_blackpoint_key()),
self.pdf_space_read_number(dictionary, pdf_space_gamma_key(), 1.0),
),
)
PdfArray([PdfNameObject(name), dictionary]) if name == pdf_space_calrgb_name =>
Some(
PdfCalRGB(
self.pdf_space_read_point(dictionary, pdf_space_whitepoint_key()),
self.pdf_space_read_point(dictionary, pdf_space_blackpoint_key()),
self.pdf_space_read_number_array(
dictionary,
pdf_space_gamma_key(),
3,
[1.0, 1.0, 1.0],
),
self.pdf_space_read_number_array(
dictionary,
pdf_space_matrix_key(),
9,
[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0],
),
),
)
PdfArray([PdfNameObject(name), dictionary]) if name == pdf_space_lab_name =>
Some(
PdfLab(
self.pdf_space_read_point(dictionary, pdf_space_whitepoint_key()),
self.pdf_space_read_point(dictionary, pdf_space_blackpoint_key()),
self.pdf_space_read_number_array(
dictionary,
pdf_space_range_key(),
4,
[-100.0, 100.0, -100.0, 100.0],
),
),
)
PdfArray([PdfNameObject(name), stream_object]) if name ==
pdf_space_iccbased_name =>
self.pdf_space_read_icc_based(resources, stream_object)
PdfArray([PdfNameObject(name), base, hival, lookup_data]) if name ==
pdf_space_indexed_name ||
name == pdf_space_i_name =>
self.pdf_space_read_indexed(resources, base, hival, lookup_data)
PdfArray([PdfNameObject(kind), PdfNameObject(name), alternate, tint]) if kind ==
pdf_space_separation_name =>
match self.read_colour_space(resources, alternate) {
Some(alternate) => Some(PdfSeparation(name, alternate, tint))
None => None
}
PdfArray([PdfNameObject(kind), PdfArray(names), alternate, tint]) if kind ==
pdf_space_device_n_name =>
self.pdf_space_read_device_n(resources, names, alternate, tint)
PdfArray(
[PdfNameObject(kind), PdfArray(names), alternate, tint, attributes]
) if kind == pdf_space_device_n_name =>
self.pdf_space_read_device_n(
resources,
names,
alternate,
tint,
attributes~,
)
PdfArray([single]) => self.read_colour_space(resources, single)
_ => None
}
}
///|
/// Compatibility wrapper for `PdfDocument::read_colour_space`.
pub fn pdf_read_colour_space(
document : PdfDocument,
resources : @syntax.PdfObject,
object : @syntax.PdfObject,
) -> PdfColourSpace? raise @core.PdfError {
document.read_colour_space(resources, object)
}