feat(uploads): DNG / camera-RAW support via embedded-preview extraction (#821)
Sharp's bundled libvips has no raw loader, so a DNG can't be thumbnailed directly. This adds a preview-extraction step so RAW/DNG uploads get a proper thumbnail + gallery preview while the original RAW is kept for download. - imageProcessor: isRawFilename() + extractRawPreview() (exiftool extracts the embedded full-res JPEG — JpgFromRaw → PreviewImage → ThumbnailImage, validated with sharp) + withProcessableImage() which is a pass-through for ordinary images and swaps in the extracted JPEG for RAW. Wired into ingest (photoProcessor) and all three on-demand generators (ensureThumbnail/Hero/ Preview). generateHeroImage/generatePreviewImage gained outputBasename so RAW-derived outputs stay named after the source. - Dockerfile: add exiftool (confirmed present in Alpine v3.24 community). - Format maps: dng → image/x-adobe-dng in uploadSettings.js and fileTypes.ts; ALLOWED_MEDIA_TYPES gains a DNG entry (TIFF magic numbers) so it passes the security file-validator. Strictly gated by extension: nothing in this path runs for jpg/png/webp/etc, so existing photos are unaffected. If extraction fails (corrupt RAW, no embedded preview), the photo is marked 'failed' with a clear error — same as any unreadable upload. Verification boundary (please validate on a real DNG after the image rebuilds): the exiftool extraction itself couldn't be exercised in the dev sandbox (exiftool isn't a dev dependency and there's no DNG fixture). Unit tests cover the gating (RAW detection + non-RAW pass-through + clean failure without exiftool); existing processPhoto tests still pass. Known limitation: a DNG is only accepted when the browser reports its MIME as image/x-adobe-dng (Chrome does); browsers that send an empty type reject it client- and server-side — a follow-up can add extension-based acceptance for the RAW set. Companion to the HEIC/dynamic-hint PR; targets main only.
This commit is contained in:
+4
-1
@@ -67,8 +67,11 @@ RUN npm install -g npm@11
|
||||
# malicious) PDF. pdftoppm does not execute embedded JS or fetch remote
|
||||
# resources, so it doubles as the SSRF/phone-home guard for untrusted inbound
|
||||
# documents (see docs/accounting-inbound-invoices.md).
|
||||
# exiftool extracts the embedded full-res JPEG preview from RAW/DNG uploads
|
||||
# (Apple ProRAW etc.) — sharp's libvips has no raw loader, so the pipeline
|
||||
# thumbnails/displays that preview while keeping the original for download.
|
||||
RUN apk add --no-cache dumb-init postgresql-client ffmpeg su-exec \
|
||||
fontconfig ttf-dejavu ttf-liberation poppler-utils && \
|
||||
fontconfig ttf-dejavu ttf-liberation poppler-utils exiftool && \
|
||||
fc-cache -f
|
||||
|
||||
# Create non-root user
|
||||
|
||||
Reference in New Issue
Block a user