Skip to content

Commit bd86b44

Browse files
committed
Add JpegDecoder
1 parent 83ff22a commit bd86b44

File tree

13 files changed

+388
-0
lines changed

13 files changed

+388
-0
lines changed

locale/circuitpython.pot

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,10 @@ msgstr ""
880880
msgid "Data chunk must follow fmt chunk"
881881
msgstr ""
882882

883+
#: shared-module/jpegio/JpegDecoder.c
884+
msgid "Data format error (may be broken data)"
885+
msgstr ""
886+
883887
#: ports/espressif/common-hal/_bleio/Adapter.c
884888
#: ports/nrf/common-hal/_bleio/Adapter.c
885889
msgid "Data not supported with directed advertising"
@@ -894,10 +898,18 @@ msgstr ""
894898
msgid "Deep sleep pins must use a rising edge with pulldown"
895899
msgstr ""
896900

901+
#: shared-module/jpegio/JpegDecoder.c
902+
msgid "Destination bitmap too small to contain image"
903+
msgstr ""
904+
897905
#: shared-bindings/audiobusio/PDMIn.c
898906
msgid "Destination capacity is smaller than destination_length."
899907
msgstr ""
900908

909+
#: shared-module/jpegio/JpegDecoder.c
910+
msgid "Device error or wrong termination of input stream"
911+
msgstr ""
912+
901913
#: ports/nrf/common-hal/audiobusio/I2SOut.c
902914
msgid "Device in use"
903915
msgstr ""
@@ -1177,6 +1189,14 @@ msgstr ""
11771189
msgid "Insufficient encryption"
11781190
msgstr ""
11791191

1192+
#: shared-module/jpegio/JpegDecoder.c
1193+
msgid "Insufficient memory pool for the image"
1194+
msgstr ""
1195+
1196+
#: shared-module/jpegio/JpegDecoder.c
1197+
msgid "Insufficient stream input buffer"
1198+
msgstr ""
1199+
11801200
#: ports/espressif/common-hal/wifi/Radio.c
11811201
msgid "Interface must be started"
11821202
msgstr ""
@@ -1207,6 +1227,10 @@ msgstr ""
12071227
msgid "Interrupt error."
12081228
msgstr ""
12091229

1230+
#: shared-module/jpegio/JpegDecoder.c
1231+
msgid "Interrupted by output function"
1232+
msgstr ""
1233+
12101234
#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c
12111235
#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c
12121236
#: ports/raspberrypi/bindings/picodvi/Framebuffer.c
@@ -1546,6 +1570,10 @@ msgstr ""
15461570
msgid "Not playing"
15471571
msgstr ""
15481572

1573+
#: shared-module/jpegio/JpegDecoder.c
1574+
msgid "Not supported JPEG standard"
1575+
msgstr ""
1576+
15491577
#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c
15501578
#, c-format
15511579
msgid "Number of data_pins must be 8 or 16, not %d"
@@ -1687,6 +1715,10 @@ msgstr ""
16871715
msgid "PWM slice channel A already in use"
16881716
msgstr ""
16891717

1718+
#: shared-module/jpegio/JpegDecoder.c
1719+
msgid "Parameter error"
1720+
msgstr ""
1721+
16901722
#: ports/espressif/common-hal/audiobusio/__init__.c
16911723
msgid "Peripheral in use"
16921724
msgstr ""
@@ -1857,6 +1889,10 @@ msgstr ""
18571889
msgid "Right channel unsupported"
18581890
msgstr ""
18591891

1892+
#: shared-module/jpegio/JpegDecoder.c
1893+
msgid "Right format but not supported"
1894+
msgstr ""
1895+
18601896
#: main.c
18611897
msgid "Running in safe mode! Not running saved code.\n"
18621898
msgstr ""

ports/espressif/mpconfigport.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ endif
128128
# Modules dependent on other modules
129129
CIRCUITPY_ESPNOW ?= $(CIRCUITPY_WIFI)
130130
CIRCUITPY_GIFIO ?= $(CIRCUITPY_ESPCAMERA)
131+
CIRCUITPY_JPEGIO ?= $(CIRCUITPY_ESPCAMERA)
131132
CIRCUITPY_QRIO ?= $(CIRCUITPY_ESPCAMERA)
132133

133134
# Features dependent on other features

ports/unix/variants/coverage/mpconfigvariant.mk

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ SRC_C += $(SRC_QRIO)
1919
CFLAGS += -DCIRCUITPY_QRIO=1
2020
$(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h
2121

22+
SRC_C += lib/tjpgd/src/tjpgd.c
23+
$(BUILD)/lib/tjpgd/src/tjpgd.o: CFLAGS += -Wno-shadow -Wno-cast-align
24+
2225
SRC_BITMAP := \
2326
shared/runtime/context_manager_helpers.c \
2427
displayio_min.c \
@@ -33,6 +36,8 @@ SRC_BITMAP := \
3336
shared-bindings/audiomixer/MixerVoice.c \
3437
shared-bindings/bitmaptools/__init__.c \
3538
shared-bindings/displayio/Bitmap.c \
39+
shared-bindings/jpegio/__init__.c \
40+
shared-bindings/jpegio/JpegDecoder.c \
3641
shared-bindings/locale/__init__.c \
3742
shared-bindings/rainbowio/__init__.c \
3843
shared-bindings/struct/__init__.c \
@@ -59,6 +64,8 @@ SRC_BITMAP := \
5964
shared-module/displayio/Bitmap.c \
6065
shared-module/displayio/ColorConverter.c \
6166
shared-module/displayio/ColorConverter.c \
67+
shared-module/jpegio/__init__.c \
68+
shared-module/jpegio/JpegDecoder.c \
6269
shared-module/os/getenv.c \
6370
shared-module/rainbowio/__init__.c \
6471
shared-module/struct/__init__.c \
@@ -83,6 +90,7 @@ CFLAGS += \
8390
-DCIRCUITPY_DISPLAYIO_UNIX=1 \
8491
-DCIRCUITPY_FUTURE=1 \
8592
-DCIRCUITPY_GIFIO=1 \
93+
-DCIRCUITPY_JPEGIO=1 \
8694
-DCIRCUITPY_LOCALE=1 \
8795
-DCIRCUITPY_OS_GETENV=1 \
8896
-DCIRCUITPY_RAINBOWIO=1 \

py/circuitpy_defns.mk

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ endif
240240
ifeq ($(CIRCUITPY_IS31FL3741),1)
241241
SRC_PATTERNS += is31fl3741/%
242242
endif
243+
ifeq ($(CIRCUITPY_JPEGIO),1)
244+
SRC_PATTERNS += jpegio/%
245+
endif
243246
ifeq ($(CIRCUITPY_KEYPAD),1)
244247
SRC_PATTERNS += keypad/%
245248
endif
@@ -644,6 +647,8 @@ SRC_SHARED_MODULE_ALL = \
644647
is31fl3741/IS31FL3741.c \
645648
is31fl3741/FrameBuffer.c \
646649
is31fl3741/__init__.c \
650+
jpegio/__init__.c \
651+
jpegio/JpegDecoder.c \
647652
keypad/__init__.c \
648653
keypad/Event.c \
649654
keypad/EventQueue.c \
@@ -751,6 +756,11 @@ SRC_MOD += $(addprefix lib/AnimatedGIF/, \
751756
$(BUILD)/lib/AnimatedGIF/gif.o: CFLAGS += -DCIRCUITPY
752757
endif
753758

759+
ifeq ($(CIRCUITPY_JPEGIO),1)
760+
SRC_MOD += lib/tjpgd/src/tjpgd.c
761+
$(BUILD)/lib/tjpgd/src/tjpgd.o: CFLAGS += -Wno-shadow -Wno-cast-align
762+
endif
763+
754764
ifeq ($(CIRCUITPY_RGBMATRIX),1)
755765
SRC_MOD += $(addprefix lib/protomatter/src/, \
756766
core.c \

py/circuitpy_mpconfig.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS)
305305
CIRCUITPY_IS31FL3741 ?= 0
306306
CFLAGS += -DCIRCUITPY_IS31FL3741=$(CIRCUITPY_IS31FL3741)
307307

308+
CIRCUITPY_JPEGIO ?= 0
309+
CFLAGS += -DCIRCUITPY_JPEGIO=$(CIRCUITPY_JPEGIO)
310+
308311
CIRCUITPY_JSON ?= $(CIRCUITPY_FULL_BUILD)
309312
CFLAGS += -DCIRCUITPY_JSON=$(CIRCUITPY_JSON)
310313

shared-bindings/jpegio/JpegDecoder.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "py/obj.h"
28+
#include "py/runtime.h"
29+
30+
#include "shared-bindings/displayio/Bitmap.h"
31+
#include "shared-bindings/jpegio/JpegDecoder.h"
32+
#include "shared-module/jpegio/JpegDecoder.h"
33+
#include "shared-module/displayio/Bitmap.h"
34+
35+
//| class JpegDecoder:
36+
//| """A JPEG decoder"""
37+
//|
38+
//| def __init__(self) -> None: ...
39+
//|
40+
STATIC mp_obj_t jpegio_jpegdecoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
41+
static const mp_arg_t allowed_args[] = {
42+
};
43+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
44+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
45+
46+
jpegio_jpegdecoder_obj_t *self = mp_obj_malloc(jpegio_jpegdecoder_obj_t, &jpegio_jpegdecoder_type);
47+
self->base.type = &jpegio_jpegdecoder_type;
48+
49+
return MP_OBJ_FROM_PTR(self);
50+
}
51+
52+
//| def decode(
53+
//| self, data: ReadableBuffer, bitmap: displaycore.Bitmap | None = None, scale=0
54+
//| ) -> tuple[int, int]:
55+
//| """Decode JPEG data
56+
//|
57+
//| If ``bitmap`` is None, only the header is decoded.
58+
//| Otherwise, the bitmap must be large enough to contain the decoded image.
59+
//|
60+
//| The image is optionally downscaled by a factor of ``2**scale``.
61+
//| Scaling by a factor of 8 (scale=3) is particularly efficient in terms of decoding time.
62+
//|
63+
//| :param ReadableBuffer data: Data in JPEG format
64+
//| :param Bitmap bitmap: Optional output buffer
65+
//| :param int scale: Scale factor from 0 to 3.
66+
//| :returns: The size of the (possibly scaled) image as ``width, height``
67+
//| """
68+
//|
69+
STATIC mp_obj_t jpegio_jpegdecoder_decode(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
70+
jpegio_jpegdecoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
71+
72+
enum { ARG_data, ARG_bitmap, ARG_scale };
73+
static const mp_arg_t allowed_args[] = {
74+
{ MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = mp_const_none } },
75+
{ MP_QSTR_bitmap, MP_ARG_OBJ, {.u_obj = mp_const_none } },
76+
{ MP_QSTR_scale, MP_ARG_INT, {.u_int = 0 } },
77+
};
78+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
79+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
80+
81+
mp_buffer_info_t bufinfo;
82+
mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
83+
84+
mp_obj_t bitmap_in = args[ARG_bitmap].u_obj;
85+
mp_arg_validate_type_or_none(bitmap_in, &displayio_bitmap_type, MP_QSTR_bitmap);
86+
displayio_bitmap_t *bitmap = (args[ARG_bitmap].u_obj != mp_const_none) ? MP_OBJ_TO_PTR(args[ARG_bitmap].u_obj) : NULL;
87+
88+
int scale = args[ARG_scale].u_int;
89+
mp_arg_validate_int_range(scale, 0, 3, MP_QSTR_scale);
90+
91+
return common_hal_jpegio_jpegdecoder_decode(self, bitmap, &bufinfo, scale);
92+
}
93+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(jpegio_jpegdecoder_decode_obj, 2, jpegio_jpegdecoder_decode);
94+
95+
STATIC const mp_rom_map_elem_t jpegio_jpegdecoder_locals_dict_table[] = {
96+
{ MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&jpegio_jpegdecoder_decode_obj) },
97+
};
98+
STATIC MP_DEFINE_CONST_DICT(jpegio_jpegdecoder_locals_dict, jpegio_jpegdecoder_locals_dict_table);
99+
100+
MP_DEFINE_CONST_OBJ_TYPE(
101+
jpegio_jpegdecoder_type,
102+
MP_QSTR_JpegDecoder,
103+
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
104+
make_new, jpegio_jpegdecoder_make_new,
105+
locals_dict, &jpegio_jpegdecoder_locals_dict
106+
);

shared-bindings/jpegio/JpegDecoder.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "py/obj.h"
28+
#include "shared-module/displayio/Bitmap.h"
29+
30+
extern const mp_obj_type_t jpegio_jpegdecoder_type;
31+
32+
typedef struct jpegio_jpegdecoder_obj jpegio_jpegdecoder_obj_t;
33+
34+
void common_hal_jpegio_jpegdecoder_construct(jpegio_jpegdecoder_obj_t *self);
35+
mp_obj_t common_hal_jpegio_jpegdecoder_decode(jpegio_jpegdecoder_obj_t *self, displayio_bitmap_t *bitmap, mp_buffer_info_t *jpeg_data, int scale);

shared-bindings/jpegio/__init__.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "py/obj.h"
28+
#include "shared-bindings/jpegio/JpegDecoder.h"
29+
30+
//|
31+
//| """Support for JPEG image decoding"""
32+
//|
33+
34+
STATIC const mp_rom_map_elem_t jpegio_module_globals_table[] = {
35+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_jpegio) },
36+
{ MP_ROM_QSTR(MP_QSTR_JpegDecoder), MP_ROM_PTR(&jpegio_jpegdecoder_type) },
37+
};
38+
39+
STATIC MP_DEFINE_CONST_DICT(jpegio_module_globals, jpegio_module_globals_table);
40+
41+
const mp_obj_module_t jpegio_module = {
42+
.base = { &mp_type_module },
43+
.globals = (mp_obj_dict_t *)&jpegio_module_globals,
44+
};
45+
46+
MP_REGISTER_MODULE(MP_QSTR_jpegio, jpegio_module);

shared-bindings/jpegio/__init__.h

Whitespace-only changes.

0 commit comments

Comments
 (0)