Het HEIC-formaat
High Efficiency Image Container
De ISOBMFF-container
Heb je ooit met MP4-video's gewerkt, dan komt HEIC je bekend voor. Apple koos het ISO Base Media File Format (ISOBMFF) als container voor HEIC, waardoor het meer familie is van videoformaten dan van klassieke afbeeldingsformaten als JPEG of PNG.
Het formaat bestaat uit geneste "boxes" (ook wel atoms genoemd) met typecodes van vier tekens. Een verrassend elegant ontwerp: het maakt ingewikkelde hiërarchieën mogelijk en blijft toch redelijk eenvoudig te parsen, zodra je de basis doorhebt.
Structuur van een HEIC-bestand
De HEIC-header (de ftyp-box)
| Offset | Hex | ASCII | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0000 | 000000186674797068656963 | ....ftypheic | |||||||||||
| 000C | 000000006D69663168656963 | ....mif1heic | |||||||||||
Opbouw van een box
Is size = 1, dan volgt er na het type een uitgebreide grootte van 8 bytes. Is size = 0, dan loopt de box door tot het einde van het bestand.
De belangrijkste boxes
De hiërarchie van boxes in een HEIC-bestand kan behoorlijk diep worden. Anders dan bij JPEG, waar metadata op voorspelbare offsets staat, begraaft HEIC zijn metadata een paar lagen diep in een geneste structuur. Zo passen de belangrijkste stukken in elkaar.
ftyp:het bestandstype
De eerste box in het bestand. Bevat de major brand en de compatible brands. Nodig om het formaat te herkennen.
heic heix hevc hevx heim heis hevm hevs mif1 msf1meta:de container met metadata
Bevat alle metadata, inclusief de locaties van items, hun properties en de koppelingen daartussen. Hier zit de EXIF- en XMP-data.
meta (container met metadata) ├── hdlr (verwijzing naar de handler) ├── pitm (ID van het primaire item) ├── iloc (locaties van items → offsets in mdat) │ └── entries met [item_id, offset, length] ├── iinf (info over items → hier vind je het item 'Exif') │ └── infe-entries met de itemtypes ├── iprp (properties van items) │ ├── ipco (container met properties) │ │ ├── hvcC (HEVC-decoderconfiguratie) │ │ ├── ispe (afmetingen van de afbeelding) │ │ ├── colr (ICC-profiel, offset+12) │ │ ├── Exif (EXIF in TIFF-formaat) │ │ └── pixi (informatie over de pixels) │ └── ipma (koppelingen van properties) └── iref (verwijzingen tussen items)
mdat:de mediagegevens
Bevat de echte beeldgegevens, gecodeerd met HEVC. De iloc-box in meta geeft de offsets in mdat.
Metadata in HEIC
Ben je de APP-markers van JPEG gewend, dan pakt HEIC het heel anders aan. In plaats van markers achter elkaar aan het begin van het bestand, zit de metadata als "item properties" in de meta-box. De EXIF-gegevens zelf staan nog altijd in het vertrouwde TIFF-formaat, maar je moet eerst door de hiërarchie van boxes navigeren om ze te vinden.
De EXIF-property
Staat in ipco (de container met item properties), met het type "Exif". Bevat gewone EXIF-gegevens in TIFF-formaat, net als bij JPEG.
De XMP-property
Metadata op basis van XML, opgeslagen als property van het type "mime", met content-type "application/rdf+xml".
Het ICC-profiel
Het kleurprofiel, opgeslagen als "colr"-box met het type "prof".
Waarom die offsets ertoe doen
De iloc-box bevat exacte byte-offsets die naar mdat wijzen. Verandert de grootte van ook maar één box (bijvoorbeeld doordat er metadata weggaat), dan moeten al die offsets opnieuw worden berekend, anders is het bestand onleesbaar.
Anonimiseren zonder kwaliteitsverlies
Hier wordt HEIC lastig. Het formaat is ontworpen om beeld en video efficiënt op te slaan, niet om makkelijk met metadata te kunnen schuiven.
Het probleem
Doordat HEIC helemaal op offsets leunt, is bytes weghalen riskant. De iloc-box bevat exacte byte-offsets die naar mdat wijzen. Haal je ook maar één box weg, dan kloppen die offsets niet meer en gaat de afbeelding niet meer open.
Overschrijven met nullen
In plaats van de metadataboxes weg te halen, overschrijft PicScrub de inhoud ervan met nullen. De structuur en de groottes van de boxes blijven zo intact.
Na: [Exif][0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00...]
Waarom overschrijven met nullen?
- • Het bestand blijft heel:alle offsets blijven kloppen
- • Geen hercompressie:de beeldgegevens blijven onaangeroerd
- • De metadata is vernietigd:nullen zeggen niets
- • Omkeerbaar?:nee, wat overschreven is, is weg
Hoe PicScrub HEIC verwerkt
De structuur van boxes parsen
ftyp en meta recursief doorlopen en alle boxes in kaart brengen
De metadata opsporen
De Exif- en XMP-properties in de ipco-container opzoeken
De metadata op nul zetten
De inhoud van de metadataboxes met nullen overschrijven
De structuur behouden
De headers, groottes en alle offsets van de boxes ongewijzigd laten
Let op de bestandsgrootte
Omdat PicScrub met nullen overschrijft in plaats van te verwijderen, is het resultaat even groot als het origineel. De ruimte van de metadata blijft bestaan, maar staat vol nullen.
HEIC, HEIF en AVIF
De namen zorgen voor verwarring, dus even helder: HEIF is de container, terwijl HEIC en AVIF aangeven met welke codec de afbeelding in die container is gecomprimeerd.
| Formaat | Container | Codec | Gebruikt door |
|---|---|---|---|
| HEIC | HEIF | HEVC (H.265) | Apple-apparaten |
| HEIF | HEIF | Verschillende | Algemene container |
| AVIF | HEIF | AV1 | Het web (royaltyvrij) |
Alle drie gebruiken ze dezelfde ISOBMFF/HEIF-containerstructuur, dus de aanpak van PicScrub werkt voor alle drie.