Skip to content

fix(latex): keep CMYK JPEG figures - #4696

Merged
PeterStaar-IBM merged 2 commits into
docling-project:mainfrom
usmanmateen:fix-latex-cmyk-figures
Oct 9, 2026
Merged

PeterStaar-IBM merged 2 commits into
docling-project:mainfrom
usmanmateen:fix-latex-cmyk-figures

Conversation

@usmanmateen

Copy link
Copy Markdown
Contributor

Issue resolved by this Pull Request:
Resolves #4695

The includegraphics branch in handlers/macros.py passed the opened figure straight to ImageRef.from_pil, which can't write CMYK as PNG. The except Exception turned that into a debug log, so a CMYK JPEG figure was added as a picture without an image. This normalizes the figure with normalize_image_for_png first, the same way the XLSX (#4664), OpenDocument (#4666), DOCX and PPTX backends do. RGB, RGBA and other PNG-compatible figures pass through unchanged.

Checklist:

  • Documentation has been updated, if necessary. (not needed)
  • Examples have been added, if necessary. (not needed)
  • Tests have been added, if necessary.

Review evidence:

  • The reproduction from LaTeX: CMYK JPEG figures are dropped #4695 prints ConversionStatus.SUCCESS [True, False] on main and ConversionStatus.SUCCESS [True, True] with this change.
  • test_latex_includegraphics_cmyk_jpeg converts a .tex file with one CMYK JPEG figure and checks that the picture has an RGB image with the expected colour. It fails on main (picture.get_image(doc) is None) and passes here.
  • pytest tests/test_latex: 134 passed.
  • ruff format --check, ruff check and tach check pass. ty check reports no diagnostics on the changed lines.

Not changed: a str source (convert("paper.tex")) still gives no figure an image, because the backend gets a stream and can't resolve relative files. That is #4694, which I'll fix in a separate PR.

🤖 Generated with Claude Code

PNG can't store CMYK, so ImageRef.from_pil raised for a CMYK
\includegraphics figure and the handler added the picture without an
image, with only a debug log. Normalize the figure first, like the
XLSX, OpenDocument, DOCX and PPTX backends do.

Resolves docling-project#4695

Signed-off-by: usmanmateen <usmanmateen255@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @usmanmateen, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) bug Something isn't working labels Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

AI triage (advisory)

Checked commit 46d0517068. The analysis read the diff only. It did not run code from this pull request.

This pull request normalizes CMYK JPEG figures before image conversion in the LaTeX backend. This change prevents dropped figures during document export.

CI safety: no concern found. A maintainer must still approve CI.

1 related pull request(s) in the same code
PR State Signal Assessment
#4697 open also references issue #4694 related: Both PRs update macro processing in the LaTeX backend, but PR 4697 resolves relative file paths for string inputs.

The ai:* labels are advisory. They do not approve CI and they do not add tests:full. A new push runs this check again.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI first review (advisory): no blocking issue found

This review covers the full diff at 762d5019fb. It read the code only. It did not run tests or code from this pull request.

The PR fixes CMYK JPEG figures being silently dropped by the LaTeX backend. It applies normalize_image_for_png before ImageRef.from_pil, matching the pattern already used in the DOCX, PPTX, XLSX, and ODF backends. A regression test constructs a synthetic CMYK JPEG, converts it through the backend, and checks that the resulting picture has an RGB image. The change is small and low-risk; the main review points are the test robustness and one minor redundancy.

A maintainer makes the merge decision. This review never approves the pull request.

Comment thread tests/test_latex/test_figures.py Outdated
Comment thread tests/test_latex/test_figures.py Outdated
@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 8, 2026
The CMYK colour decodes to exactly (255, 0, 0), so compare it directly,
like the OpenDocument test does, instead of loose channel thresholds.

Signed-off-by: usmanmateen <usmanmateen255@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) and removed ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) labels Oct 8, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI first review (advisory): no blocking issue found

This review covers the changes since 762d5019fb at 46d0517068. It read the code only. It did not run tests or code from this pull request.

This PR fixes a bug where CMYK JPEG figures in LaTeX documents were silently dropped because ImageRef.from_pil cannot write CMYK as PNG. The fix applies normalize_image_for_png before the ImageRef.from_pil call, matching the pattern already used in XLSX, ODF, DOCX, and PPTX backends. The incremental update addresses both nit findings from the previous review: it replaces the redundant isinstance guard and loose colour-threshold assertions with a single exact equality check.

A maintainer makes the merge decision. This review never approves the pull request.

@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 8, 2026
@usmanmateen

Copy link
Copy Markdown
Contributor Author

cc @PeterStaar-IBM @DanielNg0729: same normalize_image_for_png fix as #4664 / #4666, this time for LaTeX \includegraphics figures. Happy to adjust anything.

@DanielNg0729 DanielNg0729 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @usmanmateen, thank you for the fix! I noticed there are a few other fixes addressing the same normalize_image_for_png issue. If there are any other cases where this issue still occurs, would you mind including those fixes in this PR as well? That way, we can hopefully address the issue comprehensively in one place. Thanks!

@usmanmateen

Copy link
Copy Markdown
Contributor Author

Thanks @DanielNg0729! I went through every ImageRef.from_pil call on main (3181d9f) to look for other places with the same problem. With this PR, LaTeX was the last backend that passed a user-supplied image to from_pil without normalizing it. The others are covered like this:

Already normalized on main: XLSX (#4664), ODF pictures through _image_ref_from_odf_image (#4666), DOCX and PPTX (#4598).

Covered by open PRs:

Not affected, because the image is never in a mode PNG can't store: PDF, Tectonic and LibreOffice chart renders (pypdfium2 output), the HTML page screenshot and video frames (both .convert("RGB")), image input files (_to_rgb in image_backend.py), and the service client, which re-embeds images the server already wrote.

One case I left alone: METS/GBS page scans are opened without conversion, but they are page images rather than pictures, and the test archives are 1-bit TIFFs, which PNG stores as is. I didn't find a real METS/GBS source in another mode, so I didn't change it.

So this PR doesn't need more changes for now. If you'd rather have the #4683 / #4686 changes in one place, I'm happy to coordinate with their authors, but I didn't want to copy their work here.

@codecov

codecov Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@usmanmateen

Copy link
Copy Markdown
Contributor Author

run-tests-core was cancelled by the 45-minute job timeout, not by a test failure. The runner spent about 37 minutes in the setup step (Preconfiguring packages), so pytest started at 17:31 and was stopped at 63% (17:37). Every test that ran passed, including the first LaTeX tests. check and ci-status only fail because of that job. Could a maintainer re-run the failed jobs? I can't re-run them from a fork. Thanks!

@PeterStaar-IBM PeterStaar-IBM left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@PeterStaar-IBM
PeterStaar-IBM merged commit 9943158 into docling-project:main Oct 9, 2026
48 of 51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LaTeX: CMYK JPEG figures are dropped

3 participants