PicScrub logoPicScrub
Terug naar de formaten

JPEG

hier lekt het meest

Een JPEG-bestand bewaart zijn metadata in APPn-segmenten, tussen de header van het bestand en de beeldgegevens. Dit is wat er waar zit, en wat PicScrub met elk stuk doet.

kleurprofiel, blijft als je dat wilt
SOIbegin
APP0JFIF
APP1EXIF
APP1XMP
APP2ICC
APP13IPTC
COMcomment
SOS …je echte foto, onaangeroerd
EOIeind
hier verstoppen GPS en camera zich, weg ermee
byte voor byte identiek

Wat er weggaat

  • EXIF GPS-coördinaten, merk en model van de camera, datum en tijd, belichtingsinstellingen
  • XMP bewerkingsgeschiedenis, gebruikte software, beoordelingen
  • IPTC / Photoshop bijschriften, credits, trefwoorden
  • Comments en ingesloten thumbnails een piepklein kopietje van het origineel dat je uitsnedes en bewerkingen kan overleven

Wat je kunt houden

  • Beeldgegevens altijd onaangeroerd, nooit opnieuw gecodeerd
  • ICC-kleurprofiel optioneel, zodat de kleuren blijven kloppen
  • Oriëntatie optioneel, zodat portretten rechtop blijven staan
  • Copyrightvermelding optioneel, voor fotografen die credits willen zonder coördinaten

De structuur in vogelvlucht

Als je ooit een JPEG in een hex-editor hebt geopend, is het je opgevallen dat hij bestaat uit segmenten die door markers worden gescheiden. Elke marker begint met 0xFF, gevolgd door een byte die vertelt wat voor segment het is. Door dat ontwerp zijn JPEG's relatief eenvoudig te parsen: je zoekt gewoon naar FF-bytes en kijkt wat erachter komt.

Wat privacy betreft is het interessante dat alle metadata (EXIF, GPS, datum en tijd) in die segmenten zit, volledig los van de echte beeldgegevens. Daarom kunnen we de metadata verwijderen zonder de pixels aan te raken of iets opnieuw te comprimeren.

Structuur van een JPEG-bestand

SOI
APP0-15
DQT
SOF
DHT
SOS + Data
EOI
SOI
2 bytes
Begin van de afbeelding (FF D8)
APP0-15
100 bytes
Application markers (metadata)
DQT
130 bytes
Kwantisatietabellen
SOF
20 bytes
Begin van het frame
DHT
420 bytes
Huffman-tabellen
SOS + Data
Variabele lengte
Scangegevens (de afbeelding)
EOI
2 bytes
Einde van de afbeelding (FF D9)

Voorbeeld van een JPEG-header

SOI (begin van de afbeelding)
APP0-marker
Lengte van APP0
JFIF-identifier
JFIF-gegevens
APP1-marker
Lengte van APP1
Exif-identifier
OffsetHexASCII
0000
FFD8FFE000104A464946000101000048
......JFIF.....H
0010
00480000FFE112344578696600000000
.H.....4Exif..

Opbouw van een marker

  • FF xx:Marker (xx geeft het type aan)
  • LL LL:Lengte (2 bytes, big-endian, inclusief zichzelf)
  • Data...:Gegevens van het segment (lengte - 2 bytes)

Volledig overzicht van JPEG-markers

MarkerNaamBeschrijving
FF D8SOIBegin van de afbeelding
FF D9EOIEinde van de afbeelding
FF C0SOF0Begin van het frame (baseline DCT)
FF C2SOF2Begin van het frame (progressieve DCT)
FF C4DHTHuffman-tabel definiëren
FF DBDQTKwantisatietabel definiëren
FF DDDRIRestart-interval definiëren
FF DASOSBegin van de scan (hierna komen de beeldgegevens)
FF FECOMComment (metadata)
FF E0APP0JFIF-marker
FF E1APP1EXIF- / XMP-marker
FF E2APP2ICC-profiel / MPF
FF EDAPP13IPTC / Photoshop
FF EEAPP14Kleurtransformatie van Adobe

Goud = metadata (wordt verwijderd), zonder kleur = structuur die blijft

JFIF tegenover EXIF

Iets wat veel mensen in de war brengt: JPEG-bestanden bevatten vaak twee verschillende metadatastandaarden tegelijk. JFIF was er eerst en regelt de basis, zoals de resolutie. Daarna gingen camera's EXIF-gegevens toevoegen, met alle details over de opname. De meeste moderne JPEG's hebben allebei, en daarom zie je vooraan in het bestand zowel een APP0- als een APP1-marker.

APP0:JFIF

JPEG File Interchange Format. Basisinformatie over de afbeelding.

  • • Versienummer
  • • Pixeldichtheid (DPI)
  • • Beeldverhouding
  • • Optionele thumbnail

APP1:EXIF

Exchangeable Image File Format. Metadata van de camera.

  • • Merk en model van de camera
  • • GPS-coördinaten
  • • Datum en tijd
  • • Belichtingsinstellingen

APP-markers van dichtbij

De JPEG-specificatie reserveerde 16 "application"-markers (APP0 tot en met APP15) die leveranciers naar eigen inzicht mochten gebruiken. In de loop der jaren claimden verschillende organisaties verschillende markers voor hun metadataformaten. Het resultaat is een beetje een rommeltje, maar dan wel een goed gedocumenteerd rommeltje.

Lastig is vooral dat dezelfde marker iets anders kan betekenen, afhankelijk van de inhoud. APP1 kan bijvoorbeeld zowel EXIF- als XMP-gegevens bevatten, dus je moet naar de identifier binnenin kijken om te weten waar je mee te maken hebt.

APP0 (0xFFE0):JFIF

Identifier: JFIF\0. Bevat de versie, de eenheid van de dichtheid, de X/Y-dichtheid en een optionele ingesloten thumbnail. Over het algemeen veilig om te bewaren.

APP1 (0xFFE1):EXIF

Identifier: Exif\0\0. Bevat een complete TIFF-structuur met IFD-entries voor camera-info, GPS-gegevens, datum en tijd, thumbnails en maker notes. Het grootste privacyrisico.

APP1 (0xFFE1):XMP

Identifier: http://ns.adobe.com/xap/1.0/\0. Metadatastandaard van Adobe op basis van XML. Kan bewerkingsgeschiedenis, softwaregegevens en uitgebreide EXIF-gegevens bevatten.

XMP-namespaces
xmp: http://ns.adobe.com/xap/1.0/
xmpMM: http://ns.adobe.com/xap/1.0/mm/
dc: http://purl.org/dc/elements/1.1/
photoshop: http://ns.adobe.com/photoshop/1.0/
tiff: http://ns.adobe.com/tiff/1.0/
exif: http://ns.adobe.com/exif/1.0/

APP1 (0xFFE1):Extended XMP

Identifier: http://ns.adobe.com/xmp/extension/\0. Voor XMP-gegevens groter dan 65KB, verdeeld over meerdere APP1-segmenten.

APP2 (0xFFE2):MPF

Identifier: MPF\0. Multi-Picture Format, voor stereoscopische beelden en panorama's.

APP2 (0xFFE2):ICC-profiel

Identifier: ICC_PROFILE\0. Gegevens voor kleurbeheer. Kan in stukken over meerdere APP2-markers verdeeld zijn. Meestal veilig om te bewaren.

APP13 (0xFFED):IPTC/Photoshop

Identifier: Photoshop 3.0\0. Bevat IPTC-IIM-gegevens met bijschriften, trefwoorden, copyright en gegevens over de maker. Kan informatie over de auteur bevatten.

APP14 (0xFFEE):Adobe

Identifier: Adobe\0. Bevat vlaggen voor de kleurtransformatie (RGB/CMYK). Belangrijk om de kleuren goed weer te geven.

De EXIF-structuur

Hier wordt het interessant (en een beetje vreemd). EXIF-gegevens zijn in feite een piepklein TIFF-bestand dat in je JPEG zit. Ja, echt. Het heeft een eigen header, een eigen byte-volgorde en gebruikt de IFD-structuur (Image File Directory) van TIFF om tags op te slaan.

Het eerste wat je na de identifier "Exif" ziet, is een TIFF-header die aangeeft of de gegevens little-endian zijn (Intel, "II") of big-endian (Motorola, "MM"). Zit je daar naast, dan is elk getal onzin, dus dat is het eerste wat elke parser controleert.

TIFF-header (8 bytes)

Byte-volgorde (II = little-endian)
Magic number (42)
Offset van IFD0
OffsetHexASCII
0000
49492A0008000000
II*.....

II = Intel (little-endian), MM = Motorola (big-endian)

Opbouw van een IFD-entry (12 bytes)

Tag IDTypeCountValue/Offset
2 bytes2 bytes4 bytes4 bytes

Belangrijke IFD-entries

0x010F:Make
0x0110:Model
0x0132:DateTime
0x8769:ExifIFDPointer
0x8825:GPSInfoIFDPointer
0x927C:MakerNote

Hoe PicScrub JPEG verwerkt

De aanpak is vrij rechttoe rechtaan: we lopen het bestand marker voor marker door, houden de markers die nodig zijn om de afbeelding te tonen en slaan de markers met metadata over. Omdat we de gecomprimeerde beeldgegevens nooit aanraken, is er geen enkel kwaliteitsverlies.

