Skip to content

camera.snapshot generates invalid JPEG JFIF headers (JFIFVersion 258) on H.265 streams, causing Telegram integration to fail #575

Description

@bozoclips1-art

When using the camera.snapshot service on a Dahua camera (DH-IPC-HFW2449TL-S-PRO) entity configured with an 1440p H.265 main stream, the generated .jpg file contains an invalid JFIF header version. Specifically, the header injects JFIFVersion: 258 (hex: 0x0102), which does not exist in the official JPEG/JFIF specifications (only 1.00 and 1.01 are valid standards).
While common image viewers and web browsers are forgiving and ignore this bad marker, strict API engines such as the python-telegram-bot engine used by Home Assistant's Telegram integration reject the file completely, throwing an Image_process_failed error. This problem does not occur with snapshots of my dahua doorbell (DHI-VTO2202F-P-S2) H.264 720p

Reproduction Steps:

Configure a Dahua camera with H.265 encoding.
Trigger the camera.snapshot service via Home Assistant to save a frame locally (e.g., /config/www/snapshot.jpg).
Attempt to send this snapshot using the telegram_bot.send_photo action.
The action will fail with: Action failed. Image_process_failed.
(Note: Sending the exact same file using telegram_bot.send_document succeeds, proving paths and access rights are fine, but verifying the image processor engine rejects the byte payload).

Technical Metadata Analysis
A deep structural inspection of the generated snapshot file using a JPEG metadata validation bundle exposes the core parsing failure.
Parser Report Verdict:

piexifjs (JPEG-focused EXIF/JFIF parser): status: "error", detail: "Wrong JPEG data."

Extracted JFIF Section:
json

{
"section": "jfif",
"label": "JFIFVersion",
"keyPath": "JFIFVersion",
"values": [
"258"
]
}

Hex Header Signature:
ff d8 ff e0 00 10 4a 46 49 46 00 01 02 (where 01 02 explicitly reads as version 1.02 instead of standard 1.01 01 01).

Expected Behavior
The integration should encapsulate the pulled H.265 frame into a standard-compliant JPEG envelope mapping a valid web-safe specification version marker inside the APP0/JFIF block (e.g., hardcoding it to version 1.01 -> 0x0101 / 257), or completely omit the invalid version index entirely so external cloud processing hooks (like Telegram) do not drop the payload.

**Additional technical context to help locate the issue in the codebase:
The bug occurs during the encapsulation of the H.265 video frame into the JPEG container for the camera.snapshot service.

The integration/underlying streamer is manually constructing or passing an APP0 marker segment with an invalid version byte sequence:
ff d8 ff e0 00 10 4a 46 49 46 00 01 02 (JFIF v1.02)

To fix this structural error, the code needs to be updated to output standard-compliant JFIF version bytes:
ff d8 ff e0 00 10 4a 46 49 46 00 01 01 (JFIF v1.01)

This minor adjustment to the header generator will ensure full compatibility with strict image processing libraries (like piexifjs used by Telegram) without needing to alter the actual image payload or stream resolution.**

EXIFtool data:

Raw JSON Bundle

{
"name": "Voordeur_20260504_045938.jpg",
"ext": "jpg",
"mimeType": "image/jpeg",
"detectedMime": "image/jpeg",
"size": 612963,
"source": "file",
"url": "",
"signature": {
"ext": "jpg",
"mime": "image/jpeg",
"label": "JPEG (ff d8 ff e0 00 10 4a 46 49 46 00 01 02 00 00 01)"
},
"headHex": "ff d8 ff e0 00 10 4a 46 49 46 00 01 02 00 00 01",
"headHexLong": "ff d8 ff e0 00 10 4a 46 49 46 00 01 02 00 00 01 00 01 00 00 ff db 00 43 00 17 10 12 14 12 0f 17 14 13 14 1a 19 17 1c 23 3a 26 23 20 20 23 48 33 36 2a 3a 55 4a 59 58 53 4a 52 50 5d 69 86 72 5d",
"headText": "......JFIF.............C...............#:&# #H36*:UJYXSJRP]i.r]",
"headTextLong": "......JFIF.............C...............#:&# #H36*:UJYXSJRP]i.r]",
"hashes": {
"md5": "6deebcab106e55f590bab6524b501f75",
"sha1": "53c67ed633c04d516af8569a288065c89b38255b",
"sha256": "6679b3f202031af861c38fdc9b202c42bc04cc0c4ad1cdb28b4d0bc19e9a50a4",
"sha512": "0ade1a9d8308f3c44ae190f9bf18e8af83ea54faeb03d33ec46f3fc7076d01d066777a992f5c0c65cad2670d25e90e614111334629b52c17146e5337636caeaa",
"crc32": "b422b62d",
"adler32": "d550f2ee"
},
"relatedExts": [],
"viewer": {
"slug": "",
"via": "standalone",
"detectedMime": "image/jpeg"
},
"arrayBuffer": {},
"parserReports": [
{
"id": "exifr",
"label": "exifr",
"status": "success",
"note": "Broad parser for TIFF/EXIF, XMP, ICC, IPTC, JFIF, and IHDR.",
"detail": "Parsed structured metadata."
},
{
"id": "piexifjs",
"label": "piexifjs",
"status": "error",
"note": "JPEG-focused EXIF parser and fallback.",
"detail": "Wrong JPEG data."
},
{
"id": "pdf-metadata",
"label": "pdf metadata",
"status": "skipped",
"note": "PDF-specific metadata parser.",
"detail": "Skipped because the file is not PDF."
},
{
"id": "kamadak-exif",
"label": "kamadak-exif (WASM)",
"status": "skipped",
"note": "No browser-ready build is bundled in this repo. Adapter hook is available via window.EXIF_WASM_ADAPTERS.",
"detail": ""
},
{
"id": "rexif",
"label": "rexif (WASM)",
"status": "skipped",
"note": "No browser-ready build is bundled in this repo. Adapter hook is available via window.EXIF_WASM_ADAPTERS.",
"detail": ""
}
],
"metadata": [
{
"section": "jfif",
"label": "JFIFVersion",
"keyPath": "JFIFVersion",
"values": [
"258"
]
},
{
"section": "jfif",
"label": "Resolution Unit",
"keyPath": "ResolutionUnit",
"values": [
"0"
]
},
{
"section": "jfif",
"label": "Thumbnail Height",
"keyPath": "ThumbnailHeight",
"values": [
"0"
]
},
{
"section": "jfif",
"label": "Thumbnail Width",
"keyPath": "ThumbnailWidth",
"values": [
"0"
]
},
{
"section": "jfif",
"label": "XResolution",
"keyPath": "XResolution",
"values": [
"1"
]
},
{
"section": "jfif",
"label": "YResolution",
"keyPath": "YResolution",
"values": [
"1"
]
}
],
"parserResults": {
"exifr": {
"jfif": {
"JFIFVersion": 258,
"ResolutionUnit": 0,
"XResolution": 1,
"YResolution": 1,
"ThumbnailWidth": 0,
"ThumbnailHeight": 0
}
},
"piexifjs": null,
"pdf": null
},
"geoPoint": null
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions