From 241e7254649a4df1673a4e5c197689c88b0af355 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 13 Dec 2022 14:21:55 +0000 Subject: [PATCH] JPEGDEC: Sync with upstream. Adds setUserPointer and pDraw->pUser which we now use to store a pointer to the PicoGraphics instance. --- libraries/jpegdec/JPEGDEC.cpp | 23 +++++++++++++++++++++++ libraries/jpegdec/JPEGDEC.h | 6 +++++- libraries/jpegdec/jpeg.inl | 24 +++++++++++++----------- micropython/modules/jpegdec/jpegdec.cpp | 6 ++---- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/libraries/jpegdec/JPEGDEC.cpp b/libraries/jpegdec/JPEGDEC.cpp index fd3c82e0..c773bf28 100644 --- a/libraries/jpegdec/JPEGDEC.cpp +++ b/libraries/jpegdec/JPEGDEC.cpp @@ -142,6 +142,22 @@ int JPEGDEC::open(const char *szFilename, JPEG_OPEN_CALLBACK *pfnOpen, JPEG_CLOS } /* open() */ +// +// data stream initialization +// +int JPEGDEC::open(void *fHandle, int iDataSize, 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.pfnClose = pfnClose; + _jpeg.iMaxMCUs = 1000; // set to an unnaturally high value to start + _jpeg.JPEGFile.iSize = iDataSize; + _jpeg.JPEGFile.fHandle = fHandle; + return JPEGInit(&_jpeg); +} /* open() */ + #ifdef FS_H static int32_t FileRead(JPEGFILE *handle, uint8_t *buffer, int32_t length) { @@ -191,6 +207,13 @@ int JPEGDEC::decode(int x, int y, int iOptions) _jpeg.pDitherBuffer = nullptr; return DecodeJPEG(&_jpeg); } /* decode() */ +// +// set draw callback user pointer variable +// +void JPEGDEC::setUserPointer(void *p) +{ + _jpeg.pUser = p; +} // TODO PR these tweaks to https://github.com/bitbank2/JPEGDEC int JPEGDEC::decodeDither(int x, int y, uint8_t *pDither, int iOptions) diff --git a/libraries/jpegdec/JPEGDEC.h b/libraries/jpegdec/JPEGDEC.h index 8f88ff33..f49cd3b5 100644 --- a/libraries/jpegdec/JPEGDEC.h +++ b/libraries/jpegdec/JPEGDEC.h @@ -13,7 +13,7 @@ // #ifndef __JPEGDEC__ #define __JPEGDEC__ -#if defined( __MACH__ ) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) || defined( PICO_BUILD ) +#if defined( __MACH__ ) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) || defined( ESP_PLATFORM ) || defined( PICO_BUILD ) #include #include #include @@ -110,6 +110,7 @@ typedef struct jpeg_draw_tag int iWidth, iHeight; // size of this MCU int iBpp; // bit depth of the pixels (8 or 16) uint16_t *pPixels; // 16-bit pixels + void *pUser; } JPEGDRAW; // Callback function prototypes @@ -185,6 +186,7 @@ typedef struct jpeg_image_tag JPEGCOMPINFO JPCI[MAX_COMPS_IN_SCAN]; /* Max color components */ JPEGFILE JPEGFile; BUFFERED_BITS bb; + void *pUser; uint8_t *pDitherBuffer; // provided externally to do Floyd-Steinberg dithering uint16_t usPixels[MAX_BUFFERED_PIXELS]; int16_t sMCUs[DCTSIZE * MAX_MCU_COUNT]; // 4:2:0 needs 6 DCT blocks per MCU @@ -208,6 +210,7 @@ class JPEGDEC int openRAM(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw); int openFLASH(uint8_t *pData, int iDataSize, JPEG_DRAW_CALLBACK *pfnDraw); int open(const char *szFilename, JPEG_OPEN_CALLBACK *pfnOpen, JPEG_CLOSE_CALLBACK *pfnClose, JPEG_READ_CALLBACK *pfnRead, JPEG_SEEK_CALLBACK *pfnSeek, JPEG_DRAW_CALLBACK *pfnDraw); + int open(void *fHandle, int iDataSize, JPEG_CLOSE_CALLBACK *pfnClose, JPEG_READ_CALLBACK *pfnRead, JPEG_SEEK_CALLBACK *pfnSeek, JPEG_DRAW_CALLBACK *pfnDraw); #ifdef FS_H int open(File &file, JPEG_DRAW_CALLBACK *pfnDraw); #endif @@ -218,6 +221,7 @@ class JPEGDEC int getWidth(); int getHeight(); int getBpp(); + void setUserPointer(void *p); int getSubSample(); int hasThumb(); int getThumbWidth(); diff --git a/libraries/jpegdec/jpeg.inl b/libraries/jpegdec/jpeg.inl index 6618a35c..57c9261e 100644 --- a/libraries/jpegdec/jpeg.inl +++ b/libraries/jpegdec/jpeg.inl @@ -33,9 +33,11 @@ static void JPEGGetMoreData(JPEGIMAGE *pPage); static int DecodeJPEG(JPEGIMAGE *pImage); static int32_t readRAM(JPEGFILE *pFile, uint8_t *pBuf, int32_t iLen); static int32_t seekMem(JPEGFILE *pFile, int32_t iPosition); +#if defined (__MACH__) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) static int32_t readFile(JPEGFILE *pFile, uint8_t *pBuf, int32_t iLen); static int32_t seekFile(JPEGFILE *pFile, int32_t iPosition); static void closeFile(void *handle); +#endif static void JPEGDither(JPEGIMAGE *pJPEG, int iWidth, int iHeight); /* JPEG tables */ // zigzag ordering of DCT coefficients @@ -474,7 +476,7 @@ static const uint16_t usRangeTableB[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x00 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -#if defined (__MACH__) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) || defined( PICO_BUILD ) +#if defined (__MACH__) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) // // API for C // @@ -499,7 +501,6 @@ int JPEG_openRAM(JPEGIMAGE *pJPEG, uint8_t *pData, int iDataSize, JPEG_DRAW_CALL // // File initialization // -/* int JPEG_openFile(JPEGIMAGE *pJPEG, const char *szFilename, JPEG_DRAW_CALLBACK *pfnDraw) { memset(pJPEG, 0, sizeof(JPEGIMAGE)); @@ -517,7 +518,7 @@ int JPEG_openFile(JPEGIMAGE *pJPEG, const char *szFilename, JPEG_DRAW_CALLBACK * pJPEG->JPEGFile.iSize = (int)ftell((FILE *)pJPEG->JPEGFile.fHandle); fseek((FILE *)pJPEG->JPEGFile.fHandle, 0, SEEK_SET); return JPEGInit(pJPEG); -} *//* JPEG_openFile() */ +} /* JPEG_openFile() */ int JPEG_getLastError(JPEGIMAGE *pJPEG) { @@ -631,7 +632,7 @@ static int32_t seekMem(JPEGFILE *pFile, int32_t iPosition) return iPosition; } /* seekMem() */ -#if defined (__MACH__) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) || defined( PICO_BUILD ) +#if defined (__MACH__) || defined( __LINUX__ ) || defined( __MCUXPRESSO ) static void closeFile(void *handle) { @@ -2350,15 +2351,15 @@ static void JPEGPixel2LE(uint16_t *pDest, int iY1, int iY2, int iCb, int iCr) #endif } /* JPEGPixel2LE() */ -static void JPEGPixel2BE(uint16_t *pDest, int iY1, int iY2, int iCb, int iCr) +static void JPEGPixel2BE(uint16_t *pDest, int32_t iY1, int32_t iY2, int32_t iCb, int32_t iCr) { - int iCBB, iCBG, iCRG, iCRR; + int32_t iCBB, iCBG, iCRG, iCRR; uint32_t ulPixel1, ulPixel2; - iCBB = 7258 * (iCb-0x80); - iCBG = -1409 * (iCb-0x80); - iCRG = -2925 * (iCr-0x80); - iCRR = 5742 * (iCr-0x80); + iCBB = 7258L * (iCb-0x80); + iCBG = -1409L * (iCb-0x80); + iCRG = -2925L * (iCr-0x80); + iCRR = 5742L * (iCr-0x80); ulPixel1 = usRangeTableB[((iCBB + iY1) >> 12) & 0x3ff]; // blue pixel ulPixel1 |= usRangeTableG[((iCBG + iCRG + iY1) >> 12) & 0x3ff]; // green pixel ulPixel1 |= usRangeTableR[((iCRR + iY1) >> 12) & 0x3ff]; // red pixel @@ -2366,7 +2367,7 @@ static void JPEGPixel2BE(uint16_t *pDest, int iY1, int iY2, int iCb, int iCr) ulPixel2 = usRangeTableB[((iCBB + iY2) >> 12) & 0x3ff]; // blue pixel ulPixel2 |= usRangeTableG[((iCBG + iCRG + iY2) >> 12) & 0x3ff]; // green pixel ulPixel2 |= usRangeTableR[((iCRR + iY2) >> 12) & 0x3ff]; // red pixel - *(uint32_t *)&pDest[0] = __builtin_bswap16(ulPixel1) | (__builtin_bswap16(ulPixel2)<<16); + *(uint32_t *)&pDest[0] = __builtin_bswap16(ulPixel1) | ((uint32_t)__builtin_bswap16(ulPixel2)<<16); } /* JPEGPixel2BE() */ static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch) @@ -3454,6 +3455,7 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG) { xoff = 0; jd.iWidth = iPitch; // width of each LCD block group + jd.pUser = pJPEG->pUser; if (pJPEG->ucPixelType > EIGHT_BIT_GRAYSCALE) // dither to 4/2/1 bits JPEGDither(pJPEG, cx * mcuCX, mcuCY); if ((jd.y - pJPEG->iYOffset + mcuCY) > (pJPEG->iHeight>>iScaleShift)) { // last row needs to be trimmed diff --git a/micropython/modules/jpegdec/jpegdec.cpp b/micropython/modules/jpegdec/jpegdec.cpp index 69a16e26..57e9c59d 100644 --- a/micropython/modules/jpegdec/jpegdec.cpp +++ b/micropython/modules/jpegdec/jpegdec.cpp @@ -29,7 +29,6 @@ typedef struct _JPEG_obj_t { } _JPEG_obj_t; -PicoGraphics *current_graphics = nullptr; uint8_t current_flags = 0; enum FLAGS : uint8_t { @@ -88,6 +87,7 @@ int JPEGDraw(JPEGDRAW *pDraw) { #ifdef MICROPY_EVENT_POLL_HOOK MICROPY_EVENT_POLL_HOOK #endif + PicoGraphics *current_graphics = (PicoGraphics *)pDraw->pUser; // "pixel" is slow and clipped, // guaranteeing we wont draw jpeg data out of the framebuffer.. // Can we clip beforehand and make this faster? @@ -267,12 +267,10 @@ 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 - // since the JPEGDRAW struct has no userdata - current_graphics = self->graphics->graphics; + self->jpeg->setUserPointer((void *)self->graphics->graphics); result = self->jpeg->decode(x, y, f); - current_graphics = nullptr; current_flags = 0; // Close the file since we've opened it on-demand