2525 */
2626
2727#include "py/obj.h"
28+ #include "py/builtin.h"
2829#include "py/runtime.h"
2930
3031#include "shared-bindings/displayio/Bitmap.h"
3536//| class JpegDecoder:
3637//| """A JPEG decoder
3738//|
38- //| A JPEG decoder allocates a few thousand bytes of memory. To reduce memory fragmentation,
39+ //| A JpegDecoder allocates a few thousand bytes of memory. To reduce memory fragmentation,
3940//| create a single JpegDecoder object and use it anytime a JPEG image needs to be decoded.
41+ //|
42+ //| Example::
43+ //|
44+ //| from jpegio import JpegDecoder
45+ //| from displayio import Bitmap
46+ //|
47+ //| decoder = JpegDecoder()
48+ //| width, height = decoder.open("/sd/example.jpg")
49+ //| bitmap = Bitmap(width, height)
50+ //| decoder.decode(bitmap)
51+ //| # .. do something with bitmap
4052//| """
4153//|
4254//| def __init__(self) -> None: ...
@@ -54,51 +66,88 @@ STATIC mp_obj_t jpegio_jpegdecoder_make_new(const mp_obj_type_t *type, size_t n_
5466 return MP_OBJ_FROM_PTR (self );
5567}
5668
69+ //| @overload
70+ //| def open(self, filename: str) -> Tuple[int, int]: ...
71+ //| @overload
72+ //| def open(self, buffer: ReadableBuffer) -> Tuple[int, int]: ...
73+ //| @overload
74+ //| def open(self, bytesio: io.BytesIO) -> Tuple[int, int]:
75+ //| """Use the specified object as the JPEG data source.
76+ //|
77+ //| The source may be a filename, a binary buffer in memory, or an opened binary stream.
78+ //|
79+ //| The single parameter is positional-only (write ``open(f)``, not
80+ //| ``open(filename=f)`` but due to technical limitations this is
81+ //| not shown in the function signature in the documentation.
82+ //|
83+ //| Returns the image size as the tuple ``(width, height)``."""
84+ STATIC mp_obj_t jpegio_jpegdecoder_open (mp_obj_t self_in , mp_obj_t arg ) {
85+ jpegio_jpegdecoder_obj_t * self = MP_OBJ_TO_PTR (self_in );
86+ if (mp_obj_is_str (arg )) {
87+ arg = mp_call_function_2 (
88+ MP_OBJ_FROM_PTR (& mp_builtin_open_obj ),
89+ arg ,
90+ MP_OBJ_NEW_QSTR (MP_QSTR_rb ));
91+ }
92+
93+ mp_buffer_info_t bufinfo ;
94+ const mp_stream_p_t * proto = mp_get_stream (arg );
95+
96+ if (proto && proto -> read && !proto -> is_text ) {
97+ return common_hal_jpegio_jpegdecoder_set_source_file (self , arg );
98+ } else if (mp_get_buffer (arg , & bufinfo , MP_BUFFER_READ )) {
99+ return common_hal_jpegio_jpegdecoder_set_source_buffer (self , arg );
100+ }
101+ mp_raise_TypeError_varg (MP_ERROR_TEXT ("%q must be of type %q, %q, or %q, not %q" ), MP_QSTR_data_source , MP_QSTR_str , MP_QSTR_BytesIO , MP_QSTR_ReadableBuffer );
102+ }
103+ MP_DEFINE_CONST_FUN_OBJ_2 (jpegio_jpegdecoder_open_obj , jpegio_jpegdecoder_open );
104+
57105//| def decode(
58- //| self, data: ReadableBuffer, bitmap: displayio.Bitmap | None = None, scale=0
59- //| ) -> tuple[int, int]:
106+ //| self,
107+ //| bitmap: displayio.Bitmap,
108+ //| scale: int = 0,
109+ //| ) -> None:
60110//| """Decode JPEG data
61111//|
62- //| If ``bitmap`` is None, only the header is decoded.
63- //| Otherwise, the bitmap must be large enough to contain the decoded image.
112+ //| The bitmap must be large enough to contain the decoded image.
64113//| The pixel data is stored in the `displayio.Colorspace.RGB565_SWAPPED` colorspace.
65114//|
66115//| The image is optionally downscaled by a factor of ``2**scale``.
67116//| Scaling by a factor of 8 (scale=3) is particularly efficient in terms of decoding time.
68117//|
69- //| :param ReadableBuffer data: Data in JPEG format
118+ //| After a call to ``decode``, you must ``open`` a new JPEG. It is not
119+ //| possible to repeatedly ``decode`` the same jpeg data, even if it is to
120+ //| select different scales or crop regions from it.
121+ //|
70122//| :param Bitmap bitmap: Optional output buffer
71- //| :param int scale: Scale factor from 0 to 3.
72- //| :returns: The size of the (possibly scaled) image as ``width, height``
123+ //| :param int scale: Scale factor from 0 to 3, inclusive.
73124//| """
74125//|
75126STATIC mp_obj_t jpegio_jpegdecoder_decode (mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
76127 jpegio_jpegdecoder_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
77128
78- enum { ARG_data , ARG_bitmap , ARG_scale };
129+ enum { ARG_bitmap , ARG_scale };
79130 static const mp_arg_t allowed_args [] = {
80- { MP_QSTR_data , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = mp_const_none } },
81- { MP_QSTR_bitmap , MP_ARG_OBJ , {.u_obj = mp_const_none } },
131+ { MP_QSTR_bitmap , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = mp_const_none } },
82132 { MP_QSTR_scale , MP_ARG_INT , {.u_int = 0 } },
83133 };
84134 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
85135 mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
86136
87- mp_buffer_info_t bufinfo ;
88- mp_get_buffer_raise (args [ARG_data ].u_obj , & bufinfo , MP_BUFFER_READ );
89-
90137 mp_obj_t bitmap_in = args [ARG_bitmap ].u_obj ;
91- mp_arg_validate_type_or_none (bitmap_in , & displayio_bitmap_type , MP_QSTR_bitmap );
92- displayio_bitmap_t * bitmap = ( args [ ARG_bitmap ]. u_obj != mp_const_none ) ? MP_OBJ_TO_PTR (args [ARG_bitmap ].u_obj ) : NULL ;
138+ mp_arg_validate_type (bitmap_in , & displayio_bitmap_type , MP_QSTR_bitmap );
139+ displayio_bitmap_t * bitmap = MP_OBJ_TO_PTR (args [ARG_bitmap ].u_obj );
93140
94141 int scale = args [ARG_scale ].u_int ;
95142 mp_arg_validate_int_range (scale , 0 , 3 , MP_QSTR_scale );
96143
97- return common_hal_jpegio_jpegdecoder_decode (self , bitmap , & bufinfo , scale );
144+ common_hal_jpegio_jpegdecoder_decode_into (self , bitmap , scale );
145+ return mp_const_none ;
98146}
99- STATIC MP_DEFINE_CONST_FUN_OBJ_KW (jpegio_jpegdecoder_decode_obj , 2 , jpegio_jpegdecoder_decode );
147+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (jpegio_jpegdecoder_decode_obj , 1 , jpegio_jpegdecoder_decode );
100148
101149STATIC const mp_rom_map_elem_t jpegio_jpegdecoder_locals_dict_table [] = {
150+ { MP_ROM_QSTR (MP_QSTR_open ), MP_ROM_PTR (& jpegio_jpegdecoder_open_obj ) },
102151 { MP_ROM_QSTR (MP_QSTR_decode ), MP_ROM_PTR (& jpegio_jpegdecoder_decode_obj ) },
103152};
104153STATIC MP_DEFINE_CONST_DICT (jpegio_jpegdecoder_locals_dict , jpegio_jpegdecoder_locals_dict_table );
0 commit comments