Merge pull request #30 from Thorinair/master

Added JPEG support for SD and Web
This commit is contained in:
David Zovko 2020-09-01 12:51:41 +02:00 committed by GitHub
commit 420075a1e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 2638 additions and 3 deletions

View File

@ -4,6 +4,12 @@
#include "WiFi.h" #include "WiFi.h"
#include "HTTPClient.h" #include "HTTPClient.h"
#include "Inkplate.h" #include "Inkplate.h"
#include "TJpg_Decoder.h"
#define RED(a) ((((a) & 0xf800) >> 11) << 3)
#define GREEN(a) ((((a) & 0x07e0) >> 5) << 2)
#define BLUE(a) (((a) & 0x001f) << 3)
SPIClass spi2(HSPI); SPIClass spi2(HSPI);
SdFat sd(&spi2); SdFat sd(&spi2);
@ -26,6 +32,30 @@ void ckvClock()
usleep1(); usleep1();
} }
bool jpegCallback(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* data, void* _display, bool _dither, bool _invert) {
Inkplate *display = static_cast<Inkplate *>(_display);
if (_dither) {
//TODO: Implement dithering!
Serial.println(_dither);
}
int i, j;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
uint16_t rgb = data[j*w + i];
if (_invert)
rgb = ~rgb;
uint8_t px = (RED(rgb) * 2126 / 10000) + (GREEN(rgb) * 7152 / 10000) + (BLUE(rgb) * 722 / 10000);
display->drawPixel(i + x, j + y, px >> 5);
}
}
return 1;
}
//--------------------------USER FUNCTIONS-------------------------------------------- //--------------------------USER FUNCTIONS--------------------------------------------
Inkplate::Inkplate(uint8_t _mode) : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT) Inkplate::Inkplate(uint8_t _mode) : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT)
{ {
@ -513,6 +543,115 @@ int Inkplate::drawBitmapFromWeb(char *url, int x, int y, bool dither, bool inver
return ret; return ret;
} }
int Inkplate::drawJpegFromSD(Inkplate *display, SdFile *p, int x, int y, bool dither, bool invert)
{
uint8_t ret = 0;
TJpgDec.setJpgScale(1);
TJpgDec.setCallback(jpegCallback);
uint32_t pnt = 0;
uint32_t total = p->fileSize();
uint8_t *buf = (uint8_t *)ps_malloc(total);
if (buf == NULL)
return 0;
while (pnt < total) {
uint32_t toread = p->available();
if (toread > 0) {
int read = p->read(buf + pnt, toread);
if (read > 0)
pnt += read;
}
}
p->close();
selectDisplayMode(INKPLATE_3BIT);
if(TJpgDec.drawJpg(x, y, buf, total, display, dither, invert) == 0)
ret = 1;
free(buf);
return ret;
}
int Inkplate::drawJpegFromSD(Inkplate *display, char *fileName, int x, int y, bool dither, bool invert)
{
if (sdCardOk == 0)
return 0;
SdFile dat;
if (dat.open(fileName, O_RDONLY))
{
return drawJpegFromSD(display, &dat, x, y, dither, invert);
}
else
{
return 0;
}
}
int Inkplate::drawJpegFromWeb(Inkplate *display, WiFiClient *s, int x, int y, int len, bool dither, bool invert)
{
uint8_t ret = 0;
TJpgDec.setJpgScale(1);
TJpgDec.setCallback(jpegCallback);
uint32_t pnt = 0;
uint8_t *buf = (uint8_t *)ps_malloc(len);
if (buf == NULL)
return 0;
while (pnt < len) {
uint32_t toread = s->available();
if (toread > 0) {
int read = s->read(buf + pnt, toread);
if (read > 0)
pnt += read;
}
}
selectDisplayMode(INKPLATE_3BIT);
if(TJpgDec.drawJpg(x, y, buf, len, display, dither, invert) == 0)
ret = 1;
free(buf);
return ret;
}
int Inkplate::drawJpegFromWeb(Inkplate *display, char *url, int x, int y, bool dither, bool invert)
{
if (WiFi.status() != WL_CONNECTED)
return 0;
int ret = 0;
bool sleep = WiFi.getSleep();
WiFi.setSleep(false);
HTTPClient http;
http.getStream().setNoDelay(true);
http.getStream().setTimeout(1);
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200)
{
int32_t len = http.getSize();
if (len > 0)
{
WiFiClient *dat = http.getStreamPtr();
ret = drawJpegFromWeb(display, dat, x, y, len, dither, invert);
}
}
http.end();
WiFi.setSleep(sleep);
return ret;
}
void Inkplate::drawElipse(int rx, int ry, void Inkplate::drawElipse(int rx, int ry,
int xc, int yc, int xc, int yc,
int c) int c)

