kopia lustrzana https://github.com/pimoroni/pimoroni-pico
JPEGDEC: Move to libraries, use C++, draw into PicoGraphics.
rodzic
1a9ebb7b6e
commit
7f0fe44881
|
|
@ -0,0 +1,199 @@
|
|||
//
|
||||
// JPEG Decoder
|
||||
//
|
||||
// written by Larry Bank
|
||||
// bitbank@pobox.com
|
||||
// Arduino port started 8/2/2020
|
||||
// Original JPEG code written 26+ years ago :)
|
||||
// The goal of this code is to decode baseline JPEG images
|
||||
// using no more than 18K of RAM (if sent directly to an LCD display)
|
||||
//
|
||||
// Copyright 2020 BitBank Software, Inc. All Rights Reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//===========================================================================
|
||||
//
|
||||
#include "JPEGDEC.h"
|
||||
|
||||
// forward references
|
||||
JPEG_STATIC int JPEGInit(JPEGIMAGE *pJPEG);
|
||||
JPEG_STATIC int JPEGParseInfo(JPEGIMAGE *pPage, int bExtractThumb);
|
||||
JPEG_STATIC void JPEGGetMoreData(JPEGIMAGE *pPage);
|
||||
JPEG_STATIC int DecodeJPEG(JPEGIMAGE *pImage);
|
||||
|
||||
// Include the C code which does the actual work
|
||||
#include "jpeg.inl"
|
||||
|
||||
void JPEGDEC::setPixelType(int iType)
|
||||
{
|
||||
if (iType >= 0 && iType < INVALID_PIXEL_TYPE)
|
||||
_jpeg.ucPixelType = (uint8_t)iType;
|
||||
else
|
||||
_jpeg.iError = JPEG_INVALID_PARAMETER;
|
||||
} /* setPixelType() */
|
||||
|
||||
void JPEGDEC::setMaxOutputSize(int iMaxMCUs)
|
||||
{
|
||||
if (iMaxMCUs < 1)
|
||||
iMaxMCUs = 1; // don't allow invalid value
|
||||
_jpeg.iMaxMCUs = iMaxMCUs;
|
||||
} /* setMaxOutputSize() */
|
||||
//
|
||||
// Memory initialization
|
||||
//
|
||||
int JPEGDEC::openRAM(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw)
|
||||
{
|
||||
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
|
||||
_jpeg.ucMemType = JPEG_MEM_RAM;
|
||||
_jpeg.pfnRead = readRAM;
|
||||
_jpeg.pfnSeek = seekMem;
|
||||
_jpeg.pfnDraw = pfnDraw;
|
||||
_jpeg.pfnOpen = NULL;
|
||||
_jpeg.pfnClose = NULL;
|
||||
_jpeg.JPEGFile.iSize = iDataSize;
|
||||
_jpeg.JPEGFile.pData = pData;
|
||||
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
|
||||
return JPEGInit(&_jpeg);
|
||||
} /* openRAM() */
|
||||
|
||||
int JPEGDEC::openFLASH(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw)
|
||||
{
|
||||
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
|
||||
_jpeg.ucMemType = JPEG_MEM_FLASH;
|
||||
_jpeg.pfnRead = readFLASH;
|
||||
_jpeg.pfnSeek = seekMem;
|
||||
_jpeg.pfnDraw = pfnDraw;
|
||||
_jpeg.pfnOpen = NULL;
|
||||
_jpeg.pfnClose = NULL;
|
||||
_jpeg.JPEGFile.iSize = iDataSize;
|
||||
_jpeg.JPEGFile.pData = pData;
|
||||
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
|
||||
return JPEGInit(&_jpeg);
|
||||
} /* openRAM() */
|
||||
|
||||
int JPEGDEC::getOrientation()
|
||||
{
|
||||
return (int)_jpeg.ucOrientation;
|
||||
} /* getOrientation() */
|
||||
|
||||
int JPEGDEC::getLastError()
|
||||
{
|
||||
return _jpeg.iError;
|
||||
} /* getLastError() */
|
||||
|
||||
int JPEGDEC::getWidth()
|
||||
{
|
||||
return _jpeg.iWidth;
|
||||
} /* getWidth() */
|
||||
|
||||
int JPEGDEC::getHeight()
|
||||
{
|
||||
return _jpeg.iHeight;
|
||||
} /* getHeight() */
|
||||
|
||||
int JPEGDEC::hasThumb()
|
||||
{
|
||||
return (int)_jpeg.ucHasThumb;
|
||||
} /* hasThumb() */
|
||||
|
||||
int JPEGDEC::getThumbWidth()
|
||||
{
|
||||
return _jpeg.iThumbWidth;
|
||||
} /* getThumbWidth() */
|
||||
|
||||
int JPEGDEC::getThumbHeight()
|
||||
{
|
||||
return _jpeg.iThumbHeight;
|
||||
} /* getThumbHeight() */
|
||||
|
||||
int JPEGDEC::getBpp()
|
||||
{
|
||||
return (int)_jpeg.ucBpp;
|
||||
} /* getBpp() */
|
||||
|
||||
int JPEGDEC::getSubSample()
|
||||
{
|
||||
return (int)_jpeg.ucSubSample;
|
||||
} /* getSubSample() */
|
||||
|
||||
//
|
||||
// File (SD/MMC) based initialization
|
||||
//
|
||||
int JPEGDEC::open(const char *szFilename, JPEG_OPEN_CALLBACK *pfnOpen, JPEG_CLOSE_CALLBACK *pfnClose, JPEG_READ_CALLBACK *pfnRead, JPEG_SEEK_CALLBACK *pfnSeek, JPEG_DRAW_CALLBACK *pfnDraw)
|
||||
{
|
||||
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
|
||||
_jpeg.pfnRead = pfnRead;
|
||||
_jpeg.pfnSeek = pfnSeek;
|
||||
_jpeg.pfnDraw = pfnDraw;
|
||||
_jpeg.pfnOpen = pfnOpen;
|
||||
_jpeg.pfnClose = pfnClose;
|
||||
_jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start
|
||||
_jpeg.JPEGFile.fHandle = (*pfnOpen)(szFilename, &_jpeg.JPEGFile.iSize);
|
||||
if (_jpeg.JPEGFile.fHandle == NULL)
|
||||
return 0;
|
||||
return JPEGInit(&_jpeg);
|
||||
|
||||
} /* open() */
|
||||
|
||||
#ifdef FS_H
|
||||
static int32_t FileRead(JPEGFILE *handle, uint8_t *buffer, int32_t length)
|
||||
{
|
||||
return ((File *)(handle->fHandle))->read(buffer, length);
|
||||
}
|
||||
static int32_t FileSeek(JPEGFILE *handle, int32_t position)
|
||||
{
|
||||
return ((File *)(handle->fHandle))->seek(position);
|
||||
}
|
||||
static void FileClose(void *handle)
|
||||
{
|
||||
((File *)handle)->close();
|
||||
}
|
||||
|
||||
int JPEGDEC::open(File &file, JPEG_DRAW_CALLBACK *pfnDraw)
|
||||
{
|
||||
if (!file) return 0;
|
||||
memset(&_jpeg, 0, sizeof(JPEGIMAGE));
|
||||
_jpeg.pfnRead = FileRead;
|
||||
_jpeg.pfnSeek = FileSeek;
|
||||
_jpeg.pfnClose = FileClose;
|
||||
_jpeg.pfnDraw = pfnDraw;
|
||||
_jpeg.iMaxMCUs = 1000;
|
||||
_jpeg.JPEGFile.fHandle = &file;
|
||||
_jpeg.JPEGFile.iSize = file.size();
|
||||
return JPEGInit(&_jpeg);
|
||||
}
|
||||
#endif // FS_H
|
||||
|
||||
void JPEGDEC::close()
|
||||
{
|
||||
if (_jpeg.pfnClose)
|
||||
(*_jpeg.pfnClose)(_jpeg.JPEGFile.fHandle);
|
||||
} /* close() */
|
||||
|
||||
//
|
||||
// Decode the image
|
||||
// returns:
|
||||
// 1 = good result
|
||||
// 0 = error
|
||||
//
|
||||
int JPEGDEC::decode(int x, int y, int iOptions)
|
||||
{
|
||||
_jpeg.iXOffset = x;
|
||||
_jpeg.iYOffset = y;
|
||||
_jpeg.iOptions = iOptions;
|
||||
return DecodeJPEG(&_jpeg);
|
||||
} /* decode() */
|
||||
|
||||
int JPEGDEC::decodeDither(uint8_t *pDither, int iOptions)
|
||||
{
|
||||
_jpeg.iOptions = iOptions;
|
||||
_jpeg.pDitherBuffer = pDither;
|
||||
return DecodeJPEG(&_jpeg);
|
||||
}
|
||||
|
|
@ -1,90 +1,9 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/objstr.h"
|
||||
#include "JPEGDEC.h"
|
||||
#include "jpegdec.h"
|
||||
|
||||
const mp_obj_type_t JPEG_type;
|
||||
|
||||
typedef struct _JPEG_obj_t {
|
||||
mp_obj_base_t base;
|
||||
JPEGIMAGE *jpeg;
|
||||
mp_obj_t callback;
|
||||
} _JPEG_obj_t;
|
||||
|
||||
mp_obj_t current_callback = mp_const_none;
|
||||
|
||||
int JPEGDraw(JPEGDRAW *pDraw) {
|
||||
for(int y = 0; y < pDraw->iHeight; y++) {
|
||||
for(int x = 0; x < pDraw->iWidth; x++) {
|
||||
int i = y * pDraw->iWidth + x;
|
||||
mp_obj_t args[] = {
|
||||
mp_obj_new_int(pDraw->x + x),
|
||||
mp_obj_new_int(pDraw->y + y),
|
||||
mp_obj_new_int(pDraw->pPixels[i])
|
||||
};
|
||||
mp_call_function_n_kw(current_callback, MP_ARRAY_SIZE(args), 0, args);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t _JPEG_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum {
|
||||
ARG_callback
|
||||
};
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_callback, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
_JPEG_obj_t *self = m_new_obj_with_finaliser(_JPEG_obj_t);
|
||||
self->base.type = &JPEG_type;
|
||||
self->jpeg = m_new(JPEGIMAGE, 1);
|
||||
self->callback = args[ARG_callback].u_obj;
|
||||
return self;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t _JPEG_del(mp_obj_t self_in) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
m_del(JPEGIMAGE, self->jpeg, 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(JPEG_del_obj, _JPEG_del);
|
||||
|
||||
// open_RAM
|
||||
STATIC mp_obj_t _JPEG_openRAM(mp_obj_t self_in, mp_obj_t buffer) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ);
|
||||
int result = JPEG_openRAM(self->jpeg, bufinfo.buf, bufinfo.len, JPEGDraw);
|
||||
JPEG_setPixelType(self->jpeg, RGB565_BIG_ENDIAN);
|
||||
return result == 1 ? mp_const_true : mp_const_false;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(JPEG_openRAM_obj, _JPEG_openRAM);
|
||||
|
||||
// decode
|
||||
STATIC mp_obj_t _JPEG_decode(mp_obj_t self_in, mp_obj_t flags) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int f = mp_obj_get_int(flags);
|
||||
current_callback = self->callback;
|
||||
return JPEG_decode(self->jpeg, x, y, f) == 1 ? mp_const_true : mp_const_false;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(JPEG_decode_obj, _JPEG_decode);
|
||||
|
||||
// get_width
|
||||
STATIC mp_obj_t _JPEG_getWidth(mp_obj_t self_in) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_int(JPEG_getWidth(self->jpeg));
|
||||
}
|
||||
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);
|
||||
|
||||
// get_height
|
||||
STATIC mp_obj_t _JPEG_getHeight(mp_obj_t self_in) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_int(JPEG_getHeight(self->jpeg));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(JPEG_getHeight_obj, _JPEG_getHeight);
|
||||
|
||||
// class
|
||||
|
|
@ -112,10 +31,12 @@ STATIC const mp_map_elem_t JPEG_globals_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_jpegdec) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_JPEG), (mp_obj_t)&JPEG_type },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_JPEG_globals, JPEG_globals_table);
|
||||
|
||||
const mp_obj_module_t JPEG_user_cmodule = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_JPEG_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_jpegdec, JPEG_user_cmodule, MODULE_JPEGDEC_ENABLED);
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
#include "libraries/jpegdec/JPEGDEC.h"
|
||||
|
||||
#include "micropython/modules/util.hpp"
|
||||
#include "libraries/pico_graphics/pico_graphics.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
extern "C" {
|
||||
#include "jpegdec.h"
|
||||
#include "micropython/modules/picographics/picographics.h"
|
||||
|
||||
typedef struct _ModPicoGraphics_obj_t {
|
||||
mp_obj_base_t base;
|
||||
PicoGraphics *graphics;
|
||||
DisplayDriver *display;
|
||||
void *buffer;
|
||||
} ModPicoGraphics_obj_t;
|
||||
|
||||
typedef struct _JPEG_obj_t {
|
||||
mp_obj_base_t base;
|
||||
JPEGDEC *jpeg;
|
||||
mp_obj_t callback;
|
||||
ModPicoGraphics_obj_t *graphics;
|
||||
} _JPEG_obj_t;
|
||||
|
||||
PicoGraphics *current_graphics = nullptr;
|
||||
|
||||
int JPEGDraw(JPEGDRAW *pDraw) {
|
||||
// "pixel" is slow and clipped,
|
||||
// guaranteeing we wont draw jpeg data out of the framebuffer..
|
||||
// Can we clip beforehand and make this faster?
|
||||
if(pDraw->iBpp == 4) { // TODO 4-bit pixel unpacking isn't working. What's up?
|
||||
uint8_t *pixels = (uint8_t *)pDraw->pPixels;
|
||||
for(int y = 0; y < pDraw->iHeight; y++) {
|
||||
for(int x = 0; x < pDraw->iWidth; x++) {
|
||||
int i = y * pDraw->iWidth + x;
|
||||
uint8_t p = pixels[i / 2];
|
||||
p >>= (i & 0b1) * 4;
|
||||
p &= 0xf;
|
||||
current_graphics->set_pen(p);
|
||||
current_graphics->pixel({pDraw->x + x, pDraw->y + y});
|
||||
}
|
||||
}
|
||||
} else if(pDraw->iBpp == 8) {
|
||||
uint8_t *pixels = (uint8_t *)pDraw->pPixels;
|
||||
for(int y = 0; y < pDraw->iHeight; y++) {
|
||||
for(int x = 0; x < pDraw->iWidth; x++) {
|
||||
int i = y * pDraw->iWidth + x;
|
||||
current_graphics->set_pen(pixels[i] >> (current_graphics->pen_type == PicoGraphics::PEN_P4 ? 4 : 0));
|
||||
current_graphics->pixel({pDraw->x + x, pDraw->y + y});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int y = 0; y < pDraw->iHeight; y++) {
|
||||
for(int x = 0; x < pDraw->iWidth; x++) {
|
||||
int i = y * pDraw->iWidth + x;
|
||||
if (current_graphics->pen_type == PicoGraphics::PEN_RGB332) {
|
||||
current_graphics->set_pen(PicoGraphics::rgb565_to_rgb332(pDraw->pPixels[i]));
|
||||
} else {
|
||||
current_graphics->set_pen(pDraw->pPixels[i]);
|
||||
}
|
||||
current_graphics->pixel({pDraw->x + x, pDraw->y + y});
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
mp_obj_t _JPEG_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum {
|
||||
ARG_picographics
|
||||
};
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_picographics, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if(!MP_OBJ_IS_TYPE(args[ARG_picographics].u_obj, &ModPicoGraphics_type)) mp_raise_ValueError(MP_ERROR_TEXT("PicoGraphics Object Required"));
|
||||
|
||||
_JPEG_obj_t *self = m_new_obj_with_finaliser(_JPEG_obj_t);
|
||||
self->base.type = &JPEG_type;
|
||||
self->jpeg = m_new_class(JPEGDEC);
|
||||
self->graphics = (ModPicoGraphics_obj_t *)MP_OBJ_TO_PTR(args[ARG_picographics].u_obj);
|
||||
return self;
|
||||
}
|
||||
|
||||
mp_obj_t _JPEG_del(mp_obj_t self_in) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR2(self_in, _JPEG_obj_t);
|
||||
(void)self;
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// open_RAM
|
||||
mp_obj_t _JPEG_openRAM(mp_obj_t self_in, mp_obj_t buffer) {
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR2(self_in, _JPEG_obj_t);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ);
|
||||
int result = self->jpeg->openRAM((uint8_t *)bufinfo.buf, bufinfo.len, JPEGDraw);
|
||||
if (result == 1) {
|
||||
switch(self->graphics->graphics->pen_type) {
|
||||
case PicoGraphics::PEN_RGB332:
|
||||
case PicoGraphics::PEN_RGB565:
|
||||
self->jpeg->setPixelType(RGB565_BIG_ENDIAN);
|
||||
break;
|
||||
case PicoGraphics::PEN_P8:
|
||||
self->jpeg->setPixelType(EIGHT_BIT_GRAYSCALE);
|
||||
break;
|
||||
// TODO currently uses EIGHT_BIT_GREYSCALE and shifts down should this use a 4-bit dither?
|
||||
case PicoGraphics::PEN_P4:
|
||||
self->jpeg->setPixelType(EIGHT_BIT_GRAYSCALE);
|
||||
break;
|
||||
// TODO 2-bit is currently unsupported
|
||||
case PicoGraphics::PEN_P2:
|
||||
self->jpeg->setPixelType(TWO_BIT_DITHERED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result == 1 ? mp_const_true : mp_const_false;
|
||||
}
|
||||
|
||||
// decode
|
||||
mp_obj_t _JPEG_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_self, ARG_x, ARG_y, ARG_scale };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_x, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_y, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_scale, MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
_JPEG_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _JPEG_obj_t);
|
||||
|
||||
int x = args[ARG_x].u_int;
|
||||
int y = args[ARG_y].u_int;
|
||||
int f = args[ARG_scale].u_int;
|
||||
|
||||
// We need to store a pointer to the PicoGraphics surface
|
||||
// since the JPEGDRAW struct has no userdata
|
||||
current_graphics = self->graphics->graphics;
|
||||
int result = self->jpeg->decode(x, y, f);
|
||||
current_graphics = nullptr;
|
||||
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());
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/objstr.h"
|
||||
|
||||
extern const mp_obj_type_t JPEG_type;
|
||||
|
||||
extern mp_obj_t _JPEG_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
|
||||
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_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);
|
||||
|
|
@ -2,7 +2,8 @@ add_library(usermod_jpegdec INTERFACE)
|
|||
|
||||
target_sources(usermod_jpegdec INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/jpegdec.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/jpeg.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/jpegdec.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/../../../libraries/jpegdec/JPEGDEC.cpp
|
||||
)
|
||||
|
||||
target_include_directories(usermod_jpegdec INTERFACE
|
||||
|
|
@ -15,4 +16,4 @@ target_compile_definitions(usermod_jpegdec INTERFACE
|
|||
|
||||
target_link_libraries(usermod INTERFACE usermod_jpegdec)
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/jpeg.c PROPERTIES COMPILE_FLAGS "-Wno-error=unused-function")
|
||||
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/../../../libraries/jpegdec/JPEGDEC.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=unused-function")
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue