Dans mon projet, j'ai besoin de savoir à quoi ressemble un en-tête zlib
. J'ai entendu dire que c'était assez simple, mais je ne trouve aucune description de l'en-tête zlib.
Par exemple, contient-il un nombre magique?
0 1
+---+---+
|CMF|FLG|
+---+---+
CMF (méthode de compression et indicateurs) Cet octet est divisé en une méthode de compression de 4 bits et un champ d’information de 4 bits En fonction de la méthode de compression.
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
CM (Méthode de compression) Identifie la méthode de compression utilisée dans le fichier. CM = 8
indique la méthode de compression "deflate" avec une taille de fenêtre supérieureà 32K. C'est la méthode utilisée par gzip et PNG et presque tout le reste. CM = 15 est réservé.
CINFO (Informations de compression) Pour CM = 8, CINFO est le logarithme en base 2 de la fenêtre LZ77 Taille moins huit (CINFO = 7 indique une taille de fenêtre de 32 Ko). Les valeurs De CINFO supérieures à 7 ne sont pas autorisées dans cette version de la spécification CINFO n'est pas défini dans cette spécification pourCM différent de 8.
En pratique, cela signifie que le premier octet est presque toujours 78
(hex)
FLG (FLaG) Cet octet de drapeau est divisé comme suit:
bits 0 to 4 FCHECK (check bits for CMF and FLG)
bit 5 FDICT (preset dictionary)
bits 6 to 7 FLEVEL (compression level)
La valeur FCHECK doit être telle que CMF et FLG, vus sous la forme , Un entier non signé de 16 bits stocké dans l'ordre MSB (CMF * 256 + FLG), .__ est un multiple de 31.
FLEVEL (niveau de compression) Ces indicateurs sont disponibles pour une utilisation avec des méthodes de compression spécifiques La méthode "deflate" (CM = 8
) définit ces indicateurs comme suit:
0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm
en-têtes magiques zlib
78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression
Voici le format de données compressé Zlib.
+---+---+
|CMF|FLG| (2 bytes - Defines the compression mode - More details below)
+---+---+
+---+---+---+---+
| DICTID | (4 bytes. Present only when FLG.FDICT is set.) - Mostly not set
+---+---+---+---+
+=====================+
|...compressed data...| (variable size of data)
+=====================+
+---+---+---+---+
| ADLER32 | (4 bytes of checksum)
+---+---+---+---+
La plupart du temps, FLG.FDICT
(indicateur de dictionnaire) n'est pas défini. Dans de tels cas, la variable DICTID
n'est tout simplement pas présente. Donc, l’audition totale n’est que de 2 octets.
Les valeurs d'en-tête (CMF
et FLG
) sans dictionnaire sont définies comme suit.
CMF | FLG
0x78 | 0x01 - No Compression/low
0x78 | 0x9C - Default Compression
0x78 | 0xDA - Best Compression
Plus sur ZLIB RFC
En-têtes ZLIB/GZIP
Level | ZLIB | GZIP
1 | 78 01 | 1F 8B
2 | 78 5E | 1F 8B
3 | 78 5E | 1F 8B
4 | 78 5E | 1F 8B
5 | 78 5E | 1F 8B
6 | 78 9C | 1F 8B
7 | 78 DA | 1F 8B
8 | 78 DA | 1F 8B
9 | 78 DA | 1F 8B
Deflate n'a pas d'en-têtes communs
L'en-tête ZLIB (tel que défini dans RFC1950 ) est une valeur big-endian de 16 bits. Il contient ces champs du plus au moins significatif:
CINFO
(bits 12-15)
Indique la taille de la fenêtre sous forme d'une puissance de deux, comprise entre 0 (256) et 7 (32768). 7 est habituel. Des valeurs plus élevées ne sont pas autorisées.
CM
(bits 8-11)
La méthode de compression. Seul Deflate (8) est autorisé.
FLEVEL
(bits 6-7)
Indique approximativement le niveau de compression, de rapide/faible (0) à lent/élevé (3)
FDICT
(bit 5)
Indique si un dictionnaire prédéfini est utilisé. Ceci est généralement 0. 1 est techniquement autorisé, mais je ne connais aucun format Deflate définissant des dictionnaires prédéfinis.
FCHECK
(bits 0 à 4)
Une somme de contrôle, dont la valeur est calculée de telle sorte que la valeur entière divise 31 sans reste .*
En règle générale, seuls les champs CINFO
et FLEVEL
peuvent être librement modifiés. Il n'y a pas de choix dans ce que les autres champs contiennent, donc un total de seulement 32 en-têtes possibles sont valides. Les voici:
FLEVEL: 0 1 2 3
CINFO:
0 08 1D 08 5B 08 99 08 D7
1 18 19 18 57 18 95 18 D3
2 28 15 28 53 28 91 28 CF
3 38 11 38 4F 38 8D 38 CB
4 48 0D 48 4B 48 89 48 C7
5 58 09 58 47 58 85 58 C3
6 68 05 68 43 68 81 68 DE
7 78 01 78 5E 78 9C 78 DA
Le champ CINFO
est rarement, voire jamais, défini par les compresseurs sur une valeur autre que 7 (indiquant la fenêtre maximale de 32 Ko). Par conséquent, les seules valeurs que vous êtes susceptible de voir dans la nature sont les quatre dans la dernière ligne (commençant par 78
). .
* (Vous pourriez vous demander s'il y a une petite marge de manœuvre sur la valeur de FCHECK
- pourrait-il être mis à 0 ou à 31 si les deux passent la somme de contrôle? En pratique cependant, il n'y a pas d'en-tête valide où cette situation se produit, donc nous n'avons pas à nous en préoccuper.)
Cependant, toutes les réponses sont probablement correctes - si vous voulez manipuler directement le flux de compression ZLib et que celui-ci a été généré à l'aide des fonctions gz_open, gzwrite, gzclose
-, il y a un en-tête supplémentaire de 10 octets avant la compression zlib de Steam - et ceux-ci sont produits par la fonction gz_open - l'entête ressemble à ceci:
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
Et il en résulte le vidage hexadécimal suivant: 1F 8B 08 00 00 00 00 00 00 0B
Suivi du flux de compression zlib.
Mais il y a aussi 8 octets de fin - ils sont uLong
- crc sur tout le fichier, uLong
- taille du fichier non compressé - recherchez les octets suivants à la fin du flux:
putLong (s->file, s->crc);
putLong (s->file, (uLong)(s->in & 0xffffffff));