PNG

PNG

Portable Network Graphics β€” verlustfreie Kompression mit Chunks

PNG (Portable Network Graphics) wurde 1996 als patentfreier Ersatz fΓΌr GIF entworfen. Eine PNG-Datei beginnt immer mit einer 8 Byte langen Signatur und besteht danach aus einer Folge von β€žChunksβ€œ.

Jeder Chunk hat denselben Aufbau: 4 Byte LΓ€nge, 4 Byte Typ, die Nutzdaten und eine 4 Byte CRC-PrΓΌfsumme. Genau drei Chunk-Typen sind Pflicht: IHDR (Kopf), IDAT (Bilddaten) und IEND (Ende).

Die Bilddaten in IDAT werden mit DEFLATE (zlib) verlustfrei komprimiert β€” vorher wird jede Bildzeile durch einen β€žFilterβ€œ vorhergesagt, um die Kompression zu verbessern.

Magic Number: 89 50 4E 47 0D 0A 1A 0A Β β†’Β  \x89 P N G \r \n \x1a \n

🧩 Aufbau der Datei

So liegen die Bestandteile einer PNG-Datei nacheinander im Speicher.

SignaturKopf/StrukturMetadatenBilddatenEnde
PNG-Signatur
8 Byte
89 50 4E 47 0D 0A 1A 0A
Feste Magic Number. Das \x89 verhindert Verwechslung mit Text, CR/LF erkennt fehlerhafte Zeilenenden-Übertragung.
IHDR-Chunk
25 Byte
00 00 00 0D 49 48 44 52 …
Image Header: Breite, HΓΆhe, Bittiefe, Farbtyp, Kompression, Filter, Interlace.
Optionale Chunks
variabel
PLTE, gAMA, pHYs, tEXt …
Palette, Gamma, physische AuflΓΆsung, Textkommentare usw. (Reihenfolge teils festgelegt).
IDAT-Chunk(s)
variabel
49 44 41 54 …(zlib)…
Image Data: zlib/DEFLATE-komprimierte, gefilterte Pixelzeilen. Darf in mehrere Chunks aufgeteilt sein.
IEND-Chunk
12 Byte
00 00 00 00 49 45 4E 44 AE 42 60 82
Image End: leerer Chunk, markiert das Dateiende. CRC ist konstant.

πŸ“ Ablaufdiagramm (ASCII)

Schematischer Gesamtaufbau auf einen Blick.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ 89 50 4E 47 0D 0A 1A 0A   ← 8-Byte Signatur                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”Œβ”€β”€ Chunk-Schema (fΓΌr jeden Chunk identisch) ─────────────┐ β”‚
β”‚ β”‚  [LΓ€nge 4B] [Typ 4B] [Daten …] [CRC-32 4B]              β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ IHDR  β†’  Breite/HΓΆhe/Bittiefe/Farbtyp                        β”‚
β”‚ gAMA  β†’  optional: Gamma                                     β”‚
β”‚ PLTE  β†’  optional: Farbpalette (bei Farbtyp 3 Pflicht)       β”‚
β”‚ IDAT  β†’  zlib( filter(zeile_0) + filter(zeile_1) + … )       β”‚
β”‚ IDAT  β†’  (kann fortgesetzt werden)                           β”‚
β”‚ IEND  β†’  Ende                                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“Š Tabellen & Referenz

Pflicht- & wichtige Chunks

TypPflichtBedeutung
IHDRJaBildkopf: Abmessungen & Farbcodierung
PLTEBedingtFarbpalette (Pflicht bei Farbtyp 3)
IDATJaKomprimierte Bilddaten
IENDJaDateiende-Markierung
tRNSNeinTransparenz fΓΌr Paletten/Graustufen
gAMA / sRGBNeinFarb-/Gamma-Verwaltung
tEXt / zTXtNeinTextuelle Metadaten

Farbtypen im IHDR

WertFarbtypKanΓ€le
0Graustufen1 (G)
2Truecolor (RGB)3 (R,G,B)
3Palette (indexiert)1 (Index β†’ PLTE)
4Graustufen + Alpha2 (G,A)
6Truecolor + Alpha4 (R,G,B,A)

