Por dentro do PNG
Um PNG é uma assinatura fixa seguida de blocos, e cada bloco tem tamanho, tipo, dados e um código de verificação.
Todo PNG começa com a mesma assinatura de 8 bytes: 89 50 4E 47 0D 0A 1A 0A. Depois vem uma sequência de blocos (chunks), todos no mesmo formato:
| Campo | Tamanho | O que é |
|---|---|---|
| Comprimento | 4 bytes | quantos bytes de dados o bloco tem |
| Tipo | 4 bytes | quatro letras: IHDR, tEXt, IDAT, IEND... |
| Dados | variável | o conteúdo do bloco |
| CRC | 4 bytes | código de verificação calculado sobre o tipo e os dados |
Os números ficam com o byte mais importante primeiro (big-endian): 00 00 01 2C é 300.
Os blocos principais:
- IHDR vem logo depois da assinatura e tem 13 bytes de dados: largura (4), altura (4), profundidade de bits, tipo de cor e mais três campos de 1 byte. A largura fica nos bytes 16 a 19 do arquivo e a altura nos bytes 20 a 23.
- IDAT guarda os pixels comprimidos com zlib. Descomprimidos, eles formam uma linha atrás da outra, e cada linha começa com 1 byte de filtro. Numa imagem colorida comum (RGB, 8 bits), cada pixel ocupa 3 bytes, então cada linha tem
1 + 3 × largurabytes. - IEND marca o fim e não tem dados.
Como assinatura, comprimento 00 00 00 0D e IHDR são iguais em todo PNG, os 16 primeiros bytes de qualquer PNG são idênticos.
O CRC denuncia mexidas: se alguém troca um byte do tipo ou dos dados e não recalcula o CRC, o bloco fica inconsistente, e muitos programas se recusam a abrir a imagem. O PNG file chunk inspector (abre em nova aba) mostra cada bloco e os campos do IHDR, avisa quando um CRC não bate e, com a opção Check IDATs, confere se a quantidade de pixels comprimidos combina com o tamanho declarado. No CyberChef, CRC Checksum (algoritmo CRC-32) calcula o CRC de um trecho: dê a ela o tipo e os dados do bloco, sem o comprimento. Zlib Inflate descomprime os dados de um IDAT.
Exemplo: uma imagem RGB de 300 × 100 pixels tem linhas de 1 + 3 × 300 = 901 bytes, então o IDAT descomprimido tem 100 × 901 = 90.100 bytes.