Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions lib/pygraphics/_bmp565.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def read_bmp565_header(f):
bpp = struct.unpack("<H", f.read(2))[0]
if bpp != BMP565_BPP:
raise ValueError("Invalid color depth")
compression = struct.unpack("<I", f.read(4))[0]
if compression not in (0, 3): # BI_RGB or BI_BITFIELDS
raise ValueError("Unsupported BMP compression")
return width, height, data_offset


Expand All @@ -46,19 +49,29 @@ def load_bmp565_buffer(f, width, height, data_offset):
return buffer


_BMP565_R_MASK = 0xF800
_BMP565_G_MASK = 0x07E0
_BMP565_B_MASK = 0x001F

# BITMAPFILEHEADER (14) + BITMAPINFOHEADER (40) + three BI_BITFIELDS masks (12)
_BMP565_DATA_OFFSET = 14 + 40 + 12


def write_bmp565_header(f, width, height, data_size):
"""Write the Windows BITMAPINFOHEADER for an RGB565 image."""
"""Write the Windows BITMAPINFOHEADER for an RGB565 image using BI_BITFIELDS."""
f.write(b"BM")
f.write(struct.pack("<I", 14 + 40 + data_size))
f.write(struct.pack("<I", _BMP565_DATA_OFFSET + data_size))
f.write(b"\x00\x00\x00\x00")
f.write(struct.pack("<I", 14 + 40))
f.write(struct.pack("<I", _BMP565_DATA_OFFSET))
f.write(struct.pack("<I", 40))
f.write(struct.pack("<II", width, height))
f.write(struct.pack("<H", 1))
f.write(struct.pack("<H", BMP565_BPP))
f.write(b"\x00\x00\x00\x00")
f.write(struct.pack("<I", 3)) # BI_BITFIELDS
f.write(struct.pack("<I", data_size))
f.write(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
# RGB565 channel masks
f.write(struct.pack("<III", _BMP565_R_MASK, _BMP565_G_MASK, _BMP565_B_MASK))


def write_bmp565_rows(f, buffer, width, height):
Expand Down
18 changes: 13 additions & 5 deletions src/gfx_bmp565.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,20 @@ int gfx_bmp565_read_header_from_file(const char *path, int *width, int *height,
}
uint32_t header_size, w, h;
uint16_t planes, bpp;
uint32_t compression;
if (read_u32_le(f, &header_size) < 0 || read_u32_le(f, &w) < 0 || read_u32_le(f, &h) < 0
|| read_u16_le(f, &planes) < 0 || read_u16_le(f, &bpp) < 0) {
|| read_u16_le(f, &planes) < 0 || read_u16_le(f, &bpp) < 0
|| read_u32_le(f, &compression) < 0) {
fclose(f);
return -1;
}
fclose(f);
if (planes != 1 || bpp != GFX_BMP565_BPP) {
return -1;
}
if (compression != 0 && compression != 3) { /* BI_RGB or BI_BITFIELDS */
return -1;
}
*width = (int)w;
*height = (int)h;
*data_offset = off;
Expand Down Expand Up @@ -275,17 +280,20 @@ int gfx_bmp565_save(const gfx_bmp565_t *bmp, const char *path) {
fclose(f);
return -1;
}
if (write_u32_le(f, (uint32_t)(14 + 40 + data_size)) < 0
if (write_u32_le(f, (uint32_t)(14 + 40 + 12 + data_size)) < 0
|| fwrite("\x00\x00\x00\x00", 1, 4, f) != 4
|| write_u32_le(f, 14 + 40) < 0
|| write_u32_le(f, 14 + 40 + 12) < 0
|| write_u32_le(f, 40) < 0
|| write_u32_le(f, (uint32_t)bmp->width) < 0
|| write_u32_le(f, (uint32_t)bmp->height) < 0
|| write_u16_le(f, 1) < 0
|| write_u16_le(f, GFX_BMP565_BPP) < 0
|| fwrite("\x00\x00\x00\x00", 1, 4, f) != 4
|| write_u32_le(f, 3) < 0 /* BI_BITFIELDS */
|| write_u32_le(f, (uint32_t)data_size) < 0
|| fwrite("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 1, 16, f) != 16) {
|| fwrite("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 1, 16, f) != 16
|| write_u32_le(f, 0xF800) < 0 /* R mask */
|| write_u32_le(f, 0x07E0) < 0 /* G mask */
|| write_u32_le(f, 0x001F) < 0) { /* B mask */
fclose(f);
return -1;
}
Expand Down
Loading