Skip to content

Instantly share code, notes, and snippets.

@radgeRayden
Created July 17, 2015 13:12
Show Gist options
  • Save radgeRayden/baecf13d2a5ed49deb13 to your computer and use it in GitHub Desktop.
Save radgeRayden/baecf13d2a5ed49deb13 to your computer and use it in GitHub Desktop.
FORMATO BMP - MSPaint
HEADER
======
- 42 4D - B M (bitmap?) (2 bytes)
- 8 bytes reservados para o tamanho do arquivo (bytes na ordem inversa. Ex: '36 bb 17 00 00 00 00 00' torna-se '17 bb 36' = 1555254 bytes) [1]
- 4 bytes informando em que ponto a imagem em si começará a ser descrita. Ex: para bmp 24bits, '36 00 00 00' -> 36 = 54 bytes.
- 4 bytes '28 00 00 00' que não sei o que significa, mas deve ser um delimitador.
- 4 bytes para informar a largura da imagem. O formato é o mesmo do tamanho. Ex: '1c 02 00 00' torna-se '02 1c' = 540 pixels.
- 4 bytes para informar a altura da imagem, mesmo formato da largura. Ex: 'c0 03 00 00' torna-se '03 c0' = 960 pixels.
- 2 bytes que não sei para que servem, mas todos os arquivos que abri mantinham '01 00'.
- 2 bytes para informar a densidade de bits da imagem. Ex: '18 00' para 24 bits, '04 00' para 16 cores, '08 00' para 256 cores.
- 4 bytes zerados para (???) '00 00 00 00'
- 4 bytes indicando o tamanho da descrição da imagem.
- 16 bytes que não sei o que significam. Variam dependendo da imagem, mas para decodificação parecem irrelevantes. Dependendo da codificação, o número de bytes também varia. Como faltavam 16 bytes para completar os 54 indicados acima, nesse caso são 16. [2][3]
- A partir daí a imagem de fato começa, com a representação dependendo da densidade de bits. Para densidades menores que 24bits, é utilizada uma tabela de cores que traduz a informação. Obviamente menos cores poderão ser representadas, e o paint certamente arredonda valores na hora de salvar. É importante notar que para imagens com dimensões ímpares (ou algum razão semelhante que não consegui identificar com clareza) o fim das linhas pode ser marcado com um número variado de bytes zerados. Uma forma de compensar é checar a diferença entre o tamanho esperado da descrição [tamanho total do arquivo - largura * altura * (densidade de bits / 8)] e o tamanho reportado, uma vez que a quantidade de bytes zerados é sempre igual para cada linha.
[1] Essa forma de armazenar a informação é presente em todo o formato. Imagino que tenha sido usado para facilitar a programação do codificador. Inclusive cada pixel é representado como um conjunto de 3 bytes (G,B,R) e, se lido sequencialmente, o arquivo descreve uma imagem invertida ao longo do eixo vertical.
[2] O arquivo no qual me baseei para os exemplos era um BMP 24 bits, mas com pequenas adaptações as instruções servem bem para os 3 formatos.
[3] No caso do formato 16 cores, estudando os 80 bytes dessa seção identifiquei a presença da tabela de cores nos últimos 64 bytes, representados da seguinte maneira:
--bytes que antecedem a tabela
c4 0e 00 00 c4 0e 00 00 00 00 00 00 00 00 00 00
--tabela 16 cores
000000 00 - 0
000080 00 - 1
008000 00 - 2
008080 00 - 3
800000 00 - 4
800080 00 - 5
808000 00 - 6
808080 00 - 7
c0c0c0 00 - 8
0000ff 00 - 9
00ff00 00 - a
00ffff 00 - b
ff0000 00 - c
ff00ff 00 - d
ffff00 00 - e
ffffff 00 - f
É possível observar que cada sequência de 3 bytes que representa uma cor é delimitada por um byte zerado, o terminador de string. Após testes descobri que não há problema em editar a tabela, desde que o formato da mesma seja respeitado.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment