release
This commit is contained in:
197
lib/TJpg_Decoder/src/TJpg_Decoder.cpp
Normal file
197
lib/TJpg_Decoder/src/TJpg_Decoder.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
TJpg_Decoder.cpp
|
||||
|
||||
Created by Bodmer 18/10/19
|
||||
Modified by Blueforcer 02/23
|
||||
|
||||
Latest version here:
|
||||
https://github.com/Bodmer/TJpg_Decoder
|
||||
*/
|
||||
|
||||
#include "TJpg_Decoder.h"
|
||||
|
||||
// Create a class instance to be used by the sketch (defined as extern in header)
|
||||
TJpg_Decoder TJpgDec;
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: TJpg_Decoder
|
||||
** Description: Constructor
|
||||
***************************************************************************************/
|
||||
TJpg_Decoder::TJpg_Decoder()
|
||||
{
|
||||
// Setup a pointer to this class for static functions
|
||||
thisPtr = this;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: ~TJpg_Decoder
|
||||
** Description: Destructor
|
||||
***************************************************************************************/
|
||||
TJpg_Decoder::~TJpg_Decoder()
|
||||
{
|
||||
// Bye
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setJpgScale
|
||||
** Description: Set the reduction scale factor (1, 2, 4 or 8)
|
||||
***************************************************************************************/
|
||||
void TJpg_Decoder::setSwapBytes(bool swapBytes)
|
||||
{
|
||||
_swap = swapBytes;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setJpgScale
|
||||
** Description: Set the reduction scale factor (1, 2, 4 or 8)
|
||||
***************************************************************************************/
|
||||
void TJpg_Decoder::setJpgScale(uint8_t scaleFactor)
|
||||
{
|
||||
switch (scaleFactor)
|
||||
{
|
||||
case 1:
|
||||
jpgScale = 0;
|
||||
break;
|
||||
case 2:
|
||||
jpgScale = 1;
|
||||
break;
|
||||
case 4:
|
||||
jpgScale = 2;
|
||||
break;
|
||||
case 8:
|
||||
jpgScale = 3;
|
||||
break;
|
||||
default:
|
||||
jpgScale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setCallback
|
||||
** Description: Set the sketch callback function to render decoded blocks
|
||||
***************************************************************************************/
|
||||
void TJpg_Decoder::setCallback(SketchCallback sketchCallback)
|
||||
{
|
||||
tft_output = sketchCallback;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: jd_input (declared static)
|
||||
** Description: Called by tjpgd.c to get more data
|
||||
***************************************************************************************/
|
||||
unsigned int TJpg_Decoder::jd_input(JDEC *jdec, uint8_t *buf, unsigned int len)
|
||||
{
|
||||
TJpg_Decoder *thisPtr = TJpgDec.thisPtr;
|
||||
jdec = jdec; // Supress warning
|
||||
|
||||
// Handle an array input
|
||||
if (thisPtr->jpg_source == TJPG_ARRAY)
|
||||
{
|
||||
// Avoid running off end of array
|
||||
if (thisPtr->array_index + len > thisPtr->array_size)
|
||||
{
|
||||
len = thisPtr->array_size - thisPtr->array_index;
|
||||
}
|
||||
|
||||
// If buf is valid then copy len bytes to buffer
|
||||
if (buf)
|
||||
memcpy_P(buf, (const uint8_t *)(thisPtr->array_data + thisPtr->array_index), len);
|
||||
|
||||
// Move pointer
|
||||
thisPtr->array_index += len;
|
||||
}
|
||||
|
||||
#ifdef TJPGD_LOAD_FFS
|
||||
// Handle SPIFFS input
|
||||
else if (thisPtr->jpg_source == TJPG_FS_FILE)
|
||||
{
|
||||
// Check how many bytes are available
|
||||
uint32_t bytesLeft = thisPtr->jpgFile.available();
|
||||
if (bytesLeft < len)
|
||||
len = bytesLeft;
|
||||
|
||||
if (buf)
|
||||
{
|
||||
// Read into buffer, pointer moved as well
|
||||
thisPtr->jpgFile.read(buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Buffer is null, so skip data by moving pointer
|
||||
thisPtr->jpgFile.seek(thisPtr->jpgFile.position() + len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TJPGD_LOAD_SD_LIBRARY)
|
||||
// Handle SD library input
|
||||
else if (thisPtr->jpg_source == TJPG_SD_FILE)
|
||||
{
|
||||
// Check how many bytes are available
|
||||
uint32_t bytesLeft = thisPtr->jpgSdFile.available();
|
||||
if (bytesLeft < len)
|
||||
len = bytesLeft;
|
||||
|
||||
if (buf)
|
||||
{
|
||||
// Read into buffer, pointer moved as well
|
||||
thisPtr->jpgSdFile.read(buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Buffer is null, so skip data by moving pointer
|
||||
thisPtr->jpgSdFile.seek(thisPtr->jpgSdFile.position() + len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: jd_output (declared static)
|
||||
** Description: Called by tjpgd.c with an image block for rendering
|
||||
***************************************************************************************/
|
||||
// Pass image block back to the sketch for rendering, may be a complete or partial MCU
|
||||
int TJpg_Decoder::jd_output(JDEC *jdec, void *bitmap, JRECT *jrect)
|
||||
{
|
||||
|
||||
TJpg_Decoder *thisPtr = TJpgDec.thisPtr;
|
||||
jdec = jdec; // Supress warning as ID is not used
|
||||
|
||||
int16_t x = jrect->left + thisPtr->jpeg_x;
|
||||
int16_t y = jrect->top + thisPtr->jpeg_y;
|
||||
uint16_t w = jrect->right + 1 - jrect->left;
|
||||
uint16_t h = jrect->bottom + 1 - jrect->top;
|
||||
// Pass the image block and rendering parameters in a callback to the sketch
|
||||
return thisPtr->tft_output(x, y, w, h, (uint16_t *)bitmap);
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: drawFsJpg für AWTRIX
|
||||
** Description: Draw a jpg with opened file handle at x,y
|
||||
***************************************************************************************/
|
||||
JRESULT TJpg_Decoder::drawFsJpg(int32_t x, int32_t y, fs::File inFile)
|
||||
{
|
||||
|
||||
JDEC jdec;
|
||||
JRESULT jresult = JDR_OK;
|
||||
|
||||
jpg_source = TJPG_FS_FILE;
|
||||
jpeg_x = x;
|
||||
jpeg_y = y;
|
||||
|
||||
jdec.swap = _swap;
|
||||
|
||||
jpgFile = inFile;
|
||||
|
||||
jresult = jd_prepare(&jdec, jd_input, workspace, TJPGD_WORKSPACE_SIZE, (unsigned int)0);
|
||||
|
||||
// Extract image and render
|
||||
if (jresult == JDR_OK)
|
||||
{
|
||||
jresult = jd_decomp(&jdec, jd_output, jpgScale);
|
||||
}
|
||||
inFile.seek(0);
|
||||
return jresult;
|
||||
}
|
||||
128
lib/TJpg_Decoder/src/TJpg_Decoder.h
Normal file
128
lib/TJpg_Decoder/src/TJpg_Decoder.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
TJpg_Decoder.h
|
||||
|
||||
JPEG Decoder for Arduino using TJpgDec:
|
||||
http://elm-chan.org/fsw/tjpgd/00index.html
|
||||
|
||||
Incorporated into an Arduino library by Bodmer 18/10/19
|
||||
|
||||
Latest version here:
|
||||
https://github.com/Bodmer/TJpg_Decoder
|
||||
*/
|
||||
|
||||
#ifndef TJpg_Decoder_H
|
||||
#define TJpg_Decoder_H
|
||||
|
||||
#include "User_Config.h"
|
||||
#include "Arduino.h"
|
||||
#include "tjpgd.h"
|
||||
|
||||
#if defined (ESP8266) || defined (ESP32)
|
||||
#include <pgmspace.h>
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#ifdef ESP32
|
||||
#include "SPIFFS.h" // ESP32 only
|
||||
#endif
|
||||
#define TJPGD_LOAD_FFS
|
||||
#elif defined (ARDUINO_ARCH_RP2040)
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#define SPIFFS LittleFS
|
||||
#define TJPGD_LOAD_FFS
|
||||
#endif
|
||||
|
||||
#if defined (TJPGD_LOAD_SD_LIBRARY)
|
||||
#include <SD.h>
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TJPG_ARRAY = 0,
|
||||
TJPG_FS_FILE,
|
||||
TJPG_SD_FILE
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef bool (*SketchCallback)(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *data);
|
||||
|
||||
class TJpg_Decoder {
|
||||
|
||||
private:
|
||||
#if defined (TJPGD_LOAD_SD_LIBRARY)
|
||||
File jpgSdFile;
|
||||
#endif
|
||||
|
||||
#ifdef TJPGD_LOAD_FFS
|
||||
fs::File jpgFile;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
TJpg_Decoder();
|
||||
~TJpg_Decoder();
|
||||
|
||||
static int jd_output(JDEC* jdec, void* bitmap, JRECT* jrect);
|
||||
static unsigned int jd_input(JDEC* jdec, uint8_t* buf, unsigned int len);
|
||||
|
||||
void setJpgScale(uint8_t scale);
|
||||
void setCallback(SketchCallback sketchCallback);
|
||||
|
||||
|
||||
#if defined (TJPGD_LOAD_SD_LIBRARY) || defined (TJPGD_LOAD_FFS)
|
||||
JRESULT drawJpg (int32_t x, int32_t y, const char *pFilename);
|
||||
JRESULT drawJpg (int32_t x, int32_t y, const String& pFilename);
|
||||
|
||||
JRESULT getJpgSize(uint16_t *w, uint16_t *h, const char *pFilename);
|
||||
JRESULT getJpgSize(uint16_t *w, uint16_t *h, const String& pFilename);
|
||||
#endif
|
||||
|
||||
#if defined (TJPGD_LOAD_SD_LIBRARY)
|
||||
JRESULT drawSdJpg (int32_t x, int32_t y, const char *pFilename);
|
||||
JRESULT drawSdJpg (int32_t x, int32_t y, const String& pFilename);
|
||||
JRESULT drawSdJpg (int32_t x, int32_t y, File inFile);
|
||||
|
||||
JRESULT getSdJpgSize(uint16_t *w, uint16_t *h, const char *pFilename);
|
||||
JRESULT getSdJpgSize(uint16_t *w, uint16_t *h, const String& pFilename);
|
||||
JRESULT getSdJpgSize(uint16_t *w, uint16_t *h, File inFile);
|
||||
#endif
|
||||
|
||||
#ifdef TJPGD_LOAD_FFS
|
||||
JRESULT drawFsJpg (int32_t x, int32_t y, const char *pFilename, fs::FS &fs = SPIFFS);
|
||||
JRESULT drawFsJpg (int32_t x, int32_t y, const String& pFilename, fs::FS &fs = SPIFFS);
|
||||
JRESULT drawFsJpg (int32_t x, int32_t y, fs::File inFile);
|
||||
|
||||
JRESULT getFsJpgSize(uint16_t *w, uint16_t *h, const char *pFilename, fs::FS &fs = SPIFFS);
|
||||
JRESULT getFsJpgSize(uint16_t *w, uint16_t *h, const String& pFilename, fs::FS &fs = SPIFFS);
|
||||
JRESULT getFsJpgSize(uint16_t *w, uint16_t *h, fs::File inFile);
|
||||
#endif
|
||||
|
||||
JRESULT drawJpg(int32_t x, int32_t y, const uint8_t array[], uint32_t array_size);
|
||||
JRESULT getJpgSize(uint16_t *w, uint16_t *h, const uint8_t array[], uint32_t array_size);
|
||||
|
||||
void setSwapBytes(bool swap);
|
||||
|
||||
bool _swap = false;
|
||||
|
||||
const uint8_t* array_data = nullptr;
|
||||
uint32_t array_index = 0;
|
||||
uint32_t array_size = 0;
|
||||
|
||||
// Must align workspace to a 32 bit boundary
|
||||
uint8_t workspace[TJPGD_WORKSPACE_SIZE] __attribute__((aligned(4)));
|
||||
|
||||
uint8_t jpg_source = 0;
|
||||
|
||||
int16_t jpeg_x = 0;
|
||||
int16_t jpeg_y = 0;
|
||||
|
||||
uint8_t jpgScale = 0;
|
||||
|
||||
SketchCallback tft_output = nullptr;
|
||||
|
||||
TJpg_Decoder *thisPtr = nullptr;
|
||||
};
|
||||
|
||||
extern TJpg_Decoder TJpgDec;
|
||||
|
||||
#endif // TJpg_Decoder_H
|
||||
5
lib/TJpg_Decoder/src/User_Config.h
Normal file
5
lib/TJpg_Decoder/src/User_Config.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#if defined (ESP32) || defined (ESP8266) || (ARDUINO_ARCH_RP2040) || defined (ARDUINO_ARCH_MBED)
|
||||
#define TJPGD_LOAD_FFS
|
||||
#endif
|
||||
|
||||
#define TJPGD_LOAD_SD_LIBRARY
|
||||
1166
lib/TJpg_Decoder/src/tjpgd.c
Normal file
1166
lib/TJpg_Decoder/src/tjpgd.c
Normal file
File diff suppressed because it is too large
Load Diff
103
lib/TJpg_Decoder/src/tjpgd.h
Normal file
103
lib/TJpg_Decoder/src/tjpgd.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ TJpgDec - Tiny JPEG Decompressor R0.03 include file (C)ChaN, 2021
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef DEF_TJPGDEC
|
||||
#define DEF_TJPGDEC
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tjpgdcnf.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) /* VC++ or some compiler without stdint.h */
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef long int32_t;
|
||||
#else /* Embedded platform */
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if JD_FASTDECODE >= 1
|
||||
typedef int16_t jd_yuv_t;
|
||||
#else
|
||||
typedef uint8_t jd_yuv_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* Error code */
|
||||
typedef enum {
|
||||
JDR_OK = 0, /* 0: Succeeded */
|
||||
JDR_INTR, /* 1: Interrupted by output function */
|
||||
JDR_INP, /* 2: Device error or wrong termination of input stream */
|
||||
JDR_MEM1, /* 3: Insufficient memory pool for the image */
|
||||
JDR_MEM2, /* 4: Insufficient stream input buffer */
|
||||
JDR_PAR, /* 5: Parameter error */
|
||||
JDR_FMT1, /* 6: Data format error (may be broken data) */
|
||||
JDR_FMT2, /* 7: Right format but not supported */
|
||||
JDR_FMT3 /* 8: Not supported JPEG standard */
|
||||
} JRESULT;
|
||||
|
||||
|
||||
|
||||
/* Rectangular region in the output image */
|
||||
typedef struct {
|
||||
uint16_t left; /* Left end */
|
||||
uint16_t right; /* Right end */
|
||||
uint16_t top; /* Top end */
|
||||
uint16_t bottom; /* Bottom end */
|
||||
} JRECT;
|
||||
|
||||
|
||||
|
||||
/* Decompressor object structure */
|
||||
typedef struct JDEC JDEC;
|
||||
struct JDEC {
|
||||
size_t dctr; /* Number of bytes available in the input buffer */
|
||||
uint8_t* dptr; /* Current data read ptr */
|
||||
uint8_t* inbuf; /* Bit stream input buffer */
|
||||
uint8_t dbit; /* Number of bits availavble in wreg or reading bit mask */
|
||||
uint8_t scale; /* Output scaling ratio */
|
||||
uint8_t msx, msy; /* MCU size in unit of block (width, height) */
|
||||
uint8_t qtid[3]; /* Quantization table ID of each component, Y, Cb, Cr */
|
||||
uint8_t ncomp; /* Number of color components 1:grayscale, 3:color */
|
||||
int16_t dcv[3]; /* Previous DC element of each component */
|
||||
uint16_t nrst; /* Restart inverval */
|
||||
uint16_t width, height; /* Size of the input image (pixel) */
|
||||
uint8_t* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */
|
||||
uint16_t* huffcode[2][2]; /* Huffman code word tables [id][dcac] */
|
||||
uint8_t* huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */
|
||||
int32_t* qttbl[4]; /* Dequantizer tables [id] */
|
||||
#if JD_FASTDECODE >= 1
|
||||
uint32_t wreg; /* Working shift register */
|
||||
uint8_t marker; /* Detected marker (0:None) */
|
||||
#if JD_FASTDECODE == 2
|
||||
uint8_t longofs[2][2]; /* Table offset of long code [id][dcac] */
|
||||
uint16_t* hufflut_ac[2]; /* Fast huffman decode tables for AC short code [id] */
|
||||
uint8_t* hufflut_dc[2]; /* Fast huffman decode tables for DC short code [id] */
|
||||
#endif
|
||||
#endif
|
||||
void* workbuf; /* Working buffer for IDCT and RGB output */
|
||||
jd_yuv_t* mcubuf; /* Working buffer for the MCU */
|
||||
void* pool; /* Pointer to available memory pool */
|
||||
size_t sz_pool; /* Size of momory pool (bytes available) */
|
||||
size_t (*infunc)(JDEC*, uint8_t*, size_t); /* Pointer to jpeg stream input function */
|
||||
void* device; /* Pointer to I/O device identifiler for the session */
|
||||
uint8_t swap; /* Added by Bodmer to control byte swapping */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* TJpgDec API functions */
|
||||
JRESULT jd_prepare (JDEC* jd, size_t (*infunc)(JDEC*,uint8_t*,size_t), void* pool, size_t sz_pool, void* dev);
|
||||
JRESULT jd_decomp (JDEC* jd, int (*outfunc)(JDEC*,void*,JRECT*), uint8_t scale);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TJPGDEC */
|
||||
44
lib/TJpg_Decoder/src/tjpgdcnf.h
Normal file
44
lib/TJpg_Decoder/src/tjpgdcnf.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*----------------------------------------------*/
|
||||
/* TJpgDec System Configurations R0.03 */
|
||||
/*----------------------------------------------*/
|
||||
|
||||
#define JD_SZBUF 512
|
||||
/* Specifies size of stream input buffer */
|
||||
|
||||
#define JD_FORMAT 1
|
||||
/* Specifies output pixel format.
|
||||
/ 0: RGB888 (24-bit/pix)
|
||||
/ 1: RGB565 (16-bit/pix)
|
||||
/ 2: Grayscale (8-bit/pix)
|
||||
*/
|
||||
|
||||
#define JD_USE_SCALE 1
|
||||
/* Switches output descaling feature.
|
||||
/ 0: Disable
|
||||
/ 1: Enable
|
||||
*/
|
||||
|
||||
#define JD_TBLCLIP 0
|
||||
/* Use table conversion for saturation arithmetic. A bit faster, but increases 1 KB of code size.
|
||||
/ 0: Disable
|
||||
/ 1: Enable
|
||||
*/
|
||||
|
||||
#define JD_FASTDECODE 1
|
||||
/* Optimization level
|
||||
/ 0: Basic optimization. Suitable for 8/16-bit MCUs.
|
||||
/ Workspace of 3100 bytes needed.
|
||||
/ 1: + 32-bit barrel shifter. Suitable for 32-bit MCUs.
|
||||
/ Workspace of 3480 bytes needed.
|
||||
/ 2: + Table conversion for huffman decoding (wants 6 << HUFF_BIT bytes of RAM).
|
||||
/ Workspace of 9644 bytes needed.
|
||||
*/
|
||||
|
||||
// Do not change this, it is the minimum size in bytes of the workspace needed by the decoder
|
||||
#if JD_FASTDECODE == 0
|
||||
#define TJPGD_WORKSPACE_SIZE 3100
|
||||
#elif JD_FASTDECODE == 1
|
||||
#define TJPGD_WORKSPACE_SIZE 3500
|
||||
#elif JD_FASTDECODE == 2
|
||||
#define TJPGD_WORKSPACE_SIZE (3500 + 6144)
|
||||
#endif
|
||||
Reference in New Issue
Block a user