Skip to content

Commit

Permalink
Incorrect 16-bit RGB packing (#219)
Browse files Browse the repository at this point in the history
- Fixes #218
- Add tests for RGB packing
  • Loading branch information
rm-hull committed Sep 14, 2018
1 parent 2b5eb8d commit 1e20b02
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
4 changes: 2 additions & 2 deletions luma/oled/device.py
Expand Up @@ -282,7 +282,7 @@ def display(self, image):
if not(r == g == b == 0):
# 65K format 1
buf[i] = r & 0xF8 | g >> 5
buf[i + 1] = g << 5 & 0xE0 | b >> 3
buf[i + 1] = g << 3 & 0xE0 | b >> 3
i += 2

self.data(list(buf))
Expand Down Expand Up @@ -408,7 +408,7 @@ def display(self, image):
if not(r == g == b == 0):
# 65K format 1
buf[i] = r & 0xF8 | g >> 5
buf[i + 1] = g << 5 & 0xE0 | b >> 3
buf[i + 1] = g << 3 & 0xE0 | b >> 3
i += 2

self.data(list(buf))
Expand Down
30 changes: 30 additions & 0 deletions tests/test_ssd1331.py
Expand Up @@ -3,6 +3,8 @@
# Copyright (c) 2014-18 Richard Hull and contributors
# See LICENSE.rst for details.

import pytest

from luma.oled.device import ssd1331
from luma.core.render import canvas

Expand Down Expand Up @@ -77,3 +79,31 @@ def test_display():

# Next 12288 bytes are data representing the drawn image
serial.data.assert_called_once_with(get_json_data('demo_ssd1331'))


@pytest.mark.parametrize("bit,expected_16_bit_color", [
(7, [0b10000100, 0b00010000]),
(6, [0b01000010, 0b00001000]),
(5, [0b00100001, 0b00000100]),
(4, [0b00010000, 0b10000010]),
(3, [0b00001000, 0b01000001]),
(2, [0b00000000, 0b00100000]),
(1, [0b00000000, 0b00000000]),
(0, [0b00000000, 0b00000000]),
])
def test_16bit_rgb_packing(bit, expected_16_bit_color):
"""
Checks that 8 bit red component is packed into first 5 bits
Checks that 8 bit green component is packed into next 6 bits
Checks that 8 bit blue component is packed into remaining 5 bits
"""
device = ssd1331(serial)
serial.reset_mock()

rgb_color = (2 ** bit,) * 3
expected = expected_16_bit_color * device.width * device.height

with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline=rgb_color, fill=rgb_color)

serial.data.assert_called_once_with(expected)
47 changes: 47 additions & 0 deletions tests/test_ssd1351.py
Expand Up @@ -3,6 +3,8 @@
# Copyright (c) 2017-18 Richard Hull and contributors
# See LICENSE.rst for details.

import pytest

from luma.oled.device import ssd1351
from luma.core.render import canvas

Expand Down Expand Up @@ -162,3 +164,48 @@ def command(*cmd):
{'command': [117]}, {'data': [0, 127]},
{'command': [92]}, {'data': get_json_data('demo_ssd1351')}
]


@pytest.mark.parametrize("bit,expected_16_bit_color", [
(7, [0b10000100, 0b00010000]),
(6, [0b01000010, 0b00001000]),
(5, [0b00100001, 0b00000100]),
(4, [0b00010000, 0b10000010]),
(3, [0b00001000, 0b01000001]),
(2, [0b00000000, 0b00100000]),
(1, [0b00000000, 0b00000000]),
(0, [0b00000000, 0b00000000]),
])
def test_16bit_rgb_packing(bit, expected_16_bit_color):
"""
Checks that 8 bit red component is packed into first 5 bits
Checks that 8 bit green component is packed into next 6 bits
Checks that 8 bit blue component is packed into remaining 5 bits
"""
device = ssd1351(serial)
serial.reset_mock()

rgb_color = (2 ** bit,) * 3
expected = expected_16_bit_color * device.width * device.height
recordings = []

def data(data):
recordings.append({'data': data})

def command(*cmd):
recordings.append({'command': list(cmd)})

serial.command.side_effect = command
serial.data.side_effect = data

with canvas(device) as draw:
draw.rectangle(device.bounding_box, outline=rgb_color, fill=rgb_color)

assert serial.data.called
assert serial.command.called

assert recordings == [
{'command': [21]}, {'data': [0, 127]},
{'command': [117]}, {'data': [0, 127]},
{'command': [92]}, {'data': expected}
]

0 comments on commit 1e20b02

Please sign in to comment.