From b4bedf43c2203a338a7c2239d73c0340853883fc Mon Sep 17 00:00:00 2001 From: Skyler Mansfield <90399509+Skyler84@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:50:19 +0000 Subject: [PATCH] JPEGDEC: Backport width/height changes from pngdec. --- micropython/modules/jpegdec/jpegdec.c | 2 - micropython/modules/jpegdec/jpegdec.cpp | 72 +++++++++++++++---------- micropython/modules/jpegdec/jpegdec.h | 1 - 3 files changed, 44 insertions(+), 31 deletions(-) diff --git a/micropython/modules/jpegdec/jpegdec.c b/micropython/modules/jpegdec/jpegdec.c index 3696fa4ac..85dfade93 100644 --- a/micropython/modules/jpegdec/jpegdec.c +++ b/micropython/modules/jpegdec/jpegdec.c @@ -3,7 +3,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(JPEG_del_obj, _JPEG_del); STATIC MP_DEFINE_CONST_FUN_OBJ_2(JPEG_openRAM_obj, _JPEG_openRAM); STATIC MP_DEFINE_CONST_FUN_OBJ_2(JPEG_openFILE_obj, _JPEG_openFILE); -STATIC MP_DEFINE_CONST_FUN_OBJ_2(JPEG_close_obj, _JPEG_close); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(JPEG_decode_obj, 1, _JPEG_decode); STATIC MP_DEFINE_CONST_FUN_OBJ_1(JPEG_getWidth_obj, _JPEG_getWidth); STATIC MP_DEFINE_CONST_FUN_OBJ_1(JPEG_getHeight_obj, _JPEG_getHeight); @@ -13,7 +12,6 @@ STATIC const mp_rom_map_elem_t JPEG_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&JPEG_del_obj) }, { MP_ROM_QSTR(MP_QSTR_open_RAM), MP_ROM_PTR(&JPEG_openRAM_obj) }, { MP_ROM_QSTR(MP_QSTR_open_file), MP_ROM_PTR(&JPEG_openFILE_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&JPEG_close_obj) }, { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&JPEG_decode_obj) }, { MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&JPEG_getWidth_obj) }, { MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&JPEG_getHeight_obj) }, diff --git a/micropython/modules/jpegdec/jpegdec.cpp b/micropython/modules/jpegdec/jpegdec.cpp index f23e1a0ec..e53de2ec3 100644 --- a/micropython/modules/jpegdec/jpegdec.cpp +++ b/micropython/modules/jpegdec/jpegdec.cpp @@ -26,6 +26,8 @@ typedef struct _JPEG_obj_t { mp_obj_t file; mp_buffer_info_t buf; ModPicoGraphics_obj_t *graphics; + int width; + int height; } _JPEG_obj_t; @@ -83,6 +85,30 @@ int32_t jpegdec_seek_callback(JPEGFILE *jpeg, int32_t p) { return seek_s.offset; } +void jpegdec_open_helper(_JPEG_obj_t *self) { + int result = -1; + + if(mp_obj_is_str(self->file)){ + GET_STR_DATA_LEN(self->file, str, str_len); + + result = self->jpeg->open( + (const char*)str, + jpegdec_open_callback, + jpegdec_close_callback, + jpegdec_read_callback, + jpegdec_seek_callback, + JPEGDraw); + + // Source is a buffer + } else { + mp_get_buffer_raise(self->file, &self->buf, MP_BUFFER_READ); + + result = self->jpeg->openRAM((uint8_t *)self->buf.buf, self->buf.len, self->decode_callback); + } + + if(result != 0) mp_raise_msg(&mp_type_RuntimeError, "JPEG: could not read file/buffer."); +} + int JPEGDraw(JPEGDRAW *pDraw) { #ifdef mp_event_handle_nowait mp_event_handle_nowait(); @@ -205,20 +231,13 @@ mp_obj_t _JPEG_openFILE(mp_obj_t self_in, mp_obj_t filename) { _JPEG_obj_t *self = MP_OBJ_TO_PTR2(self_in, _JPEG_obj_t); // TODO Check for valid filename, and maybe that file exists? - if (!mp_obj_is_str(self->file)) - return mp_const_false; - GET_STR_DATA_LEN(filename, str, str_len); + self->file = filename; - result = self->jpeg->open( - (const char*)str, - jpegdec_open_callback, - jpegdec_close_callback, - jpegdec_read_callback, - jpegdec_seek_callback, - JPEGDraw); - - if(result != 1) mp_raise_msg(&mp_type_RuntimeError, "JPEG: could not read file."); + jpegdec_open_helper(self); + self->width = self->jpeg->getWidth(); + self->height = self->jpeg->getHeight(); + self->jpeg->close(); return mp_const_true; } @@ -229,22 +248,14 @@ mp_obj_t _JPEG_openRAM(mp_obj_t self_in, mp_obj_t buffer) { // TODO Check for valid buffer - mp_get_buffer_raise(buffer, &self->buf, MP_BUFFER_READ); - - result = self->jpeg->openRAM((uint8_t *)self->buf.buf, self->buf.len, JPEGDraw); - - if(result != 1) mp_raise_msg(&mp_type_RuntimeError, "JPEG: could not read buffer."); - - return mp_const_true; -} - -// close -mp_obj_t _JPEG_close(mp_obj_t self_in) { - _JPEG_obj_t *self = MP_OBJ_TO_PTR2(self_in, _JPEG_obj_t); + self->file = buffer; + jpegdec_open_helper(self); + self->width = self->jpeg->getWidth(); + self->height = self->jpeg->getHeight(); self->jpeg->close(); - return mp_const_none; + return mp_const_true; } // decode @@ -269,6 +280,8 @@ mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args current_flags = args[ARG_dither].u_obj == mp_const_false ? FLAG_NO_DITHER : 0; + jpegdec_open_helper(self); + // Force a specific data output type to best match our PicoGraphics buffer switch(self->graphics->graphics->pen_type) { case PicoGraphics::PEN_RGB332: @@ -293,23 +306,26 @@ mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args // We need to store a pointer to the PicoGraphics surface self->jpeg->setUserPointer((void *)self->graphics->graphics); - result = self->jpeg->decode(x, y, f); + int result = self->jpeg->decode(x, y, f); current_flags = 0; + // Close the file since we've opened it on-demand + self->jpeg->close(); + return result == 1 ? mp_const_true : mp_const_false; } // get_width mp_obj_t _JPEG_getWidth(mp_obj_t self_in) { _JPEG_obj_t *self = MP_OBJ_TO_PTR2(self_in, _JPEG_obj_t); - return mp_obj_new_int(self->jpeg->getWidth()); + return mp_obj_new_int(self->width); } // get_height mp_obj_t _JPEG_getHeight(mp_obj_t self_in) { _JPEG_obj_t *self = MP_OBJ_TO_PTR2(self_in, _JPEG_obj_t); - return mp_obj_new_int(self->jpeg->getHeight()); + return mp_obj_new_int(self->height); } } diff --git a/micropython/modules/jpegdec/jpegdec.h b/micropython/modules/jpegdec/jpegdec.h index bc6b13886..fd1a59de4 100644 --- a/micropython/modules/jpegdec/jpegdec.h +++ b/micropython/modules/jpegdec/jpegdec.h @@ -7,7 +7,6 @@ extern mp_obj_t _JPEG_make_new(const mp_obj_type_t *type, size_t n_args, size_t extern mp_obj_t _JPEG_del(mp_obj_t self_in); extern mp_obj_t _JPEG_openRAM(mp_obj_t self_in, mp_obj_t buffer); extern mp_obj_t _JPEG_openFILE(mp_obj_t self_in, mp_obj_t filename); -extern mp_obj_t _JPEG_close(mp_obj_t self_in); extern mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); extern mp_obj_t _JPEG_getWidth(mp_obj_t self_in); extern mp_obj_t _JPEG_getHeight(mp_obj_t self_in); \ No newline at end of file