tonhowtf/omniget · error

sem memoria para x

Error message

sem memoria para {}x{}

What it means

Allocation guard in PageRef render: the MuPDF bitmap of the computed pixel dimensions could not be created — the w×h at the chosen DPI exceeds available memory — so rasterizing this page at this resolution is impossible.

Solutions

  1. Lower the DPI (e.g. from 300 to 96–150) and retry
  2. Cap rendered dimensions: compute w*h beforehand and reduce DPI so the product stays reasonable
  3. Check available memory; a w×h RGB bitmap needs ~3*w*h bytes
  4. Skip or stub rendering for pages whose computed dimensions are extreme

Example fix

// before
let scale = dpi.max(24) as f32 / 72.0;
// after
let scale = (dpi.max(24) as f32 / 72.0).min(max_scale_for(w_pt, h_pt));
// where max_scale_for keeps w_pt*scale*h_pt*scale under ~50M pixels
Defensive patterns

Strategy: validation

Validate before calling

let (w, h) = computed_dimensions(page, dpi);
anyhow::ensure!(w <= 20_000 && h <= 20_000 && (w as u64) * (h as u64) <= 80_000_000, "dpi {dpi} too high for this page");

Try / catch

match page.render(dpi) {
    Ok(img) => img,
    Err(e) if e.to_string().starts_with("sem memoria") => page.render(dpi / 2).context("rendering failed even at half DPI")?,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling render (directly or via the live preview path) with a DPI/zoom that, applied to a very large page, yields bitmap dimensions near the 20000×20000 clamp — e.g. a huge-format page (posters, blueprints) at 300+ DPI.

Common situations: Rendering A0/architectural drawings at high DPI, previewing zoomed-in pages of large-format PDFs, memory-constrained environments where even modest bitmaps fail to allocate.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/2d061f37f4344bf4. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/pdf.rs:333

struct PageRef<'a> {
    api: &'static Api,
    page: Page,
    _doc: &'a Document,
}

impl PageRef<'_> {
    fn size_pt(&self) -> (f32, f32) {
        unsafe { ((self.api.page_w)(self.page), (self.api.page_h)(self.page)) }
    }

    fn render(&self, dpi: u32) -> anyhow::Result<image::RgbImage> {
        let (w_pt, h_pt) = self.size_pt();
        let scale = dpi.max(24) as f32 / 72.0;
        let w = ((w_pt * scale).round() as i32).clamp(1, 20_000);
        let h = ((h_pt * scale).round() as i32).clamp(1, 20_000);
        let bmp = unsafe { (self.api.bmp_create)(w, h, 0) };
        if bmp.is_null() {
            return Err(anyhow!("sem memoria para {}x{}", w, h));
        }
        let mut img = image::RgbImage::new(w as u32, h as u32);
        unsafe {
            (self.api.bmp_fill)(bmp, 0, 0, w, h, 0xFFFF_FFFF);
            (self.api.render)(bmp, self.page, 0, 0, w, h, 0, FPDF_ANNOT);
            let stride = (self.api.bmp_stride)(bmp) as usize;
            let buf = (self.api.bmp_buffer)(bmp) as *const u8;
            let src = std::slice::from_raw_parts(buf, stride * h as usize);
            for y in 0..h as usize {
                let row = &src[y * stride..y * stride + w as usize * 4];
                for x in 0..w as usize {
                    let p = &row[x * 4..x * 4 + 4]; // BGRx
                    img.put_pixel(x as u32, y as u32, image::Rgb([p[2], p[1], p[0]]));
                }
            }
            (self.api.bmp_destroy)(bmp);
        }
        Ok(img)

View on GitHub (pinned to 8600b91f42)