Pular para o conteúdo
Todos os conceitos

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
o arquivo, do byte 0 ao fim 8 bytes, sempre iguais assinatura 89 50 4E 47… IHDR tEXt IDAT IDAT IEND um bloco aberto: todos têm estes 4 campos Comprimento 4 bytes 00 00 00 0D Tipo 4 bytes I H D R Dados 13 bytes no IHDR largura, altura… CRC 4 bytes CRC-32 o CRC é calculado sobre o tipo e os dados
Um PNG é a assinatura de 8 bytes seguida de blocos; cada bloco tem comprimento, tipo, dados e um CRC que confere 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 × largura bytes.
  • 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.

Aparece nestes desafios