Repository navigation
Set width/height on outgoing image attachments - #2093
Merged
Merged
Conversation
createAttachmentStream() never populated SignalServiceAttachmentStream's width/height fields, even though the Builder has supported them since at least the currently pinned libsignal-service version. Without them, other Signal clients render outgoing image attachments as a square-cropped thumbnail instead of their actual aspect ratio. Probe dimensions via ImageIO for image/* attachments up to 20MiB (buffered in memory only for that check) and pass them through to the builder. Falls back to width/height 0 (today's behavior) for non-images, oversized files, or anything ImageIO can't parse.
AsamK
approved these changes
Jul 29, 2026
zdiemer
added a commit
to zdiemer/selfhosted
that referenced
this pull request
Aug 13, 2026
Sending any photo over Signal failed. 0.14.7 added "Set width/height on outgoing image attachments" (AsamK/signal-cli#2093), which reads the image through javax.imageio β and the GraalVM native build we use ships no ImageIO/AWT at all. A regression landing in exactly the version we pinned. Confirmed against the live daemon: a text attachment by path succeeds, the same photo declared image/jpeg fails with "Could not initialize class javax.imageio.ImageIO", and the release notes name the feature that added the call. The native tarball is a single binary β nothing was being discarded by the Dockerfile's targeted extract, so there were no AWT libs to restore. 0.14.6 does not read dimensions and is five weeks older, well inside what Signal's servers accept. The untyped data URI fallback from the previous commit stays as a safety net, but it is not a fix: Signal renders application/octet-stream as a "MacBinary archive" file card rather than an inline image, which is what the first real send produced. My earlier reading that it previewed correctly was wrong. The JVM distribution plus a Java 21 runtime is the other way out and would even shrink the image ~200MB, but it replaces the daemon this surface talks over, to recover a dimensions field. Documented in the Dockerfile with what to check before anyone bumps this again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
elShiaLabeouf
added a commit
to elShiaLabeouf/signal-cli
that referenced
this pull request
Aug 29, 2026
Extends the outgoing attachment dimension probe (added for images in AsamK#2093) to video: MP4/QuickTime/M4V via ISO-BMFF box walking (moov > trak > tkhd, honoring the rotation matrix for portrait video) and WebM/Matroska via EBML parsing (Segment > Tracks > TrackEntry > Video). No new dependencies, no frame decoding, same 0/0-on-failure posture as the image probe. Recipients currently see outgoing videos as a generic file row instead of a video tile with a play button until they download it, because signal-cli sends no width/height metadata for video attachments (only images get this today). Setting real dimensions is a prerequisite for clients to render a proper preview tile. Off by default behind a new --set-video-preview flag (also available over JSON-RPC as setVideoPreview), since it changes outgoing attachment metadata that existing automated workflows may depend on staying byte-for-byte the same. Threaded through Message -> AttachmentHelper -> AttachmentUtils; image probing is unaffected.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
AttachmentUtils.createAttachmentStream()never populatesSignalServiceAttachmentStream'swidth/heightfields, even though theSignalServiceAttachment.Builderhas supportedwithWidth()/withHeight()since at least the currently-pinnedlibsignal-serviceversion (2.15.3_unofficial_149). Without those fields set, other Signal clients render outgoing image attachments as a square-cropped thumbnail instead of their real aspect ratio, since the receiving client has no dimension metadata to lay the attachment out correctly.This PR probes the attachment's dimensions with
ImageIOwhen the content type isimage/*and the payload is under 20MiB, then passes them through to the builder. Behavior is unchanged for everything else:ImageIOcan't parse: falls back to width/height 0, attachment still sends normally.Test plan
./gradlew :lib:buildpasses (existing test suite green)AttachmentUtilsTestwith two cases:width/heightcome back correctly and the uploaded stream bytes match the source image exactlyπ€ Generated with Claude Code