View File

@ -237,6 +237,10 @@ public:
int drawBitmapFromSD(char *fileName, int x, int y, bool dither = false, bool invert = false); int drawBitmapFromSD(char *fileName, int x, int y, bool dither = false, bool invert = false);
int drawBitmapFromWeb(WiFiClient *s, int x, int y, int len, bool dither = false, bool invert = false); int drawBitmapFromWeb(WiFiClient *s, int x, int y, int len, bool dither = false, bool invert = false);
int drawBitmapFromWeb(char *url, int x, int y, bool dither = false, bool invert = false); int drawBitmapFromWeb(char *url, int x, int y, bool dither = false, bool invert = false);
int drawJpegFromSD(Inkplate *display, SdFile *p, int x, int y, bool dither = false, bool invert = false);
int drawJpegFromSD(Inkplate *display, char *fileName, int x, int y, bool dither = false, bool invert = false);
int drawJpegFromWeb(Inkplate *display, WiFiClient *s, int x, int y, int len, bool dither = false, bool invert = false);
int drawJpegFromWeb(Inkplate *display, char *url, int x, int y, bool dither = false, bool invert = false);
void drawElipse(int rx, int ry, int xc, int yc, int c); void drawElipse(int rx, int ry, int xc, int yc, int c);
void fillElipse(int rx, int ry, int xc, int yc, int c); void fillElipse(int rx, int ry, int xc, int yc, int c);
void drawPolygon(int *x, int *y, int n, int color); void drawPolygon(int *x, int *y, int n, int color);

176
TJpg_Decoder.cpp Normal file
View File

@ -0,0 +1,176 @@
/*
TJpg_Decoder.cpp
Created by Bodmer 18/10/19
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
***************************************************************************************/
uint16_t TJpg_Decoder::jd_input(JDEC* jdec, uint8_t* buf, uint16_t 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;
}
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
uint16_t TJpg_Decoder::jd_output(JDEC* jdec, void* bitmap, JRECT* jrect)
{
// This is a static function so create a pointer to access other members of the class
TJpg_Decoder *thisPtr = TJpgDec.thisPtr;
jdec = jdec; // Supress warning as ID is not used
// Retrieve rendering parameters and add any offset
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, (void*)jdec->_display, jdec->_dither, jdec->_invert);
}
/***************************************************************************************
** Function name: drawJpg
** Description: Draw a jpg saved in a FLASH memory array
***************************************************************************************/
JRESULT TJpg_Decoder::drawJpg(int32_t x, int32_t y, const uint8_t jpeg_data[], uint32_t data_size, void* display, bool dither, bool invert) {
JDEC jdec;
JRESULT jresult = JDR_OK;
jpg_source = TJPG_ARRAY;
array_index = 0;
array_data = jpeg_data;
array_size = data_size;
jpeg_x = x;
jpeg_y = y;
jdec.swap = _swap;
// Analyse input data
jresult = jd_prepare(&jdec, jd_input, workspace, TJPGD_WORKSPACE_SIZE, 0);
// Extract image and render
if (jresult == JDR_OK) {
jresult = jd_decomp(&jdec, jd_output, jpgScale, display, dither, invert);
}
return jresult;
}
/***************************************************************************************
** Function name: getJpgSize
** Description: Get width and height of a jpg saved in a FLASH memory array
***************************************************************************************/
JRESULT TJpg_Decoder::getJpgSize(uint16_t *w, uint16_t *h, const uint8_t jpeg_data[], uint32_t data_size) {
JDEC jdec;
JRESULT jresult = JDR_OK;
*w = 0;
*h = 0;
jpg_source = TJPG_ARRAY;
array_index = 0;
array_data = jpeg_data;
array_size = data_size;
// Analyse input data
jresult = jd_prepare(&jdec, jd_input, workspace, TJPGD_WORKSPACE_SIZE, 0);
if (jresult == JDR_OK) {
*w = jdec.width;
*h = jdec.height;
}
return jresult;
}

78
TJpg_Decoder.h Normal file
View File

