diff --git a/src/pixie/fileformats/bmp.nim b/src/pixie/fileformats/bmp.nim index 793ecdf..8ca1cf7 100644 --- a/src/pixie/fileformats/bmp.nim +++ b/src/pixie/fileformats/bmp.nim @@ -1,4 +1,4 @@ -import ../images, flatty/binny, flatty/hexPrint, chroma, sequtils +import ../images, flatty/binny, flatty/hexPrint, chroma, sequtils, print # See: https://en.wikipedia.org/wiki/BMP_file_format @@ -10,21 +10,32 @@ proc decodeBmp*(data: string): Image = let width = data.readInt32(0x12).int height = data.readInt32(0x16).int - # TODO: Handle masks. + bits = data.readUint16(0x1C) + compression = data.readUint32(0x1E) var offset = data.readUInt32(0xA).int + doAssert bits in {32, 24} + doAssert compression in {0, 3} + result = newImage(width, height) for y in 0 ..< result.height: for x in 0 ..< result.width: var rgba: ColorRGBA - rgba.r = data.readUint8(offset+0) - rgba.g = data.readUint8(offset+1) - rgba.b = data.readUint8(offset+2) - rgba.a = data.readUint8(offset+3) + if bits == 32: + rgba.r = data.readUint8(offset + 0) + rgba.g = data.readUint8(offset + 1) + rgba.b = data.readUint8(offset + 2) + rgba.a = data.readUint8(offset + 3) + offset += 4 + elif bits == 24: + rgba.r = data.readUint8(offset + 2) + rgba.g = data.readUint8(offset + 1) + rgba.b = data.readUint8(offset + 0) + rgba.a = 255 + offset += 3 result[x, result.height - y - 1] = rgba - offset += 4 proc encodeBmp*(image: Image): string = ## Encodes an image into bitmap data. diff --git a/tests/images/bmp/knight.24.bmp b/tests/images/bmp/knight.24.bmp new file mode 100644 index 0000000..ed23acc Binary files /dev/null and b/tests/images/bmp/knight.24.bmp differ diff --git a/tests/images/bmp/knight.24.master.bmp b/tests/images/bmp/knight.24.master.bmp new file mode 100644 index 0000000..a641e1b Binary files /dev/null and b/tests/images/bmp/knight.24.master.bmp differ diff --git a/tests/images/bmp/knight.32.bmp b/tests/images/bmp/knight.32.bmp new file mode 100644 index 0000000..ebce0d1 Binary files /dev/null and b/tests/images/bmp/knight.32.bmp differ diff --git a/tests/images/bmp/knight.32.master.bmp b/tests/images/bmp/knight.32.master.bmp new file mode 100644 index 0000000..ebce0d1 Binary files /dev/null and b/tests/images/bmp/knight.32.master.bmp differ diff --git a/tests/testbmp.nim b/tests/testbmp.nim index 0c02aaa..681f974 100644 --- a/tests/testbmp.nim +++ b/tests/testbmp.nim @@ -29,3 +29,8 @@ block: doAssert image2.width == image.width doAssert image2.height == image.height doAssert image2.data == image.data + +block: + for bits in [32, 24]: + var image = decodeBmp(readFile("images/bmp/knight." & $bits & ".master.bmp")) + writeFile("images/bmp/knight." & $bits & ".bmp", encodeBmp(image))