mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-29 20:47:32 -06:00
refactor(edit): images read page content through content_streams
The image module kept its own copy of the page-content reader; the one in text carries the page decode budget.
This commit is contained in:
@@ -9,6 +9,7 @@ use pdfcraft_cos::{Dict, Document, ObjRef, Object};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::EditError;
|
||||
use crate::text::content_streams;
|
||||
|
||||
/// An image drawn on a page.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -73,10 +74,6 @@ struct ClipPath {
|
||||
even_odd: bool,
|
||||
}
|
||||
|
||||
fn streams(doc: &Document, page: &Dict) -> Result<Vec<(Object, Vec<u8>)>, EditError> {
|
||||
crate::text::content_streams(doc, page)
|
||||
}
|
||||
|
||||
/// Image draws one page's inventory lists at most: a form drawn many times from other forms
|
||||
/// would otherwise multiply a few hundred bytes into millions of records.
|
||||
pub(crate) const MAX_PAGE_IMAGES: usize = 100_000;
|
||||
@@ -230,7 +227,7 @@ pub fn page_images(doc: &Document, page: usize) -> Result<Vec<PageImage>, EditEr
|
||||
let mut out = Vec::new();
|
||||
// The streams are one stream in pieces, so the graphics state and operators carry over.
|
||||
let mut state = ImageState::new(Matrix::IDENTITY, p.crop(doc), Vec::new());
|
||||
let pieces = joined(&streams(doc, &p.dict)?);
|
||||
let pieces = joined(&content_streams(doc, &p.dict)?);
|
||||
for (i, op) in pieces.parse().ops.iter().enumerate() {
|
||||
state.apply(op)?;
|
||||
let ctm = state.placement.matrix;
|
||||
@@ -381,7 +378,7 @@ pub fn reading_images(doc: &Document, page: usize) -> Result<Vec<PageImage>, Edi
|
||||
let mut out = Vec::new();
|
||||
let mut st = ImageState::new(Matrix::IDENTITY, p.crop(doc), Vec::new());
|
||||
let mut forms = Forms { path: Vec::new(), budget: crate::text::FormBudget::default() };
|
||||
let pieces = joined(&streams(doc, &p.dict)?);
|
||||
let pieces = joined(&content_streams(doc, &p.dict)?);
|
||||
walk(doc, &pieces.parse().ops, &res, &mut st, &|op| pieces.piece_of(op.span.start), &mut forms, &mut out)?;
|
||||
Ok(out)
|
||||
}
|
||||
@@ -482,7 +479,7 @@ pub fn change_image(doc: &mut Document, page: usize, index: usize, change: &Imag
|
||||
let images = page_images(doc, page)?;
|
||||
let img = images.get(index).cloned().ok_or_else(|| EditError::Invalid(format!("page {} has no image {}", page + 1, index + 1)))?;
|
||||
let p = page_of(doc, page)?;
|
||||
let all = streams(doc, &p.dict)?;
|
||||
let all = content_streams(doc, &p.dict)?;
|
||||
let pieces = joined(&all);
|
||||
let ops = pieces.parse().ops;
|
||||
if !ops.get(img.op).is_some_and(|op| op.is("Do")) {
|
||||
@@ -530,7 +527,7 @@ pub(crate) fn selectable_images(
|
||||
excluded: &std::collections::BTreeSet<ObjRef>,
|
||||
) -> Result<Vec<(usize, PageImage)>, EditError> {
|
||||
let p = page_of(doc, page)?;
|
||||
let all = streams(doc, &p.dict)?;
|
||||
let all = content_streams(doc, &p.dict)?;
|
||||
Ok(page_images(doc, page)?
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
@@ -754,7 +751,7 @@ pub(crate) fn translate_images(doc: &mut Document, page: usize, indexes: &[usize
|
||||
}
|
||||
let images = page_images(doc, page)?;
|
||||
let p = page_of(doc, page)?;
|
||||
let all = streams(doc, &p.dict)?;
|
||||
let all = content_streams(doc, &p.dict)?;
|
||||
let mut plans = std::collections::BTreeMap::new();
|
||||
for index in indexes {
|
||||
let image = images.get(*index).ok_or_else(|| EditError::Invalid("a selected image no longer exists".into()))?;
|
||||
|
||||
Reference in New Issue
Block a user