flxzt/rnote · error

ImageMemoryFormat try_from() gdk::MemoryFormat failed…

Error message

ImageMemoryFormat try_from() gdk::MemoryFormat failed, unsupported MemoryFormat `{:?}`

What it means

Converting a GDK MemoryFormat to the engine's ImageMemoryFormat failed because the format was anything other than R8g8b8a8Premultiplied. The engine only supports this single premultiplied RGBA layout when importing GTK/GDK image textures.

Solutions

  1. Convert the GdkTexture/MemoryTexture to R8g8b8a8Premultiplied before the try_from (e.g. download bytes and swizzle or request the right format).
  2. Add a conversion branch for the offending MemoryFormat in image.rs instead of failing.
  3. Downsample/normalize the source image to standard 8-bit premultiplied RGBA upstream.
  4. Log the unsupported format value and fall back to re-encoding the image through PNG which guarantees RGBA8.

Example fix

// before
let fmt = ImageMemoryFormat::try_from(mem_format)?;
// after
let fmt = match ImageMemoryFormat::try_from(mem_format) {
    Ok(f) => f,
    Err(_) => { /* convert bytes to R8g8b8a8Premultiplied first */ ImageMemoryFormat::R8g8b8a8Premultiplied }
};
Defensive patterns

Strategy: fallback

Validate before calling

// rust
let supported = matches!(mem_format, gdk::MemoryFormat::R8g8b8a8Premultiplied);
if !supported { /* convert before calling try_from */ }

Type guard

fn is_rgba8_premultiplied(f: gdk::MemoryFormat) -> bool {
    matches!(f, gdk::MemoryFormat::R8g8b8a8Premultiplied)
}

Try / catch

let fmt = match ImageMemoryFormat::try_from(mem_format) {
    Ok(f) => f,
    Err(e) => { log::warn!("{e}; converting to RGBA8"); convert_to_rgba8(mem_format)? }
};

Prevention

When it happens

Trigger: Calling ImageMemoryFormat::try_from(gdk::MemoryFormat) with a texture whose memory format is e.g. B8g8r8a8Premultiplied, R8g8b8a8, R16g16b16a16, or any non-premultiplied variant.

Common situations: Pasting or importing images from other applications that deliver textures in BGRA order (common on some platforms/Python bindings); renderers producing 16-bit float textures.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/8f1e4d56f28c3463. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/image.rs:44

#[non_exhaustive]
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum ImageMemoryFormat {
    R8g8b8a8Premultiplied,
}

impl Default for ImageMemoryFormat {
    fn default() -> Self {
        Self::R8g8b8a8Premultiplied
    }
}

#[cfg(feature = "ui")]
impl TryFrom<gtk4::gdk::MemoryFormat> for ImageMemoryFormat {
    type Error = anyhow::Error;
    fn try_from(value: gtk4::gdk::MemoryFormat) -> Result<Self, Self::Error> {
        match value {
            gtk4::gdk::MemoryFormat::R8g8b8a8Premultiplied => Ok(Self::R8g8b8a8Premultiplied),
            _ => Err(anyhow::anyhow!(
                "ImageMemoryFormat try_from() gdk::MemoryFormat failed, unsupported MemoryFormat `{:?}`",
                value
            )),
        }
    }
}

#[cfg(feature = "ui")]
impl From<ImageMemoryFormat> for gtk4::gdk::MemoryFormat {
    fn from(value: ImageMemoryFormat) -> Self {
        match value {
            ImageMemoryFormat::R8g8b8a8Premultiplied => {
                gtk4::gdk::MemoryFormat::R8g8b8a8Premultiplied
            }
        }
    }
}

View on GitHub (pinned to bbc5354502)