De kern is dat de markerstructuur van JPEG dit makkelijk maakt. We hoeven niets te begrijpen van DCT-coëfficiënten of Huffman-tabellen. We hoeven alleen te herkennen welke segmenten metadata zijn en welke niet.

1

De header controleren

Nagaan of de SOI-marker (FF D8) aan het begin van het bestand staat

2

De markers parsen

Elke marker op volgorde lezen en het type en de lengte eruit halen

3

De metadata herkennen

De identifiers in de APP-segmenten nalopen (EXIF, XMP, IPTC en zo verder)

4

Selectief kopiëren

Segmenten zonder metadata naar het resultaat kopiëren, de rest overslaan

Wat er blijft

  • • SOI/EOI-markers (verplicht)
  • • DQT (kwantisatietabellen)
  • • SOF (frameheader)
  • • DHT (Huffman-tabellen)
  • • SOS en scangegevens (de echte afbeelding)
  • • Optioneel: het ICC-kleurprofiel (in te stellen)

Wat er weggaat

  • • APP1 EXIF (camera, GPS, datum en tijd)
  • • APP1 XMP (metadata van bewerkingen)
  • • APP13 IPTC (bijschriften, auteur)
  • • COM-markers (comments)
  • • EXIF-thumbnails

Overzicht van EXIF-tags

Niet elke EXIF-tag is even gevoelig. Sommige, zoals de belichtingsinstellingen, zijn tamelijk onschuldig. Andere, zoals serienummers en namen van eigenaren, wijzen rechtstreeks naar jou of naar je apparatuur. Dit zijn de tags die wij als risicovol beschouwen:

Tag-IDNaamPrivacyrisico
0x9003DateTimeOriginalHoog
0x9004DateTimeDigitizedHoog
0x9010OffsetTimeGemiddeld
0x9286UserCommentHoog
0x927CMakerNoteHoog
0xA420ImageUniqueIDHoog
0xA430CameraOwnerNameHoog
0xA431BodySerialNumberHoog
0xA434LensModelGemiddeld
0xA435LensSerialNumberHoog
0xFDE8OwnerNameHoog
0xFDE9SerialNumberHoog
Bekijk alle tags met camera-instellingen (niet herleidbaar)
0x829A ExposureTime
0x829D FNumber
0x8822 ExposureProgram
0x8827 ISOSpeedRatings
0x9201 ShutterSpeedValue
0x9202 ApertureValue
0x9203 BrightnessValue
0x9204 ExposureBiasValue
0x9207 MeteringMode
0x9208 LightSource
0x9209 Flash
0x920A FocalLength
0xA001 ColorSpace
0xA002 PixelXDimension
0xA003 PixelYDimension
0xA402 ExposureMode
0xA403 WhiteBalance
0xA405 FocalLengthIn35mmFilm
0xA406 SceneCaptureType

Overzicht van GPS-tags

GPS-gegevens staan in een eigen sub-IFD, waar tag 0x8825 in de hoofd-IFD naar verwijst. Bestaat die pointer, dan zit er locatiedata in je afbeelding. Moderne smartphones zijn hier bijzonder fanatiek in, vaak met genoeg precisie om aan te wijzen waar je precies stond.

Tag-IDNaamBeschrijving
0x0000GPSVersionIDVersie van de GPS-tags
0x0001GPSLatitudeRefN of S
0x0002GPSLatitudeGraden, minuten, seconden
0x0003GPSLongitudeRefE of W
0x0004GPSLongitudeGraden, minuten, seconden
0x0005GPSAltitudeRefBoven of onder zeeniveau
0x0006GPSAltitudeMeters
0x0007GPSTimeStampTijd in UTC
0x001DGPSDateStampDatum in UTC
0x0012GPSMapDatumGebruikt geodetisch datum
0x001BGPSProcessingMethodGPS/CELLID/WLAN/MANUAL
0x001CGPSAreaInformationNaam van de locatie

Overzicht van IPTC-tags

IPTC is bedacht zodat persbureaus bijschriften, credits en copyrightgegevens in een foto konden zetten. Het staat in APP13, met de identifier "Photoshop 3.0" (ja, Adobe nam het over). Heb je ooit copyrightgegevens of trefwoorden toegevoegd in Lightroom of Photoshop, dan belanden die hier.

0x0250 By-line (auteur)
0x0255 By-line Title (functie van de auteur)
0x025A City (stad)
0x025C Sub-location (plek binnen de stad)
0x025F Province/State (provincie of staat)
0x0265 Country Name (land)
0x0274 Copyright Notice (copyrightvermelding)
0x0276 Contact (contactgegevens)
0x0237 Date Created (aanmaakdatum)
0x023C Time Created (aanmaaktijd)
0x0278 Caption/Abstract (bijschrift)
0x0219 Keywords (trefwoorden)