@ -0,0 +1,78 @@
/*
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 "Arduino.h"
#include "tjpgd.h"
#if defined (ESP8266) || defined (ESP32)
#include <pgmspace.h>
#endif
#define TJPGD_WORKSPACE_SIZE 3100
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, void* display, bool dither, bool invert);
class TJpg_Decoder {
private:
public:
TJpg_Decoder();
~TJpg_Decoder();
static uint16_t jd_output(JDEC* jdec, void* bitmap, JRECT* jrect);
static uint16_t jd_input(JDEC* jdec, uint8_t* buf, uint16_t len);
void setJpgScale(uint8_t scale);
void setCallback(SketchCallback sketchCallback);
JRESULT drawJpg(int32_t x, int32_t y, const uint8_t array[], uint32_t array_size, void* display, bool dither, bool invert);
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

54
TJpg_License.txt Normal file
View File

@ -0,0 +1,54 @@
This library incorporate the Tiny JPEG Decompressor code files:
"tjpgd.h" and "tjpgd.c". The licence for these files is:
/*----------------------------------------------------------------------------/
/ TJpgDec - Tiny JPEG Decompressor R0.01c (C)ChaN, 2019
/-----------------------------------------------------------------------------/
/ The TJpgDec is a generic JPEG decompressor module for tiny embedded systems.
/ This is a free software that opened for education, research and commercial
/ developments under license policy of following terms.
/
/ Copyright (C) 2019, ChaN, all right reserved.
/
/ * The TJpgDec module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/
/-----------------------------------------------------------------------------/
This Arduino library "TJpd_Decoder" has been created by Bodmer, for all the
additional code the FreeBSD licence applies and is compatible with the GNU GPL:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvStartvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Software License Agreement (FreeBSD License)
Copyright (c) 2019 Bodmer (https://github.com/Bodmer)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^End^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,5 +1,5 @@
/* /*
10_Inkplate_Download_And_Show example for e-radionica Inkplate6 10_Web_BMP_pictures example for e-radionica Inkplate6
For this example you will need a micro USB cable, Inkplate6, and an available WiFi connection. For this example you will need a micro USB cable, Inkplate6, and an available WiFi connection.
Select "Inkplate 6(ESP32)" from Tools -> Board menu. Select "Inkplate 6(ESP32)" from Tools -> Board menu.
Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it: Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it:
@ -22,7 +22,7 @@
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome) Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
const char* ssid = ""; //Your WiFi SSID const char* ssid = ""; //Your WiFi SSID
const char* password = ""; //Your WiFi password const char* password = ""; //Your WiFi password
void setup() { void setup() {
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE) display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
@ -52,7 +52,7 @@ void setup() {
//Photo taken by: Roberto Fernandez //Photo taken by: Roberto Fernandez
if (!display.drawBitmapFromWeb("https://varipass.org/neowise_mono.bmp", 0, 0, false, true)) { if (!display.drawBitmapFromWeb("https://varipass.org/neowise_mono.bmp", 0, 0, false, true)) {
//If is something failed (wrong filename or wrong bitmap format), write error message on the screen. //If is something failed (wrong filename or wrong bitmap format), write error message on the screen.
//REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression! //REMEMBER! You can only use Windows Bitmap file with color depth of 1, 4, 8 or 24 bits with no compression!
display.println("Image open error"); display.println("Image open error");
display.display(); display.display();
} }

View File

@ -0,0 +1,61 @@
/*
5_Inkplate_SD_JPEG_pictures example for e-radionica Inkplate6
For this example you will need a micro USB cable, Inkplate6 and a SD card loaded with
pyramid.jpg file that can be found inside folder of this example.
Select "Inkplate 6(ESP32)" from Tools -> Board menu.
Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it:
https://e-radionica.com/en/blog/add-inkplate-6-to-arduino-ide/
To work with SD card on Inkplate, you will need to add one extra library.
Download and install it from here: https://github.com/e-radionicacom/Inkplate-6-SDFat-Arduino-Library
You can open .jpg files that have resoluton smaller than 800x600 or otherwise it won't fit on screen.
Format your SD card in standard FAT fileformat.
This example will show you how you can read a .jpg file (picture) from SD card and
display that image on e-paper display.
Want to learn more about Inkplate? Visit www.inkplate.io
Looking to get support? Write on our forums: http://forum.e-radionica.com/en/
31 August 2020 by e-radionica.com
*/
#include "Inkplate.h" //Include Inkplate library to the sketch
#include "SdFat.h" //Include library for SD card
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
SdFile file; //Create SdFile object used for accessing files on SD card
void setup() {
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display
//Init SD card. Display if SD card is init propery or not.
if (display.sdCardInit()) {
display.println("SD Card OK! Reading image...");
display.partialUpdate();
//If card is properly init, try to load image and display it on e-paper at position X=100, Y=0
//NOTE: These methods require you to pass a reference to the display object as first parameter.
//NOTE: Both drawJpegFromSD methods allow for an optional sixth "invert" parameter. Setting this parameter to true
//will flip all colors on the image, making black white and white black.
//fifth parameter will dither the image.
if (!display.drawJpegFromSD(&display, "pyramid.jpg", 100, 0, true, false)) {
//If is something failed (wrong filename or wrong format), write error message on the screen.
//You can turn off dithering for somewhat faster image load by changing the fifth parameter to false, or removing the parameter completely
display.println("Image open error");
display.display();
}
display.display();
}
else {
//If SD card init not success, display error on screen and stop the program (using infinite loop)
display.println("SD Card error!");
display.partialUpdate();
while (true);
}
}
void loop() {
//Nothing...
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -0,0 +1,63 @@
/*
12-Inkplate_Web_JPEG_pictures for e-radionica Inkplate6
For this example you will need a micro USB cable, Inkplate6, and an available WiFi connection.
Select "Inkplate 6(ESP32)" from Tools -> Board menu.
Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it:
https://e-radionica.com/en/blog/add-inkplate-6-to-arduino-ide/
You can open .jpg files that have resoluton smaller than 800x600 or otherwise it won't fit on screen.
This example will show you how you can download a .jpg file (picture) from the web and
display that image on e-paper display.
Want to learn more about Inkplate? Visit www.inkplate.io
Looking to get support? Write on our forums: http://forum.e-radionica.com/en/
31 August 2020 by e-radionica.com
*/
#include "Inkplate.h" //Include Inkplate library to the sketch
#include "HTTPClient.h" //Include library for HTTPClient
#include "WiFi.h" //Include library for WiFi
Inkplate display(INKPLATE_1BIT); //Create an object on Inkplate library and also set library into 1 Bit mode (Monochrome)
const char* ssid = ""; //Your WiFi SSID
const char* password = ""; //Your WiFi password
void setup() {
Serial.begin(115200);
display.begin(); //Init Inkplate library (you should call this function ONLY ONCE)
display.clearDisplay(); //Clear frame buffer of display
display.display(); //Put clear image on display
display.print("Connecting to WiFi...");
display.partialUpdate();
//Connect to the WiFi network.
WiFi.mode(WIFI_MODE_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
display.print(".");
display.partialUpdate();
}
display.println("\nWiFi OK! Downloading...");
display.partialUpdate();
//Try to load image and display it on e-paper at position X=0, Y=100
//NOTE: These methods require you to pass a reference to the display object as first parameter.
//NOTE: Both drawJpegFromWeb methods allow for an optional sisxth "invert" parameter. Setting this parameter to true
//will flip all colors on the image, making black white and white black.
//fifth parameter will dither the image.
if (!display.drawJpegFromWeb(&display, "https://varipass.org/destination.jpg", 0, 100, true, false)) {
//If is something failed (wrong filename or format), write error message on the screen.
display.println("Image open error");
display.display();
}
display.display();
WiFi.mode(WIFI_OFF);
}
void loop() {
//Nothing...
}

1967
tjpgd.c Normal file

File diff suppressed because it is too large Load Diff

93
tjpgd.h Normal file
View File

@ -0,0 +1,93 @@
/*----------------------------------------------------------------------------/
/ TJpgDec - Tiny JPEG Decompressor include file (C)ChaN, 2019
/----------------------------------------------------------------------------*/
#ifndef DEF_TJPGDEC
#define DEF_TJPGDEC
/*---------------------------------------------------------------------------*/
/* System Configurations */
#define JD_SZBUF 512 /* Size of stream input buffer */
#define JD_FORMAT 1 /* Output pixel format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */
#define JD_USE_SCALE 1 /* Use descaling feature for output */
#ifdef ESP32 // Table gives no speed mprovement for ESP32
#define JD_TBLCLIP 0 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */
#else
#define JD_TBLCLIP 1 /* Use table for saturation (might be a bit faster but increases 1K bytes of code size) */
#endif
/*---------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32) /* Main development platform */
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned long uint32_t;
typedef long int32_t;
#else
#include "stdint.h"
#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 damaged data) */
JDR_FMT2, /* 7: Right format but not supported */
JDR_FMT3 /* 8: Not supported JPEG standard */
} JRESULT;
/* Rectangular structure */
typedef struct {
uint16_t left, right, top, bottom;
} JRECT;
/* Decompressor object structure */
typedef struct JDEC_s JDEC;
struct JDEC_s {
uint16_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 dmsk; /* Current bit in the current read byte */
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 */
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] */
void* workbuf; /* Working buffer for IDCT and RGB output */
uint8_t* mcubuf; /* Working buffer for the MCU */
void* pool; /* Pointer to available memory pool */
uint16_t sz_pool; /* Size of momory pool (bytes available) */
uint16_t (*infunc)(JDEC*, uint8_t*, uint16_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 */
void* _display;
uint8_t _dither;
uint8_t _invert;
};
/* TJpgDec API functions */
JRESULT jd_prepare (JDEC*, uint16_t(*)(JDEC*,uint8_t*,uint16_t), void*, uint16_t, void*);
JRESULT jd_decomp (JDEC*, uint16_t(*)(JDEC*,void*,JRECT*), uint8_t, void*, uint8_t, uint8_t);
#ifdef __cplusplus
}
#endif
#endif /* _TJPGDEC */