From 646309261300d22eaa9248a1e7d819febbae0853 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 12 Apr 2019 16:02:51 -0700 Subject: [PATCH 01/12] Simplify load and use [] on the bitmap --- adafruit_imageload/bmp/indexed.py | 32 +++++++++---------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index 76e35cd..f690f14 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -54,30 +54,16 @@ def load(f, width, height, data_start, colors, color_depth, *, bitmap=None, pale if line_size % 4 != 0: line_size += (4 - line_size % 4) - packed_pixels = None - if color_depth != minimum_color_depth and minimum_color_depth == 2: - target_line_size = width // 4 - if target_line_size % 4 != 0: - target_line_size += (4 - target_line_size % 4) + chunk = bytearray(line_size) - packed_pixels = bytearray(target_line_size) + for y in range(height-1,-1,-1): + f.readinto(chunk) + pixels_per_byte = 8 // color_depth + offset = y * width - for line in range(height-1,-1,-1): - chunk = f.read(line_size) - if packed_pixels: - original_pixels_per_byte = 8 // color_depth - packed_pixels_per_byte = 8 // minimum_color_depth - - for i in range(width // packed_pixels_per_byte): - packed_pixels[i] = 0 - - for i in range(width): - pi = i // packed_pixels_per_byte - ci = i // original_pixels_per_byte - packed_pixels[pi] |= ((chunk[ci] >> (8 - color_depth*(i % original_pixels_per_byte + 1))) & 0x3) << (8 - minimum_color_depth*(i % packed_pixels_per_byte + 1)) - - bitmap._load_row(line, packed_pixels) - else: - bitmap._load_row(line, chunk) + for x in range(width): + ci = x // pixels_per_byte + pixel = (chunk[ci] >> (8 - color_depth*(x % pixels_per_byte + 1))) & ((1 << minimum_color_depth) - 1) + bitmap[offset + x] = pixel return bitmap, palette From 3d00b42985a9bac5796c5181dd39dc57853ac6c0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 12 Apr 2019 16:31:36 -0700 Subject: [PATCH 02/12] Lint! --- adafruit_imageload/__init__.py | 11 +++++---- adafruit_imageload/bmp/__init__.py | 36 ++++++++++++++++++------------ adafruit_imageload/bmp/indexed.py | 29 +++++++++++++++--------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/adafruit_imageload/__init__.py b/adafruit_imageload/__init__.py index 8b09882..5c36a32 100644 --- a/adafruit_imageload/__init__.py +++ b/adafruit_imageload/__init__.py @@ -41,11 +41,10 @@ def load(filename, *, bitmap=None, palette=None): palette is the desired pallete type. The constructor should take the number of colors and support assignment to indices via []. """ - with open(filename, "rb") as f: - header = f.read(3) + with open(filename, "rb") as file: + header = file.read(3) if header.startswith(b"BM"): from . import bmp - f.seek(0) - return bmp.load(f, bitmap=bitmap, palette=palette) - else: - raise RuntimeError("Unsupported image format") + file.seek(0) + return bmp.load(file, bitmap=bitmap, palette=palette) + raise RuntimeError("Unsupported image format") diff --git a/adafruit_imageload/bmp/__init__.py b/adafruit_imageload/bmp/__init__.py index 3e3f906..1b158b1 100644 --- a/adafruit_imageload/bmp/__init__.py +++ b/adafruit_imageload/bmp/__init__.py @@ -32,25 +32,33 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git" -def load(f, *, bitmap=None, palette=None): - f.seek(10) - data_start = int.from_bytes(f.read(4), 'little') +def load(file, *, bitmap=None, palette=None): + """Loads a bmp image from the open ``file``. + + Returns tuple of bitmap object and palette object. + + :param object bitmap: Type to store bitmap data. Must have API similar to `displayio.Bitmap`. + Will be skipped if None + :param object palette: Type to store the palette. Must have API similar to + `displayio.Palette`. Will be skipped if None""" + file.seek(10) + data_start = int.from_bytes(file.read(4), 'little') # f.seek(14) - # bmp_header_length = int.from_bytes(f.read(4), 'little') + # bmp_header_length = int.from_bytes(file.read(4), 'little') # print(bmp_header_length) - f.seek(18) - width = int.from_bytes(f.read(4), 'little') - height = int.from_bytes(f.read(4), 'little') - f.seek(28) - color_depth = int.from_bytes(f.read(2), 'little') - f.seek(46) - colors = int.from_bytes(f.read(4), 'little') - - compute_palette = False + file.seek(18) + width = int.from_bytes(file.read(4), 'little') + height = int.from_bytes(file.read(4), 'little') + file.seek(28) + color_depth = int.from_bytes(file.read(2), 'little') + file.seek(46) + colors = int.from_bytes(file.read(4), 'little') + if colors == 0 and color_depth >= 16: raise NotImplementedError("True color BMP unsupported") else: if colors == 0: colors = 2 ** color_depth from . import indexed - return indexed.load(f, width, height, data_start, colors, color_depth, bitmap=bitmap, palette=palette) + return indexed.load(file, width, height, data_start, colors, color_depth, bitmap=bitmap, + palette=palette) diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index f690f14..d561ab6 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -32,16 +32,22 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git" -import math +def load(file, width, height, data_start, colors, color_depth, *, bitmap=None, palette=None): + """Loads indexed bitmap data into bitmap and palette objects. -def load(f, width, height, data_start, colors, color_depth, *, bitmap=None, palette=None): + :param file file: The open bmp file + :param int width: Image width in pixels + :param int height: Image height in pixels + :param int data_start: Byte location where the data starts (after headers) + :param int colors: Number of distinct colors in the image + :param int color_depth: Number of bits used to store a value""" + # pylint: disable=too-many-arguments,too-many-locals if palette: palette = palette(colors) - f.seek(data_start - colors * 4) - for color in range(colors): - c = f.read(4) - palette[color] = c + file.seek(data_start - colors * 4) + for value in range(colors): + palette[value] = file.read(4) if bitmap: minimum_color_depth = 1 @@ -49,21 +55,22 @@ def load(f, width, height, data_start, colors, color_depth, *, bitmap=None, pale minimum_color_depth *= 2 bitmap = bitmap(width, height, colors) - f.seek(data_start) + file.seek(data_start) line_size = width // (8 // color_depth) if line_size % 4 != 0: line_size += (4 - line_size % 4) chunk = bytearray(line_size) + mask = (1 << minimum_color_depth) - 1 - for y in range(height-1,-1,-1): - f.readinto(chunk) + for y in range(height - 1, -1, -1): + file.readinto(chunk) pixels_per_byte = 8 // color_depth offset = y * width for x in range(width): - ci = x // pixels_per_byte - pixel = (chunk[ci] >> (8 - color_depth*(x % pixels_per_byte + 1))) & ((1 << minimum_color_depth) - 1) + i = x // pixels_per_byte + pixel = (chunk[i] >> (8 - color_depth*(x % pixels_per_byte + 1))) & mask bitmap[offset + x] = pixel return bitmap, palette From 32542989ce5de0b3ae0298a327019576666028bd Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 12 Apr 2019 16:34:17 -0700 Subject: [PATCH 03/12] Lint example too --- examples/imageload_simpletest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/imageload_simpletest.py b/examples/imageload_simpletest.py index 56962b7..17dc3bf 100644 --- a/examples/imageload_simpletest.py +++ b/examples/imageload_simpletest.py @@ -1,4 +1,6 @@ import displayio import adafruit_imageload -image, palette = adafruit_imageload.load("images/4bit.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) +image, palette = adafruit_imageload.load("images/4bit.bmp", + bitmap=displayio.Bitmap, + palette=displayio.Palette) From 852d0f84ff3cfffed22a0239aed935b7f467e9bc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 12 Apr 2019 16:47:34 -0700 Subject: [PATCH 04/12] Fixup sphinx --- README.rst | 2 +- docs/index.rst | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 36397bf..d8650f3 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ overhead of the decoding code. Usage Example ============= -.. literalinclude:: examples/imageload_simpletest.py +.. literalinclude:: ../examples/imageload_simpletest.py Contributing ============ diff --git a/docs/index.rst b/docs/index.rst index 166594f..ae5ed09 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,15 +23,9 @@ Table of Contents .. toctree:: :caption: Tutorials -.. todo:: Add any Learn guide links here. If there are none, then simply delete this todo and leave - the toctree above for use later. - .. toctree:: :caption: Related Products -.. todo:: Add any product links here. If there are none, then simply delete this todo and leave - the toctree above for use later. - .. toctree:: :caption: Other Links From cfda5cc407ed1c13ca5f4d996f021291f7793a8d Mon Sep 17 00:00:00 2001 From: siehputz Date: Fri, 10 May 2019 10:32:03 -0500 Subject: [PATCH 05/12] Fixed red/green color issue in indexed.py and added an example and image to show the complete color wheel. --- adafruit_imageload/bmp/indexed.py | 5 ++++- examples/code.py | 15 +++++++++++++++ examples/imageload_colorwheel.py | 15 +++++++++++++++ examples/images/color_wheel.bmp | Bin 0 -> 77880 bytes 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 examples/code.py create mode 100644 examples/imageload_colorwheel.py create mode 100644 examples/images/color_wheel.bmp diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index d561ab6..4287fb0 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -47,7 +47,10 @@ def load(file, width, height, data_start, colors, color_depth, *, bitmap=None, p file.seek(data_start - colors * 4) for value in range(colors): - palette[value] = file.read(4) + c = file.read(4) + # Need to swap red & green bytes (bytes 0 and 2) + d = bytes(b''.join([c[2:3],c[1:2],c[0:1],c[3:1]])) + palette[value] = d if bitmap: minimum_color_depth = 1 diff --git a/examples/code.py b/examples/code.py new file mode 100644 index 0000000..9c2f3b0 --- /dev/null +++ b/examples/code.py @@ -0,0 +1,15 @@ +import board +import displayio +import adafruit_imageload + +display = board.DISPLAY + +bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) + +tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette) + +group = displayio.Group() +group.append(tile_grid) +display.show(group) +while True: + pass diff --git a/examples/imageload_colorwheel.py b/examples/imageload_colorwheel.py new file mode 100644 index 0000000..9c2f3b0 --- /dev/null +++ b/examples/imageload_colorwheel.py @@ -0,0 +1,15 @@ +import board +import displayio +import adafruit_imageload + +display = board.DISPLAY + +bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) + +tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette) + +group = displayio.Group() +group.append(tile_grid) +display.show(group) +while True: + pass diff --git a/examples/images/color_wheel.bmp b/examples/images/color_wheel.bmp new file mode 100644 index 0000000000000000000000000000000000000000..34d7e5fd4d470781674579711f35c270a85b6ebf GIT binary patch literal 77880 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 Date: Fri, 10 May 2019 10:36:02 -0500 Subject: [PATCH 06/12] Delete code.py --- examples/code.py | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 examples/code.py diff --git a/examples/code.py b/examples/code.py deleted file mode 100644 index 9c2f3b0..0000000 --- a/examples/code.py +++ /dev/null @@ -1,15 +0,0 @@ -import board -import displayio -import adafruit_imageload - -display = board.DISPLAY - -bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) - -tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette) - -group = displayio.Group() -group.append(tile_grid) -display.show(group) -while True: - pass From 1b41a1f678b6c1977c2fa2e2999c5bdf947cbd0c Mon Sep 17 00:00:00 2001 From: siehputz Date: Fri, 10 May 2019 11:57:47 -0500 Subject: [PATCH 07/12] Fixing up travis errors --- adafruit_imageload/bmp/indexed.py | 5 ++--- examples/imageload_colorwheel.py | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index 4287fb0..2c8273c 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -47,10 +47,9 @@ def load(file, width, height, data_start, colors, color_depth, *, bitmap=None, p file.seek(data_start - colors * 4) for value in range(colors): - c = file.read(4) + c_bytes = file.read(4) # Need to swap red & green bytes (bytes 0 and 2) - d = bytes(b''.join([c[2:3],c[1:2],c[0:1],c[3:1]])) - palette[value] = d + palette[value] = bytes(b''.join([c_bytes[2:3], c_bytes[1:2], c_bytes[0:1], c_bytes[3:1]])) if bitmap: minimum_color_depth = 1 diff --git a/examples/imageload_colorwheel.py b/examples/imageload_colorwheel.py index 9c2f3b0..d9a8537 100644 --- a/examples/imageload_colorwheel.py +++ b/examples/imageload_colorwheel.py @@ -4,7 +4,8 @@ display = board.DISPLAY -bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) +bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", + bitmap=displayio.Bitmap, palette=displayio.Palette) tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette) @@ -12,4 +13,4 @@ group.append(tile_grid) display.show(group) while True: - pass + pass From 9481049679116be06e497725d3673d2f720830dc Mon Sep 17 00:00:00 2001 From: siehputz Date: Fri, 10 May 2019 17:08:23 -0500 Subject: [PATCH 08/12] Changed comment to reflect actual swap of red & blue bytes --- adafruit_imageload/bmp/indexed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index 2c8273c..a3fbf69 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -48,7 +48,7 @@ def load(file, width, height, data_start, colors, color_depth, *, bitmap=None, p file.seek(data_start - colors * 4) for value in range(colors): c_bytes = file.read(4) - # Need to swap red & green bytes (bytes 0 and 2) + # Need to swap red & blue bytes (bytes 0 and 2) palette[value] = bytes(b''.join([c_bytes[2:3], c_bytes[1:2], c_bytes[0:1], c_bytes[3:1]])) if bitmap: From 99679af72ee0b53066b09738e969e75f7e1634fa Mon Sep 17 00:00:00 2001 From: siehputz Date: Fri, 10 May 2019 17:17:49 -0500 Subject: [PATCH 09/12] Fixing lint warnings --- adafruit_imageload/bmp/indexed.py | 3 ++- examples/imageload_colorwheel.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index a3fbf69..a397447 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -49,7 +49,8 @@ def load(file, width, height, data_start, colors, color_depth, *, bitmap=None, p for value in range(colors): c_bytes = file.read(4) # Need to swap red & blue bytes (bytes 0 and 2) - palette[value] = bytes(b''.join([c_bytes[2:3], c_bytes[1:2], c_bytes[0:1], c_bytes[3:1]])) + palette[value] = bytes(b''.join([c_bytes[2:3], + c_bytes[1:2], c_bytes[0:1], c_bytes[3:1]])) if bitmap: minimum_color_depth = 1 diff --git a/examples/imageload_colorwheel.py b/examples/imageload_colorwheel.py index d9a8537..ba388b6 100644 --- a/examples/imageload_colorwheel.py +++ b/examples/imageload_colorwheel.py @@ -5,7 +5,7 @@ display = board.DISPLAY bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", - bitmap=displayio.Bitmap, palette=displayio.Palette) + bitmap=displayio.Bitmap, palette=displayio.Palette) tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette) @@ -13,4 +13,4 @@ group.append(tile_grid) display.show(group) while True: - pass + pass From 5e27e004e17131fee4ce12bb47f63fed5fb38996 Mon Sep 17 00:00:00 2001 From: siehputz Date: Fri, 10 May 2019 17:35:59 -0500 Subject: [PATCH 10/12] Still fixing lint issues --- adafruit_imageload/bmp/indexed.py | 4 +++- examples/imageload_colorwheel.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/adafruit_imageload/bmp/indexed.py b/adafruit_imageload/bmp/indexed.py index a397447..e4ffd97 100644 --- a/adafruit_imageload/bmp/indexed.py +++ b/adafruit_imageload/bmp/indexed.py @@ -50,7 +50,9 @@ def load(file, width, height, data_start, colors, color_depth, *, bitmap=None, p c_bytes = file.read(4) # Need to swap red & blue bytes (bytes 0 and 2) palette[value] = bytes(b''.join([c_bytes[2:3], - c_bytes[1:2], c_bytes[0:1], c_bytes[3:1]])) + c_bytes[1:2], + c_bytes[0:1], + c_bytes[3:1]])) if bitmap: minimum_color_depth = 1 diff --git a/examples/imageload_colorwheel.py b/examples/imageload_colorwheel.py index ba388b6..a60f5b9 100644 --- a/examples/imageload_colorwheel.py +++ b/examples/imageload_colorwheel.py @@ -5,7 +5,8 @@ display = board.DISPLAY bitmap, palette = adafruit_imageload.load("images/color_wheel.bmp", - bitmap=displayio.Bitmap, palette=displayio.Palette) + bitmap=displayio.Bitmap, + palette=displayio.Palette) tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette) From 5521a2effa03afedfd8e3b9fcc417a972e723a6e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 14 May 2019 10:03:44 -0700 Subject: [PATCH 11/12] Fixup doc build --- docs/developing.rst | 10 +++++----- docs/index.rst | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/developing.rst b/docs/developing.rst index 9588b07..7b1d345 100644 --- a/docs/developing.rst +++ b/docs/developing.rst @@ -102,16 +102,16 @@ The corresponding Bitmap to the example above appears like this after loading:: 4 4 4 5 5 5 12 12 12 5 5 5 7 7 7 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 -This grid represents the example image (`15 pixels wide` and `17 pixels tall`). -The coordinates are arranged in a zero indexed grid, starting in the top left at `[0,0]`, -and continuing down and to the right to a final coordinate of `[14,16]`. +This grid represents the example image (``15 pixels wide`` and ``17 pixels tall``). +The coordinates are arranged in a zero indexed grid, starting in the top left at ``[0,0]``, +and continuing down and to the right to a final coordinate of ``[14,16]``. The value at each position is an integer, representing an entry in the palette object. -For example, the Bitmap coordinate `[0,0]` has the value (integer) `5`. +For example, the Bitmap coordinate ``[0,0]`` has the value (integer) ``5``. -This corresponds to the the Palette object's, `[5]` which is `b'\x00\x00\xff\x00'`. This is a byte string that represents a color. +This corresponds to the the Palette object's, ``[5]`` which is ``b'\x00\x00\xff\x00'``. This is a byte string that represents a color. diff --git a/docs/index.rst b/docs/index.rst index ae5ed09..6428fa2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,6 +23,12 @@ Table of Contents .. toctree:: :caption: Tutorials +.. toctree:: + :caption: Development + :maxdepth: 3 + + developing + .. toctree:: :caption: Related Products From 8d93f8086d67333b702ede3f2585fb322145f538 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 14 May 2019 10:05:57 -0700 Subject: [PATCH 12/12] Use hex offsets --- adafruit_imageload/bmp/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_imageload/bmp/__init__.py b/adafruit_imageload/bmp/__init__.py index 1b158b1..e83bd2b 100644 --- a/adafruit_imageload/bmp/__init__.py +++ b/adafruit_imageload/bmp/__init__.py @@ -46,12 +46,12 @@ def load(file, *, bitmap=None, palette=None): # f.seek(14) # bmp_header_length = int.from_bytes(file.read(4), 'little') # print(bmp_header_length) - file.seek(18) + file.seek(0x12) # Width of the bitmap in pixels width = int.from_bytes(file.read(4), 'little') height = int.from_bytes(file.read(4), 'little') - file.seek(28) + file.seek(0x1c) # Number of bits per pixel color_depth = int.from_bytes(file.read(2), 'little') - file.seek(46) + file.seek(0x2e) # Number of colors in the color palette colors = int.from_bytes(file.read(4), 'little') if colors == 0 and color_depth >= 16: