tonhowtf/omniget · error
JPEG sem cabecalho SOF
Error message
JPEG sem cabecalho SOF
What it means
After confirming the SOI marker, jpeg_info walks the segment chain looking for a Start-Of-Frame marker (SOF0/SOF2, etc.) that carries width/height/channels. If it consumes the whole buffer without finding one, it raises "JPEG sem cabecalho SOF" (JPEG without SOF header). This happens for valid-signature but structurally broken or exotic files.
Solutions
- Verify the file opens in an image viewer / `file` reports a complete JPEG — if not, re-download it
- Compare bytes received against Content-Length to detect truncation before parsing
- Fall back to a robust decoder (image crate) to extract dimensions when the custom parser fails
Example fix
// before
let info = jpeg_info(&bytes)?; // Err: JPEG sem cabecalho SOF
// after
let info = match jpeg_info(&bytes) {
Ok(i) => i,
Err(_) => {
let img = image::load_from_memory(&bytes)?; // robust fallback
JpegInfo { width: img.width(), height: img.height(), components: 3 }
}
}; Defensive patterns
Strategy: fallback
Validate before calling
// ensure the whole file arrived before parsing assert_eq!(bytes.len(), expected_content_length as usize, "JPEG truncado");
Try / catch
let info = jpeg_info(&bytes).or_else(|_| {
image::load_from_memory(&bytes).map(|img| JpegInfo {
width: img.width(), height: img.height(), components: 3,
})
})?; Prevention
- Validate downloads completed (Content-Length match) before parsing
- Fall back to a full image decoder when the lightweight SOF walker fails
- Reject zero-length or suspiciously small files early
When it happens
Trigger: Truncated JPEG cut off before the SOF segment; progressive/EXIF files whose scan data precedes parsing assumptions and the loop skips past the SOF; concatenated/corrupted buffers where segment lengths lead parsing astray.
Common situations: Partially downloaded image (only header bytes); file corrupted in transfer/storage; JPEG produced by an unusual encoder that this simple parser does not handle.
Related errors
- nao e um JPEG
- máscara com tamanho inconsistente
- não gravei o JPEG
- nenhum objeto encontrado — arquivo vazio ou cifrado
- não achei o catálogo (/Root) do documento
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/3c1bf6635e5fd27c.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/jpeg_pdf.rs:48
if (0xD0..=0xD9).contains(&marker) || marker == 0x01 {
i += 2;
continue;
}
let len = u16::from_be_bytes([data[i + 2], data[i + 3]]) as usize;
let is_sof = matches!(marker, 0xC0..=0xCF) && !matches!(marker, 0xC4 | 0xC8 | 0xCC);
if is_sof {
let height = u16::from_be_bytes([data[i + 5], data[i + 6]]) as u32;
let width = u16::from_be_bytes([data[i + 7], data[i + 8]]) as u32;
let components = data[i + 9];
return Ok(JpegInfo {
width,
height,
components,
});
}
i += 2 + len;
}
Err(anyhow!("JPEG sem cabecalho SOF"))
}
pub fn is_jpeg(data: &[u8]) -> bool {
data.len() > 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF
}
/// Monta o PDF em memória. Página no tamanho da imagem em pontos (72 dpi).
pub fn build_pdf(images: &[Vec<u8>]) -> anyhow::Result<Vec<u8>> {
if images.is_empty() {
return Err(anyhow!("nenhuma imagem"));
}
let mut out: Vec<u8> = Vec::new();
let mut offsets: Vec<usize> = Vec::new();
out.extend_from_slice(b"%PDF-1.4\n%\xE2\xE3\xCF\xD3\n");
// objetos: 1 catalog, 2 pages, depois por imagem: page, xobject, content
let n_pages = images.len();
let obj_page = |i: usize| 3 + i * 3;View on GitHub (pinned to 8600b91f42)