⌨️ C-Strukturen & Auslese-Code

Einfache C-Strukturen, die exakt dem Byte-Layout entsprechen, plus Beispielcode zum Einlesen.

PNG-Signatur & Chunk-Kopf Β· c
#include <stdint.h>

/* Die ersten 8 Bytes jeder PNG-Datei */
static const uint8_t PNG_SIGNATURE[8] = {
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
};

/* Jeder Chunk hat exakt diesen Rahmen (Big-Endian!) */
typedef struct {
    uint32_t length;     /* LΓ€nge des data-Feldes in Byte   */
    char     type[4];    /* z. B. "IHDR", "IDAT", "IEND"     */
    /* uint8_t data[length];  -- folgt direkt, variable LΓ€nge */
    uint32_t crc;        /* CRC-32 ΓΌber type[] + data[]      */
} png_chunk_header_t;

ℹ️ Achtung: Alle Mehrbyte-Zahlen in PNG sind Big-Endian (Netzwerk-Byteorder).

IHDR β€” Bildkopf (13 Byte Nutzdaten) Β· c
#pragma pack(push, 1)         /* keine Ausrichtungs-LΓΌcken */
typedef struct {
    uint32_t width;            /* Bildbreite  (Big-Endian)     */
    uint32_t height;           /* BildhΓΆhe    (Big-Endian)     */
    uint8_t  bit_depth;        /* 1,2,4,8 oder 16 Bit/Sample   */
    uint8_t  color_type;       /* 0,2,3,4,6 (siehe Tabelle)    */
    uint8_t  compression;      /* immer 0 = DEFLATE            */
    uint8_t  filter_method;    /* immer 0 = adaptive Filter    */
    uint8_t  interlace;        /* 0 = keins, 1 = Adam7         */
} png_ihdr_t;
#pragma pack(pop)
Signatur prΓΌfen & IHDR auslesen Β· c
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>  /* ntohl: Big-Endian -> Host */

int read_png_header(FILE *f, png_ihdr_t *out) {
    uint8_t sig[8];
    if (fread(sig, 1, 8, f) != 8) return -1;
    if (memcmp(sig, PNG_SIGNATURE, 8) != 0) return -1; /* keine PNG */

    png_chunk_header_t ch;
    fread(&ch.length, 4, 1, f);
    fread(ch.type,    1, 4, f);
    if (memcmp(ch.type, "IHDR", 4) != 0) return -1;    /* IHDR fehlt */

    fread(out, 1, 13, f);
    out->width  = ntohl(out->width);   /* Byteorder korrigieren */
    out->height = ntohl(out->height);
    printf("PNG %ux%u, %d Bit, Farbtyp %d\n",
           out->width, out->height, out->bit_depth, out->color_type);
    return 0;
}

ℹ️ Big-Endian-Werte mΓΌssen auf Little-Endian-Maschinen (x86) getauscht werden.

πŸ—œοΈ Kompression

PNG nutzt das DEFLATE-Verfahren (LZ77 + Huffman, ΓΌber die zlib). Vor der Kompression wird jede Bildzeile mit einem von fΓΌnf Filtern (None, Sub, Up, Average, Paeth) vorhergesagt. Filter erzeugen kleine Differenzwerte, die sich besonders gut komprimieren lassen β€” daher ist PNG verlustfrei und trotzdem kompakt.

πŸ’‘ Wissenswert

✨Die Signatur enthΓ€lt bewusst \r\n und \n, um beschΓ€digte Text-Übertragungen (CRLF↔LF) zu erkennen.
✨Groß-/Kleinschreibung im Chunk-Typ kodiert Eigenschaften: Bit 5 des 1. Buchstabens = β€žkritisch vs. optionalβ€œ.
✨PNG kann keine Animationen β€” dafΓΌr gibt es die Erweiterung APNG mit zusΓ€tzlichen fcTL/fdAT-Chunks.
← ZurΓΌck zur Übersicht