Remove JPG and BMP support. Add uPNG support.

This commit is contained in:
Pim van Pelt
2017-11-26 21:03:48 +01:00
parent d5e01dedd2
commit 13f6ed14f1
4 changed files with 1400 additions and 541 deletions

View File

@ -9,6 +9,7 @@
#include <stdlib.h>
#include "tftspi.h"
#include "upng.h"
typedef struct {
uint16_t x1;
@ -601,43 +602,8 @@ void mgos_ili9341_clearStringRect(int x, int y, char *str);
//----------------------------------------------------------
color_t HSBtoRGB(float _hue, float _sat, float _brightness);
/*
* Decodes and displays JPG image
* Limits:
* Baseline only. Progressive and Lossless JPEG format are not supported.
* Image size: Up to 65520 x 65520 pixels
* Color space: YCbCr three components only. Gray scale image is not supported.
* Sampling factor: 4:4:4, 4:2:2 or 4:2:0.
*
* Params:
* x: image left position; constants CENTER & RIGHT can be used; negative value is accepted
* y: image top position; constants CENTER & BOTTOM can be used; negative value is accepted
* scale: image scale factor: 0~3; if scale>0, image is scaled by factor 1/(2^scale) (1/2, 1/4 or 1/8)
* fname: pointer to the name of the file from which the image will be read
* if set to NULL, image will be read from memory buffer pointed to by 'buf'
* buf: pointer to the memory buffer from which the image will be read; used if fname=NULL
* size: size of the memory buffer from which the image will be read; used if fname=NULL & buf!=NULL
*
*/
//-----------------------------------------------------------------------------------
void mgos_ili9341_jpg_image(int x, int y, uint8_t scale, char *fname, uint8_t *buf, int size);
/*
* Decodes and displays BMP image
* Only uncompressed RGB 24-bit with no color space information BMP images can be displayed
*
* Params:
* x: image left position; constants CENTER & RIGHT can be used; negative value is accepted
* y: image top position; constants CENTER & BOTTOM can be used; negative value is accepted
* scale: image scale factor: 0~7; if scale>0, image is scaled by factor 1/(scale+1)
* fname: pointer to the name of the file from which the image will be read
* if set to NULL, image will be read from memory buffer pointed to by 'imgbuf'
* imgbuf: pointer to the memory buffer from which the image will be read; used if fname=NULL
* size: size of the memory buffer from which the image will be read; used if fname=NULL & imgbuf!=NULL
*
*/
//-------------------------------------------------------------------------------------
int mgos_ili9341_bmp_image(int x, int y, uint8_t scale, char *fname, uint8_t *imgbuf, int size);
/* Draw PNG at coords x,y */
int mgos_ili9341_png(int x, int y, char *fname);
/*
* Compile font c source file to .fnt file

View File

@ -0,0 +1,81 @@
/*
uPNG -- derived from LodePNG version 20100808
Copyright (c) 2005-2010 Lode Vandevenne
Copyright (c) 2010 Sean Middleditch
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#if !defined(UPNG_H)
#define UPNG_H
typedef enum upng_error {
UPNG_EOK = 0, /* success (no error) */
UPNG_ENOMEM = 1, /* memory allocation failed */
UPNG_ENOTFOUND = 2, /* resource not found (file missing) */
UPNG_ENOTPNG = 3, /* image data does not have a PNG header */
UPNG_EMALFORMED = 4, /* image data is not a valid PNG image */
UPNG_EUNSUPPORTED = 5, /* critical PNG chunk type is not supported */
UPNG_EUNINTERLACED = 6, /* image interlacing is not supported */
UPNG_EUNFORMAT = 7, /* image color format is not supported */
UPNG_EPARAM = 8 /* invalid parameter to method call */
} upng_error;
typedef enum upng_format {
UPNG_BADFORMAT,
UPNG_RGB8,
UPNG_RGB16,
UPNG_RGBA8,
UPNG_RGBA16,
UPNG_LUMINANCE1,
UPNG_LUMINANCE2,
UPNG_LUMINANCE4,
UPNG_LUMINANCE8,
UPNG_LUMINANCE_ALPHA1,
UPNG_LUMINANCE_ALPHA2,
UPNG_LUMINANCE_ALPHA4,
UPNG_LUMINANCE_ALPHA8
} upng_format;
typedef struct upng_t upng_t;
upng_t* upng_new_from_bytes (const unsigned char* buffer, unsigned long size);
upng_t* upng_new_from_file (const char* path);
void upng_free (upng_t* upng);
upng_error upng_header (upng_t* upng);
upng_error upng_decode (upng_t* upng);
upng_error upng_get_error (const upng_t* upng);
unsigned upng_get_error_line (const upng_t* upng);
unsigned upng_get_width (const upng_t* upng);
unsigned upng_get_height (const upng_t* upng);
unsigned upng_get_bpp (const upng_t* upng);
unsigned upng_get_bitdepth (const upng_t* upng);
unsigned upng_get_components (const upng_t* upng);
unsigned upng_get_pixelsize (const upng_t* upng);
upng_format upng_get_format (const upng_t* upng);
const unsigned char* upng_get_buffer (const upng_t* upng);
unsigned upng_get_size (const upng_t* upng);
#endif /*defined(UPNG_H)*/

View File

@ -15,7 +15,7 @@
#include "tft.h"
#include "time.h"
#include <math.h>
#include "rom/tjpgd.h"
// #include "rom/tjpgd.h"
#include "esp_heap_caps.h"
#include "tftspi.h"
#include "mgos.h"
@ -2242,520 +2242,51 @@ void mgos_ili9341_restoreClipWin()
}
// ================ JPG SUPPORT ================================================
// User defined device identifier
typedef struct {
FILE *fhndl; // File handler for input function
int x; // image top left point X position
int y; // image top left point Y position
uint8_t *membuff; // memory buffer containing the image
uint32_t bufsize; // size of the memory buffer
uint32_t bufptr; // memory buffer current position
color_t *linbuf[2]; // memory buffer used for display output
uint8_t linbuf_idx;
} JPGIODEV;
// User defined call-back function to input JPEG data from file
//---------------------
static UINT tjd_input (
JDEC* jd, // Decompression object
BYTE* buff, // Pointer to the read buffer (NULL:skip)
UINT nd // Number of bytes to read/skip from input stream
)
int mgos_ili9341_png(int x, int y, char *fname)
{
int rb = 0;
// Device identifier for the session (5th argument of jd_prepare function)
JPGIODEV *dev = (JPGIODEV*)jd->device;
upng_t* upng;
const uint8_t *png_buf;
uint16_t i,j;
color_t pixel;
if (buff) { // Read nd bytes from the input strem
rb = fread(buff, 1, nd, dev->fhndl);
return rb; // Returns actual number of bytes read
}
else { // Remove nd bytes from the input stream
if (fseek(dev->fhndl, nd, SEEK_CUR) >= 0) return nd;
else return 0;
}
}
int ret = -1;
// User defined call-back function to input JPEG data from memory buffer
//-------------------------
static UINT tjd_buf_input (
JDEC* jd, // Decompression object
BYTE* buff, // Pointer to the read buffer (NULL:skip)
UINT nd // Number of bytes to read/skip from input stream
)
{
// Device identifier for the session (5th argument of jd_prepare function)
JPGIODEV *dev = (JPGIODEV*)jd->device;
if (!dev->membuff) return 0;
if (dev->bufptr >= (dev->bufsize + 2)) return 0; // end of stream
if ((dev->bufptr + nd) > (dev->bufsize + 2)) nd = (dev->bufsize + 2) - dev->bufptr;
if (buff) { // Read nd bytes from the input strem
memcpy(buff, dev->membuff + dev->bufptr, nd);
dev->bufptr += nd;
return nd; // Returns number of bytes read
}
else { // Remove nd bytes from the input stream
dev->bufptr += nd;
return nd;
}
}
// User defined call-back function to output RGB bitmap to display device
//----------------------
static UINT tjd_output (
JDEC* jd, // Decompression object of current session
void* bitmap, // Bitmap data to be output
JRECT* rect // Rectangular region to output
)
{
// Device identifier for the session (5th argument of jd_prepare function)
JPGIODEV *dev = (JPGIODEV*)jd->device;
// ** Put the rectangular into the display device **
int x;
int y;
int dleft, dtop, dright, dbottom;
BYTE *src = (BYTE*)bitmap;
int left = rect->left + dev->x;
int top = rect->top + dev->y;
int right = rect->right + dev->x;
int bottom = rect->bottom + dev->y;
if ((left > dispWin.x2) || (top > dispWin.y2)) return 1; // out of screen area, return
if ((right < dispWin.x1) || (bottom < dispWin.y1)) return 1;// out of screen area, return
if (left < dispWin.x1) dleft = dispWin.x1;
else dleft = left;
if (top < dispWin.y1) dtop = dispWin.y1;
else dtop = top;
if (right > dispWin.x2) dright = dispWin.x2;
else dright = right;
if (bottom > dispWin.y2) dbottom = dispWin.y2;
else dbottom = bottom;
if ((dleft > dispWin.x2) || (dtop > dispWin.y2)) return 1; // out of screen area, return
if ((dright < dispWin.x1) || (dbottom < dispWin.y1)) return 1; // out of screen area, return
uint32_t len = ((dright-dleft+1) * (dbottom-dtop+1)); // calculate length of data
if ((len > 0) && (len <= JPG_IMAGE_LINE_BUF_SIZE)) {
uint8_t *dest = (uint8_t *)(dev->linbuf[dev->linbuf_idx]);
for (y = top; y <= bottom; y++) {
for (x = left; x <= right; x++) {
// Clip to display area
if ((x >= dleft) && (y >= dtop) && (x <= dright) && (y <= dbottom)) {
*dest++ = (*src++) & 0xFC;
*dest++ = (*src++) & 0xFC;
*dest++ = (*src++) & 0xFC;
}
else src += 3; // skip
}
}
wait_trans_finish(1);
send_data(dleft, dtop, dright, dbottom, len, dev->linbuf[dev->linbuf_idx]);
dev->linbuf_idx = ((dev->linbuf_idx + 1) & 1);
}
else {
wait_trans_finish(1);
LOG(LL_ERROR, ("Data size error: %d jpg: (%d,%d,%d,%d) disp: (%d,%d,%d,%d)", len, left,top,right,bottom, dleft,dtop,dright,dbottom));
return 0; // stop decompression
}
return 1; // Continue to decompression
}
// tft.jpgimage(X, Y, scale, file_name, buf, size]
// X & Y can be < 0 !
//==================================================================================
void mgos_ili9341_jpg_image(int x, int y, uint8_t scale, char *fname, uint8_t *buf, int size)
{
JPGIODEV dev;
struct stat sb;
char *work = NULL; // Pointer to the working buffer (must be 4-byte aligned)
UINT sz_work = 3800; // Size of the working buffer (must be power of 2)
JDEC jd; // Decompression object (70 bytes)
JRESULT rc;
dev.linbuf[0] = NULL;
dev.linbuf[1] = NULL;
dev.linbuf_idx = 0;
dev.fhndl = NULL;
x+= dispWin.x1;
y+= dispWin.y1;
if (fname == NULL) {
// image from buffer
dev.membuff = buf;
dev.bufsize = size;
dev.bufptr = 0;
}
else {
// image from file
dev.membuff = NULL;
dev.bufsize = 0;
dev.bufptr = 0;
if (stat(fname, &sb) != 0) {
if (image_debug) LOG(LL_ERROR, ("File error: %ss", strerror(errno)));
if (!(upng = upng_new_from_file(fname))) {
LOG(LL_ERROR, ("Can't read %s", fname));
goto exit;
}
dev.fhndl = fopen(fname, "r");
if (!dev.fhndl) {
if (image_debug) LOG(LL_ERROR, ("Error opening file: %s", strerror(errno)));
upng_decode(upng);
if (upng_get_error(upng) != UPNG_EOK) {
LOG(LL_ERROR, ("PNG decode error"));
goto exit;
}
}
if (scale > 3) scale = 3;
work = malloc(sz_work);
if (work) {
if (dev.membuff) rc = jd_prepare(&jd, tjd_buf_input, (void *)work, sz_work, &dev);
else rc = jd_prepare(&jd, tjd_input, (void *)work, sz_work, &dev);
if (rc == JDR_OK) {
if (x == CENTER) x = ((dispWin.x2 - dispWin.x1 + 1 - (int)(jd.width >> scale)) / 2) + dispWin.x1;
else if (x == RIGHT) x = dispWin.x2 + 1 - (int)(jd.width >> scale);
if (y == CENTER) y = ((dispWin.y2 - dispWin.y1 + 1 - (int)(jd.height >> scale)) / 2) + dispWin.y1;
else if (y == BOTTOM) y = dispWin.y2 + 1 - (int)(jd.height >> scale);
if (x < ((dispWin.x2-1) * -1)) x = (dispWin.x2-1) * -1;
if (y < ((dispWin.y2-1)) * -1) y = (dispWin.y2-1) * -1;
if (x > (dispWin.x2-1)) x = dispWin.x2 - 1;
if (y > (dispWin.y2-1)) y = dispWin.y2-1;
dev.x = x;
dev.y = y;
dev.linbuf[0] = heap_caps_malloc(JPG_IMAGE_LINE_BUF_SIZE*3, MALLOC_CAP_DMA);
if (dev.linbuf[0] == NULL) {
if (image_debug) LOG(LL_ERROR, ("Error allocating line buffer #0"));
goto exit;
}
dev.linbuf[1] = heap_caps_malloc(JPG_IMAGE_LINE_BUF_SIZE*3, MALLOC_CAP_DMA);
if (dev.linbuf[1] == NULL) {
if (image_debug) LOG(LL_ERROR, ("Error allocating line buffer #1"));
if (upng_get_format(upng) != UPNG_RGB8) {
LOG(LL_ERROR, ("PNG is not in RGB8 format"));
goto exit;
}
// Do stuff with upng data
LOG(LL_INFO, ("%s: w=%d h=%d size=%d bpp=%d bitdepth=%d pixelsize=%d", fname, upng_get_width(upng), upng_get_height(upng), upng_get_size(upng), upng_get_bpp(upng), upng_get_bitdepth(upng), upng_get_pixelsize(upng)));
// Start to decode the JPEG file
png_buf = upng_get_buffer(upng);
disp_select();
rc = jd_decomp(&jd, tjd_output, scale);
for(j=0; j<upng_get_height(upng); j++) {
for(i=0; i<upng_get_width(upng); i++) {
pixel.r = *png_buf++;
pixel.g = *png_buf++;
pixel.b = *png_buf++;
mgos_ili9341_drawPixel(i, j, pixel, 0);
}
}
disp_deselect();
if (rc != JDR_OK) {
if (image_debug) LOG(LL_ERROR, ("Jpg decompression error %d", rc));
}
if (image_debug) LOG(LL_INFO, ("Jpg size: %dx%d, position; %d,%d, scale: %d, bytes used: %d", jd.width, jd.height, x, y, scale, jd.sz_pool));
}
else {
if (image_debug) LOG(LL_ERROR, ("jpg prepare error %d", rc));
}
}
else {
if (image_debug) LOG(LL_ERROR, ("work buffer allocation error"));
}
exit:
if (work) free(work); // free work buffer
if (dev.linbuf[0]) free(dev.linbuf[0]);
if (dev.linbuf[1]) free(dev.linbuf[1]);
if (dev.fhndl) fclose(dev.fhndl); // close input file
if (upng) upng_free(upng);
return ret;
}
//====================================================================================
int mgos_ili9341_bmp_image(int x, int y, uint8_t scale, char *fname, uint8_t *imgbuf, int size)
{
FILE *fhndl = NULL;
struct stat sb;
int i, err=0;
int img_xsize, img_ysize, img_xstart, img_xlen, img_ystart, img_ylen;
int img_pos, img_pix_pos, scan_lines, rd_len;
uint8_t tmpc;
uint16_t wtemp;
uint32_t temp;
int disp_xstart, disp_xend, disp_ystart, disp_yend;
uint8_t buf[56];
char err_buf[64];
uint8_t *line_buf[2] = {NULL,NULL};
uint8_t lb_idx = 0;
uint8_t *scale_buf = NULL;
uint8_t scale_pix;
uint16_t co[3] = {0,0,0}; // RGB sum
uint8_t npix;
if (scale > 7) scale = 7;
scale_pix = scale+1; // scale factor ( 1~8 )
if (fname) {
// * File name is given, reading image from file
if (stat(fname, &sb) != 0) {
sprintf(err_buf, "opening file");
err = -1;
goto exit;
}
size = sb.st_size;
fhndl = fopen(fname, "r");
if (!fhndl) {
sprintf(err_buf, "opening file");
err = -2;
goto exit;
}
i = fread(buf, 1, 54, fhndl); // read header
}
else {
// * Reading image from buffer
if ((imgbuf) && (size > 54)) {
memcpy(buf, imgbuf, 54);
i = 54;
}
else i = 0;
}
sprintf(err_buf, "reading header");
if (i != 54) {err = -3; goto exit;}
// ** Check image header and get image properties
if ((buf[0] != 'B') || (buf[1] != 'M')) {err=-4; goto exit;} // accept only images with 'BM' id
memcpy(&temp, buf+2, 4); // file size
if (temp != size) {err=-5; goto exit;}
memcpy(&img_pos, buf+10, 4); // start of pixel data
memcpy(&temp, buf+14, 4); // BMP header size
if (temp != 40) {err=-6; goto exit;}
memcpy(&wtemp, buf+26, 2); // the number of color planes
if (wtemp != 1) {err=-7; goto exit;}
memcpy(&wtemp, buf+28, 2); // the number of bits per pixel
if (wtemp != 24) {err=-8; goto exit;}
memcpy(&temp, buf+30, 4); // the compression method being used
if (temp != 0) {err=-9; goto exit;}
memcpy(&img_xsize, buf+18, 4); // the bitmap width in pixels
memcpy(&img_ysize, buf+22, 4); // the bitmap height in pixels
// * scale image dimensions
img_xlen = img_xsize / scale_pix; // image display horizontal size
img_ylen = img_ysize / scale_pix; // image display vertical size
if (x == CENTER) x = ((dispWin.x2 - dispWin.x1 + 1 - img_xlen) / 2) + dispWin.x1;
else if (x == RIGHT) x = dispWin.x2 + 1 - img_xlen;
if (y == CENTER) y = ((dispWin.y2 - dispWin.y1 + 1 - img_ylen) / 2) + dispWin.y1;
else if (y == BOTTOM) y = dispWin.y2 + 1 - img_ylen;
if ((x < ((dispWin.x2 + 1) * -1)) || (x > (dispWin.x2 + 1)) || (y < ((dispWin.y2 + 1) * -1)) || (y > (dispWin.y2 + 1))) {
sprintf(err_buf, "out of display area (%d,%d", x, y);
err = -10;
goto exit;
}
// ** set display and image areas
if (x < dispWin.x1) {
disp_xstart = dispWin.x1;
img_xstart = -x; // image pixel line X offset
img_xlen += x;
}
else {
disp_xstart = x;
img_xstart = 0;
}
if (y < dispWin.y1) {
disp_ystart = dispWin.y1;
img_ystart = -y; // image pixel line Y offset
img_ylen += y;
}
else {
disp_ystart = y;
img_ystart = 0;
}
disp_xend = disp_xstart + img_xlen - 1;
disp_yend = disp_ystart + img_ylen - 1;
if (disp_xend > dispWin.x2) {
disp_xend = dispWin.x2;
img_xlen = disp_xend - disp_xstart + 1;
}
if (disp_yend > dispWin.y2) {
disp_yend = dispWin.y2;
img_ylen = disp_yend - disp_ystart + 1;
}
if ((img_xlen < 8) || (img_ylen < 8) || (img_xstart >= (img_xsize-2)) || ((img_ysize - img_ystart) < 2)) {
sprintf(err_buf, "image too small");
err = -11;
goto exit;
}
// ** Allocate memory for 2 lines of image pixels
line_buf[0] = heap_caps_malloc(img_xsize*3, MALLOC_CAP_DMA);
if (line_buf[0] == NULL) {
sprintf(err_buf, "allocating line buffer #1");
err=-12;
goto exit;
}
line_buf[1] = heap_caps_malloc(img_xsize*3, MALLOC_CAP_DMA);
if (line_buf[1] == NULL) {
sprintf(err_buf, "allocating line buffer #2");
err=-13;
goto exit;
}
if (scale) {
// Allocate memory for scale buffer
rd_len = img_xlen * 3 * scale_pix;
scale_buf = malloc(rd_len*scale_pix);
if (scale_buf == NULL) {
sprintf(err_buf, "allocating scale buffer");
err=-14;
goto exit;
}
}
else rd_len = img_xlen * 3;
// ** ***************************************************** **
// ** BMP images are stored in file from LAST to FIRST line **
// ** ***************************************************** **
/* Used variables:
img_xsize horizontal image size in pixels
img_ysize number of image lines
img_xlen image display horizontal scaled size in pixels
img_ylen image display vertical scaled size in pixels
img_xstart first pixel in line to be displayed
img_ystart first image line to be displayed
img_xlen number of pixels in image line to be displayed, starting with 'img_xstart'
img_ylen number of lines in image to be displayed, starting with 'img_ystart'
rd_len length of color data which are read from image line in bytes
*/
// Set position in image to the first color data (beginning of the LAST line)
img_pos += (img_ystart * (img_xsize*3));
if (fhndl) {
if (fseek(fhndl, img_pos, SEEK_SET) != 0) {
sprintf(err_buf, "file seek at %d", img_pos);
err = -15;
goto exit;
}
}
if (image_debug) LOG(LL_INFO, ("BMP: image size: (%d,%d) scale: %d disp size: (%d,%d) img xofs: %d img yofs: %d at: %d,%d; line buf: 2* %d scale buf: %d",
img_xsize, img_ysize, scale_pix, img_xlen, img_ylen, img_xstart, img_ystart, disp_xstart, disp_ystart, img_xsize*3, ((scale) ? (rd_len*scale_pix) : 0)));
// * Select the display
disp_select();
while ((disp_yend >= disp_ystart) && ((img_pos + (img_xsize*3)) <= size)) {
if (img_pos > size) {
sprintf(err_buf, "EOF reached: %d > %d", img_pos, size);
err = -16;
goto exit1;
}
if (scale == 0) {
// Read the line of color data into color buffer
if (fhndl) {
i = fread(line_buf[lb_idx], 1, img_xsize*3, fhndl); // read line from file
if (i != (img_xsize*3)) {
sprintf(err_buf, "file read at %d (%d<>%d)", img_pos, i, img_xsize*3);
err = -16;
goto exit1;
}
}
else memcpy(line_buf[lb_idx], imgbuf+img_pos, img_xsize*3);
if (img_xstart > 0) memmove(line_buf[lb_idx], line_buf[lb_idx]+(img_xstart*3), rd_len);
// Convert colors BGR-888 (BMP) -> RGB-888 (DISPLAY) ===
for (i=0; i < rd_len; i += 3) {
tmpc = line_buf[lb_idx][i+2] & 0xfc; // save R
line_buf[lb_idx][i+2] = line_buf[lb_idx][i] & 0xfc; // B -> R
line_buf[lb_idx][i] = tmpc; // R -> B
line_buf[lb_idx][i+1] &= 0xfc; // G
}
img_pos += (img_xsize*3);
}
else {
// scale image, read 'scale_pix' lines and find the average color
for (scan_lines=0; scan_lines<scale_pix; scan_lines++) {
if (img_pos > size) break;
if (fhndl) {
i = fread(line_buf[lb_idx], 1, img_xsize*3, fhndl); // read line from file
if (i != (img_xsize*3)) {
sprintf(err_buf, "file read at %d (%d<>%d)", img_pos, i, img_xsize*3);
err = -17;
goto exit1;
}
}
else memcpy(line_buf[lb_idx], imgbuf+img_pos, img_xsize*3);
img_pos += (img_xsize*3);
// copy only data which are displayed to scale buffer
memcpy(scale_buf + (rd_len * scan_lines), line_buf[lb_idx]+img_xstart, rd_len);
}
// Populate display line buffer
for (int n=0;n<(img_xlen*3);n += 3) {
memset(co, 0, sizeof(co)); // initialize color sum
npix = 0; // initialize number of pixels in scale rectangle
// sum all pixels in scale rectangle
for (int sc_line=0; sc_line<scan_lines; sc_line++) {
// Get colors position in scale buffer
img_pix_pos = (rd_len * sc_line) + (n * scale_pix);
for (int sc_col=0; sc_col<scale_pix; sc_col++) {
co[0] += scale_buf[img_pix_pos];
co[1] += scale_buf[img_pix_pos + 1];
co[2] += scale_buf[img_pix_pos + 2];
npix++;
}
}
// Place the average in display buffer, convert BGR-888 (BMP) -> RGB-888 (DISPLAY)
line_buf[lb_idx][n+2] = (uint8_t)(co[0] / npix); // B
line_buf[lb_idx][n+1] = (uint8_t)(co[1] / npix); // G
line_buf[lb_idx][n] = (uint8_t)(co[2] / npix); // R
}
}
wait_trans_finish(1);
send_data(disp_xstart, disp_yend, disp_xend, disp_yend, img_xlen, (color_t *)line_buf[lb_idx]);
lb_idx = (lb_idx + 1) & 1; // change buffer
disp_yend--;
}
err = 0;
exit1:
disp_deselect();
exit:
if (scale_buf) free(scale_buf);
if (line_buf[0]) free(line_buf[0]);
if (line_buf[1]) free(line_buf[1]);
if (fhndl) fclose(fhndl);
if ((err) && (image_debug)) LOG(LL_ERROR, ("Error: %d [%s]", err, err_buf));
return err;
}
void mgos_ili9341_set_fg(const color_t *color)
{
_fg = *color;

1281
libs/ili9341/src/upng.c Normal file

File diff suppressed because it is too large Load Diff