This commit is contained in:
2026-02-13 14:42:07 -08:00
parent df0527b123
commit fbc02af589
670 changed files with 55968 additions and 51275 deletions

View File

@@ -1,65 +0,0 @@
//
// PNG Display helper class
//
// written by Larry Bank
// bitbank@pobox.com
//
// Copyright 2025 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.
//===========================================================================
//
#ifndef __PNGDISPLAY__
#define __PNGDISPLAY__
#include <PNGdec.h>
#include <SD.h>
#ifndef ARDUINO_ARCH_NRF52
#include "FS.h"
#include <LittleFS.h>
#endif
#if !defined(__BB_EPAPER__) && !defined(SPI_LCD_H) && !defined(__FASTEPD_H__)
#error "One of the following display libraries must be included BEFORE PNGDisplay: bb_spi_lcd, bb_epaper, FastEPD"
#endif
// To center one or both coordinates for the drawing position
// use this constant value
#define PNGDISPLAY_CENTER -2
class PNGDisplay
{
public:
#ifdef SPI_LCD_H
int loadPNG(BB_SPI_LCD *pLCD, int x, int y, const void *pData, int iDataSize, uint32_t bgColor = 0xffffffff);
int loadPNG(BB_SPI_LCD *pLCD, int x, int y, const char *fname, uint32_t bgColor = 0xffffffff);
int loadPNG_LFS(BB_SPI_LCD *pLCD, int x, int y, const char *fname, uint32_t bgColor = 0xffffffff);
#endif // SPI_LCD_H
#ifdef __FASTEPD_H__
int loadPNG(FASTEPD *pDisplay, int x, int y, const void *pData, int iDataSize, uint32_t bgColor = 0xffffffff);
int loadPNG(FASTEPD *pDisplay, int x, int y, const char *fname, uint32_t bgColor = 0xffffffff);
int loadPNG_LFS(FASTEPD *pDisplay, int x, int y, const char *fname, uint32_t bgColor = 0xffffffff);
#endif // __FASTEPD_H__
#ifdef __BB_EPAPER__
int loadPNG(BBEPAPER *pDisplay, int x, int y, const void *pData, int iDataSize, uint32_t bgColor = 0xffffffff);
int loadPNG(BBEPAPER *pDisplay, int x, int y, const char *fname, uint32_t bgColor = 0xffffffff);
int loadPNG_LFS(BBEPAPER *pDisplay, int x, int y, const char *fname, uint32_t bgColor = 0xffffffff);
#endif // __BB_EPAPER__
int getPNGInfo(int *width, int *height, int *bpp, const void *pData, int iDataSize);
int getPNGInfo(int *width, int *height, int *bpp, const char *fname);
int getPNGInfo_LFS(int *width, int *height, int *bpp, const char *fname);
int getLastError() {return _iLastError;}
private:
int _iLastError;
};
#endif // __PNGDISPLAY__

View File

@@ -1,465 +0,0 @@
//
// PNG Display helper class
//
// written by Larry Bank
// bitbank@pobox.com
//
// Copyright 2025 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.
//===========================================================================
//
#ifndef __PNGDISPLAY_IMPL__
#define __PNGDISPLAY_IMPL__
#include "PNGDisplay.h"
static int PNGDraw(PNGDRAW *pDraw)
{
int *pInfo = (int *)pDraw->pUser;
uint16_t *p16;
PNG *pPNG;
#ifdef SPI_LCD_H
BB_SPI_LCD *pLCD;
pLCD = (BB_SPI_LCD *)pInfo[0]; // pointer to LCD class pointer
pPNG = (PNG *)pInfo[1]; // pointer to PNG class pointer
p16 = (uint16_t *)&pInfo[3]; // start of temporary pixel space
pPNG->getLineAsRGB565(pDraw, p16, PNG_RGB565_BIG_ENDIAN, (uint32_t)pInfo[2]);
pLCD->pushPixels(p16, pDraw->iWidth);
#endif // SPI_LCD_H
#ifdef __BB_EPAPER__
BBEPAPER *pEPD;
int w, iLen, iPitch; // bits per pixel mode of the EPD
uint8_t uc_s, uc_d, srcMask, destMask, *s, *d;
int32_t iWidth, i, x, y;
pEPD = (BBEPAPER *)pInfo[0]; // pointer to display class object
pPNG = (PNG *)pInfo[1]; // pointer to PNG class pointer
if (pPNG->getBpp() != 1) {
return 0; // mismatch, don't try to convert the bit depth
}
d = (uint8_t *)pEPD->getBuffer();
x = pInfo[3]; y = pInfo[4]; // display offset to draw the image
if (pDraw->y + y > pEPD->height()) return 0; // off bottom edge
w = pPNG->getWidth();
if (w + x > pEPD->width()) w = pEPD->width() - x; // clip to right edge
iPitch = (pEPD->width()+7)/8;
d += (x/8) + ((pDraw->y + y) * iPitch);
srcMask = 0x80;
destMask = 0x80 >> (x & 7);
s = pDraw->pPixels;
i = 0;
if ((x & 7) == 0) { // take advantage of src/dest bit alignment
while (i < w-7) {
*d++ = *s++;
i += 8;
}
}
uc_s = *s++;
uc_d = d[0];
for (; i<w; i++) { // do it pixel-by-pixel
if (uc_s & srcMask) {
uc_d |= destMask; // use the same pixel color polarity
} else {
uc_d &= ~destMask;
}
srcMask >>= 1;
if (srcMask == 0) {
srcMask = 0x80;
uc_s = *s++;
}
destMask >>= 1;
if (destMask == 0) {
destMask = 0x80;
*d++ = uc_d;
uc_d = d[0];
}
} // for i
if (destMask != 0x80) { // store the last partial byte
d[0] = uc_d;
}
#endif // __BB_EPAPER__
#ifdef __FASTEPD_H__
FASTEPD *pEPD;
int i, iLen, iPitch, iBpp; // bits per pixel mode of the EPD
uint8_t srcMask, destMask, uc_s, uc_d, *s, *d;
int32_t iWidth, w, x, y;
pEPD = (FASTEPD *)pInfo[0]; // pointer to display class object
pPNG = (PNG *)pInfo[1]; // pointer to PNG class pointer
iBpp = (pEPD->getMode() == BB_MODE_1BPP) ? 1:4;
if (pPNG->getBpp() != iBpp) return 0; // mismatch, don't try to convert the bit depth
d = (uint8_t *)pEPD->currentBuffer();
x = pInfo[3]; y = pInfo[4]; // display offset to draw the image
if (pDraw->y + y > pEPD->height()) return 0; // off bottom edge
w = pPNG->getWidth();
if (w + x > pEPD->width()) w = pEPD->width() - x; // clip to right edge
iPitch = (pEPD->width()*iBpp)/8;
d += ((x * iBpp)/8) + ((pDraw->y + y) * iPitch);
if (iBpp == 4) {
memcpy(d, pDraw->pPixels, (w*iBpp)/8);
} else { // 1 bpp
srcMask = 0x80;
destMask = 0x80 >> (x & 7);
s = pDraw->pPixels;
if ((x & 7) == 0) { // take advantage of src/dest bit alignment
while (i <= w-7) {
*d++ = *s++;
i += 8;
}
}
uc_s = *s++;
uc_d = d[0];
for (; i<w; i++) { // do it pixel-by-pixel
if (uc_s & srcMask) {
uc_d |= destMask; // use the same pixel color polarity
} else {
uc_d &= ~destMask;
}
srcMask >>= 1;
if (srcMask == 0) {
srcMask = 0x80;
uc_s = *s++;
}
destMask >>= 1;
if (destMask == 0) {
destMask = 0x80;
*d++ = uc_d;
uc_d = d[0];
}
} // for i
if (destMask != 0) { // store the last partial byte
d[0] = uc_d;
}
} // 1-bpp
#endif // __FASTEPD_H__
return 1; // continue decoding
} /* PNGDraw() */
// Functions to access a file on the SD card
static void * pngOpen(const char *filename, int32_t *size) {
static File myfile;
myfile = SD.open(filename);
*size = myfile.size();
return &myfile;
}
#ifndef ARDUINO_ARCH_NRF52
static void * pngOpenLFS(const char *filename, int32_t *size) {
static File myfile;
myfile = LittleFS.open(filename, FILE_READ);
if (myfile) {
*size = myfile.size();
return &myfile;
} else {
return NULL;
}
}
#endif // !nRF52
static void pngClose(void *handle) {
File *pFile = (File *)handle;
if (pFile) pFile->close();
}
static int32_t pngRead(PNGFILE *handle, uint8_t *buffer, int32_t length) {
File *pFile = (File *)handle->fHandle;
if (!pFile) return 0;
return pFile->read(buffer, length);
}
static int32_t pngSeek(PNGFILE *handle, int32_t position) {
File *pFile = (File *)handle->fHandle;
if (!pFile) return 0;
return pFile->seek(position);
}
#ifdef SPI_LCD_H
int PNGDisplay::loadPNG(BB_SPI_LCD *pDisplay, int x, int y, const void *pData, int iDataSize, uint32_t bgColor)
#endif // SPI_LCD_H
#ifdef __FASTEPD_H__
int PNGDisplay::loadPNG(FASTEPD *pDisplay, int x, int y, const void *pData, int iDataSize, uint32_t bgColor)
#endif // __FASTEPD_H__
#ifdef __BB_EPAPER__
int PNGDisplay::loadPNG(BBEPAPER *pDisplay, int x, int y, const void *pData, int iDataSize, uint32_t bgColor)
#endif // __BB_EPAPER__
{
PNG *png;
int w, h, rc;
uint32_t *png_info;
png = (PNG *)malloc(sizeof(PNG));
if (!png) {
_iLastError = PNG_MEM_ERROR;
return 0;
}
rc = png->openRAM((uint8_t *)pData, iDataSize, PNGDraw);
if (rc == PNG_SUCCESS) {
w = png->getWidth();
h = png->getHeight();
if (x == PNGDISPLAY_CENTER) {
x = (pDisplay->width() - w)/2;
if (x < 0) x = 0;
} else if (x < 0 || w + x > pDisplay->width()) {
// clipping is not supported
_iLastError = PNG_INVALID_PARAMETER;
free(png);
return 0;
}
if (y == PNGDISPLAY_CENTER) {
y = (pDisplay->height() - h)/2;
if (y < 0) y = 0;
} else if (y < 0 || y + h > pDisplay->height()) {
// clipping is not supported
free(png);
_iLastError = PNG_INVALID_PARAMETER;
return 0;
}
png_info = (uint32_t *)malloc((w * sizeof(uint16_t)) + 3 * sizeof(int)); // enough for pixels and 3 32-bit values
png_info[0] = (uint32_t)pDisplay;
png_info[1] = (uint32_t)png;
png_info[2] = bgColor;
png_info[3] = x;
png_info[4] = y;
#ifdef SPI_LCD_H
pDisplay->setAddrWindow(x, y, w, h);
#endif
png->decode((void *)png_info, 0); // simple decode, no options
png->close();
free(png);
_iLastError = PNG_SUCCESS;
return 1;
}
_iLastError = png->getLastError();
free(png);
return 0;
} /* loadPNG() */
#ifdef SPI_LCD_H
int PNGDisplay::loadPNG(BB_SPI_LCD *pDisplay, int x, int y, const char *fname, uint32_t bgColor)
#endif
#ifdef __FASTEPD_H__
int PNGDisplay::loadPNG(FASTEPD *pDisplay, int x, int y, const char *fname, uint32_t bgColor)
#endif
#ifdef __BB_EPAPER__
int PNGDisplay::loadPNG(BBEPAPER *pDisplay, int x, int y, const char *fname, uint32_t bgColor)
#endif
{
PNG *png;
int w, h, rc;
uint32_t *png_info;
png = (PNG *)malloc(sizeof(PNG));
if (!png) {
_iLastError = PNG_MEM_ERROR;
return 0;
}
rc = png->open(fname, pngOpen, pngClose, pngRead, pngSeek, PNGDraw);
if (rc == PNG_SUCCESS) {
w = png->getWidth();
h = png->getHeight();
if (x == PNGDISPLAY_CENTER) {
x = (pDisplay->width() - w)/2;
if (x < 0) x = 0;
} else if (x < 0 || w + x > pDisplay->width()) {
// clipping is not supported
free(png);
_iLastError = PNG_INVALID_PARAMETER;
return 0;
}
if (y == PNGDISPLAY_CENTER) {
y = (pDisplay->height() - h)/2;
if (y < 0) y = 0;
} else if (y < 0 || y + h > pDisplay->height()) {
free(png);
_iLastError = PNG_INVALID_PARAMETER;
return 0;
}
png_info = (uint32_t *)malloc((w * sizeof(uint16_t)) + 3 * sizeof(int)); // enough for pixels and 3 32-bit values
png_info[0] = (uint32_t)pDisplay;
png_info[1] = (uint32_t)png;
png_info[2] = bgColor;
png_info[3] = x;
png_info[4] = y;
#ifdef SPI_LCD_H
pDisplay->setAddrWindow(x, y, w, h);
#endif
png->decode((void *)png_info, 0); // simple decode, no options
png->close();
free(png);
_iLastError = PNG_SUCCESS;
return 1;
}
_iLastError = png->getLastError();
free(png);
return 0;
} /* loadPNG() */
#ifndef ARDUINO_ARCH_NRF52
#ifdef SPI_LCD_H
int PNGDisplay::loadPNG_LFS(BB_SPI_LCD *pDisplay, int x, int y, const char *fname, uint32_t bgColor)
#endif
#ifdef __FASTEPD_H__
int PNGDisplay::loadPNG_LFS(FASTEPD *pDisplay, int x, int y, const char *fname, uint32_t bgColor)
#endif
#ifdef __BB_EPAPER__
int PNGDisplay::loadPNG_LFS(BBEPAPER *pDisplay, int x, int y, const char *fname, uint32_t bgColor)
#endif
{
PNG *png;
int w, h, rc;
uint32_t *png_info;
if (!LittleFS.begin(false)) {
return 0;
}
png = (PNG *)malloc(sizeof(PNG));
if (!png) {
_iLastError = PNG_MEM_ERROR;
return 0;
}
rc = png->open(fname, pngOpenLFS, pngClose, pngRead, pngSeek, PNGDraw);
if (rc == PNG_SUCCESS) {
w = png->getWidth();
h = png->getHeight();
if (x == PNGDISPLAY_CENTER) {
x = (pDisplay->width() - w)/2;
if (x < 0) x = 0;
} else if (x < 0 || w + x > pDisplay->width()) {
// clipping is not supported
free(png);
_iLastError = PNG_INVALID_PARAMETER;
return 0;
}
if (y == PNGDISPLAY_CENTER) {
y = (pDisplay->height() - h)/2;
if (y < 0) y = 0;
} else if (y < 0 || y + h > pDisplay->height()) {
free(png);
_iLastError = PNG_INVALID_PARAMETER;
return 0;
}
png_info = (uint32_t *)malloc((w * sizeof(uint16_t)) + 3 * sizeof(int)); // enough for pixels and 3 32-bit values
png_info[0] = (uint32_t)pDisplay;
png_info[1] = (uint32_t)png;
png_info[2] = bgColor;
png_info[3] = x;
png_info[4] = y;
#ifdef SPI_LCD_H
pDisplay->setAddrWindow(x, y, w, h);
#endif
png->decode((void *)png_info, 0); // simple decode, no options
png->close();
free(png);
_iLastError = PNG_SUCCESS;
return 1;
}
_iLastError = png->getLastError();
free(png);
return 0;
} /* loadPNG_LFS() */
#endif // !nRF52
int PNGDisplay::getPNGInfo(int *width, int *height, int *bpp, const void *pData, int iDataSize)
{
PNG *png;
int rc;
uint32_t *png_info;
if (!width || !height || !bpp || !pData || iDataSize < 32) return 0;
png = (PNG *)malloc(sizeof(PNG));
if (!png) {
_iLastError = PNG_MEM_ERROR;
return 0;
}
rc = png->openRAM((uint8_t *)pData, iDataSize, PNGDraw);
if (rc == PNG_SUCCESS) {
*width = png->getWidth();
*height = png->getHeight();
*bpp = png->getBpp();
free(png);
_iLastError = PNG_SUCCESS;
return 1;
}
_iLastError = png->getLastError();
free(png);
return 0;
} /* getPNGInfo() */
int PNGDisplay::getPNGInfo(int *width, int *height, int *bpp, const char *fname)
{
PNG *png;
int rc;
uint32_t *png_info;
if (!width || !height || !bpp || !fname) return 0;
png = (PNG *)malloc(sizeof(PNG));
if (!png) {
_iLastError = PNG_MEM_ERROR;
return 0;
}
rc = png->open(fname, pngOpen, pngClose, pngRead, pngSeek, PNGDraw);
if (rc == PNG_SUCCESS) {
*width = png->getWidth();
*height = png->getHeight();
*bpp = png->getBpp();
png->close();
free(png);
_iLastError = PNG_SUCCESS;
return 1;
}
_iLastError = png->getLastError();
free(png);
return 0;
} /* getPNGInfo() */
#ifndef ARDUINO_ARCH_NRF52
int PNGDisplay::getPNGInfo_LFS(int *width, int *height, int *bpp, const char *fname)
{
PNG *png;
int rc;
uint32_t *png_info;
if (!LittleFS.begin(false)) {
return 0;
}
if (!width || !height || !bpp || !fname) return 0;
png = (PNG *)malloc(sizeof(PNG));
if (!png) {
_iLastError = PNG_MEM_ERROR;
return 0;
}
rc = png->open(fname, pngOpenLFS, pngClose, pngRead, pngSeek, PNGDraw);
if (rc == PNG_SUCCESS) {
*width = png->getWidth();
*height = png->getHeight();
*bpp = png->getBpp();
png->close();
free(png);
_iLastError = PNG_SUCCESS;
return 1;
}
_iLastError = png->getLastError();
free(png);
return 0;
} /* getPNGInfo_LFS() */
#endif // !nRF52
#endif // __PNGDISPLAY_IMPL__

View File

@@ -49,13 +49,8 @@
/* Defines and variables */
#define PNG_FILE_BUF_SIZE 2048
// Number of bytes to reserve for current and previous lines
// Defaults to 320 32-bit pixels max width
// but can be overidden with a macro defined at compile time
#ifndef PNG_MAX_BUFFERED_PIXELS
#define PNG_MAX_BUFFERED_PIXELS ((320*4 + 1)*2)
#endif
#ifndef __PNGENC__
// Defaults to 640 32-bit pixels max width
#define PNG_MAX_BUFFERED_PIXELS (640*4 + 1)
// PNG filter type
enum {
PNG_FILTER_NONE=0,
@@ -80,6 +75,16 @@ enum {
PNG_PIXEL_GRAY_ALPHA=4,
PNG_PIXEL_TRUECOLOR_ALPHA=6
};
// RGB565 endianness
enum {
PNG_RGB565_LITTLE_ENDIAN = 0,
PNG_RGB565_BIG_ENDIAN
};
enum {
PNG_MEM_RAM=0,
PNG_MEM_FLASH
};
// Error codes returned by getLastError()
enum {
@@ -90,29 +95,7 @@ enum {
PNG_NO_BUFFER,
PNG_UNSUPPORTED_FEATURE,
PNG_INVALID_FILE,
PNG_TOO_BIG,
PNG_QUIT_EARLY
};
typedef struct png_file_tag
{
int32_t iPos; // current file position
int32_t iSize; // file size
uint8_t *pData; // memory file pointer
void * fHandle; // class pointer to File/SdFat or whatever you want
} PNGFILE;
#endif // !__PNGENC__
// RGB565 endianness
enum {
PNG_RGB565_LITTLE_ENDIAN = 0,
PNG_RGB565_BIG_ENDIAN
};
enum {
PNG_MEM_RAM=0,
PNG_MEM_FLASH
PNG_TOO_BIG
};
typedef struct png_draw_tag
@@ -129,11 +112,19 @@ typedef struct png_draw_tag
uint8_t *pPixels;
} PNGDRAW;
typedef struct png_file_tag
{
int32_t iPos; // current file position
int32_t iSize; // file size
uint8_t *pData; // memory file pointer
void * fHandle; // class pointer to File/SdFat or whatever you want
} PNGFILE;
// Callback function prototypes
typedef int32_t (PNG_READ_CALLBACK)(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen);
typedef int32_t (PNG_SEEK_CALLBACK)(PNGFILE *pFile, int32_t iPosition);
typedef void * (PNG_OPEN_CALLBACK)(const char *szFilename, int32_t *pFileSize);
typedef int (PNG_DRAW_CALLBACK)(PNGDRAW *);
typedef void (PNG_DRAW_CALLBACK)(PNGDRAW *);
typedef void (PNG_CLOSE_CALLBACK)(void *pHandle);
//
@@ -156,9 +147,9 @@ typedef struct png_image_tag
PNG_DRAW_CALLBACK *pfnDraw;
PNG_CLOSE_CALLBACK *pfnClose;
PNGFILE PNGFile;
uint8_t ucZLIB[32768 + sizeof(struct inflate_state)]; // put this here to avoid needing malloc/free
uint8_t ucZLIB[32768 + sizeof(inflate_state)]; // put this here to avoid needing malloc/free
uint8_t ucPalette[1024];
uint8_t ucPixels[PNG_MAX_BUFFERED_PIXELS];
uint8_t ucPixels[PNG_MAX_BUFFERED_PIXELS * 2];
uint8_t ucFileBuf[PNG_FILE_BUF_SIZE]; // holds temp file data
} PNGIMAGE;
@@ -195,8 +186,8 @@ class PNG
};
#else
#define PNG_STATIC
int PNG_openRAM(PNGIMAGE *pPNG, uint8_t *pData, int iDataSize, PNG_DRAW_CALLBACK *pfnDraw);
int PNG_openFile(PNGIMAGE *pPNG, const char *szFilename, PNG_DRAW_CALLBACK *pfnDraw);
int PNG_openRAM(PNGIMAGE *pPNG, uint8_t *pData, int iDataSize);
int PNG_openFile(PNGIMAGE *pPNG, const char *szFilename);
int PNG_getWidth(PNGIMAGE *pPNG);
int PNG_getHeight(PNGIMAGE *pPNG);
int PNG_decode(PNGIMAGE *pPNG, void *pUser, int iOptions);

View File

@@ -7,9 +7,6 @@
#include "zutil.h"
#ifndef __ADLER32_C__
#define __ADLER32_C__
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#define BASE 65521U /* largest prime smaller than 65536 */
@@ -63,7 +60,10 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#endif
/* ========================================================================= */
uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len)
uLong ZEXPORT adler32_z(adler, buf, len)
uLong adler;
const Bytef *buf;
z_size_t len;
{
unsigned long sum2;
unsigned n;
@@ -131,13 +131,19 @@ uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len)
}
/* ========================================================================= */
uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len)
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
{
return adler32_z(adler, buf, len);
}
/* ========================================================================= */
local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2)
local uLong adler32_combine_(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off64_t len2;
{
unsigned long sum1;
unsigned long sum2;
@@ -163,14 +169,18 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2)
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2)
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off_t len2;
{
return adler32_combine_(adler1, adler2, len2);
}
uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2)
uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off64_t len2;
{
return adler32_combine_(adler1, adler2, len2);
}
#endif // __ADLER32_C__

View File

@@ -185,7 +185,7 @@ local void write_table(out, table)
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
const z_crc_t FAR * ZEXPORT get_crc_table(void)
const z_crc_t FAR * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
@@ -199,7 +199,10 @@ const z_crc_t FAR * ZEXPORT get_crc_table(void)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
/* ========================================================================= */
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, z_size_t len)
unsigned long ZEXPORT crc32_z(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
z_size_t len;
{
if (buf == Z_NULL) return 0UL;
@@ -231,7 +234,10 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, z
}
/* ========================================================================= */
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
unsigned long ZEXPORT crc32(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
uInt len;
{
return crc32_z(crc, buf, len);
}
@@ -257,7 +263,10 @@ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uIn
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
/* ========================================================================= */
local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, z_size_t len)
local unsigned long crc32_little(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
z_size_t len;
{
register z_crc_t c;
register const z_crc_t FAR *buf4;
@@ -294,7 +303,10 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
/* ========================================================================= */
local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, z_size_t len)
local unsigned long crc32_big(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
z_size_t len;
{
register z_crc_t c;
register const z_crc_t FAR *buf4;
@@ -329,7 +341,9 @@ local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, z
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
/* ========================================================================= */
local unsigned long gf2_matrix_times(unsigned long *mat, unsigned long vec)
local unsigned long gf2_matrix_times(mat, vec)
unsigned long *mat;
unsigned long vec;
{
unsigned long sum;
@@ -344,7 +358,9 @@ local unsigned long gf2_matrix_times(unsigned long *mat, unsigned long vec)
}
/* ========================================================================= */
local void gf2_matrix_square(unsigned long *square, unsigned long *mat)
local void gf2_matrix_square(square, mat)
unsigned long *square;
unsigned long *mat;
{
int n;
@@ -353,7 +369,10 @@ local void gf2_matrix_square(unsigned long *square, unsigned long *mat)
}
/* ========================================================================= */
local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2)
local uLong crc32_combine_(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off64_t len2;
{
int n;
unsigned long row;
@@ -406,12 +425,18 @@ local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2)
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2)
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off_t len2;
{
return crc32_combine_(crc1, crc2, len2);
}
uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2)
uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off64_t len2;
{
return crc32_combine_(crc1, crc2, len2);
}

View File

@@ -16,7 +16,7 @@
#include "inffast.h"
/* function prototypes */
local void fixedtables (struct inflate_state FAR *state);
local void fixedtables OF((struct inflate_state FAR *state));
/*
strm provides memory allocation functions in zalloc and zfree, or
@@ -25,7 +25,12 @@ local void fixedtables (struct inflate_state FAR *state);
windowBits is in the range 8..15, and window is a user-supplied
window and output buffer that is 2**windowBits bytes.
*/
int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)
int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
z_streamp strm;
int windowBits;
unsigned char FAR *window;
const char *version;
int stream_size;
{
struct inflate_state FAR *state;
@@ -74,7 +79,8 @@ int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *
used for threaded applications, since the rewriting of the tables and virgin
may not be thread-safe.
*/
local void fixedtables(struct inflate_state FAR *state)
local void fixedtables(state)
struct inflate_state FAR *state;
{
#ifdef BUILDFIXED
static int virgin = 1;
@@ -241,7 +247,12 @@ local void fixedtables(struct inflate_state FAR *state)
inflateBack() can also return Z_STREAM_ERROR if the input parameters
are not correct, i.e. strm is Z_NULL or the state was not initialized.
*/
int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)
int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
z_streamp strm;
in_func in;
void FAR *in_desc;
out_func out;
void FAR *out_desc;
{
struct inflate_state FAR *state;
z_const unsigned char FAR *next; /* next input */
@@ -617,7 +628,8 @@ int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func
return ret;
}
int ZEXPORT inflateBackEnd(z_streamp strm)
int ZEXPORT inflateBackEnd(strm)
z_streamp strm;
{
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;

View File

@@ -8,13 +8,24 @@
#include "inflate.h"
#include "inffast.h"
#if (INTPTR_MAX == INT64_MAX) || defined(HAL_ESP32_HAL_H_) || defined(TEENSYDUINO) || defined(ARM_MATH_CM4) || defined(ARM_MATH_CM7)
#define ALLOWS_UNALIGNED
#endif
#if INTPTR_MAX == INT64_MAX
#define REGISTER_WIDTH 64
typedef uint64_t BIGUINT;
typedef uint32_t SMALLUINT;
#else
#define REGISTER_WIDTH 32
typedef uint32_t BIGUINT;
typedef uint16_t SMALLUINT;
#endif // native register size
#ifdef ASMINF
# pragma message("Assembler code may have bugs -- use at your own risk")
#else
#if ((INTPTR_MAX == INT64_MAX) || defined(HAL_ESP32_HAL_H_) || defined(TEENSYDUINO) || defined(ARM_MATH_CM4) || defined(ARM_MATH_CM7)) && !defined(ARDUINO_ARCH_RP2040)
#define ALLOWS_UNALIGNED
#endif
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
@@ -50,7 +61,10 @@
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
void ZLIB_INTERNAL inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
z_const unsigned char FAR *in; /* local strm->next_in */
z_const unsigned char FAR *last; /* have enough input while in < last */
@@ -64,13 +78,14 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
BIGUINT hold, tmpbits; /* local strm->hold */
// unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
code const *here; /* retrieved table entry */
code here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
@@ -101,60 +116,84 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
if (bits < 15) {
if (bits < (REGISTER_WIDTH/2)) { // helps on 32 and 64-bit CPUs
#ifdef ALLOWS_UNALIGNED
tmpbits = *(SMALLUINT *)in;
hold |= (BIGUINT)(tmpbits << bits);
in += sizeof(SMALLUINT);
bits += (REGISTER_WIDTH / 2);
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = lcode + (hold & lmask);
here = lcode[hold & lmask];
dolen:
op = (unsigned)(here->bits);
op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
op = (unsigned)(here->op);
op = (unsigned)(here.op);
if (op == 0) { /* literal */
Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here->val));
*out++ = (unsigned char)(here->val);
"inflate: literal 0x%02x\n", here.val));
*out++ = (unsigned char)(here.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(here->val);
len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
#if REGISTER_WIDTH == 32
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
hold += (uint32_t)(*in++) << bits;
bits += 8;
}
#endif
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
if (bits < (REGISTER_WIDTH/2)) { // helps on 32 and 64-bit CPUs
#ifdef UNALIGNED_OK
tmpbits = *(SMALLUINT *)in;
hold |= (BIGUINT)(tmpbits << bits);
in += sizeof(SMALLUINT);
bits += (REGISTER_WIDTH / 2);
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
#endif
}
here = dcode + (hold & dmask);
here = dcode[hold & dmask];
dodist:
op = (unsigned)(here->bits);
op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
op = (unsigned)(here->op);
op = (unsigned)(here.op);
if (op & 16) { /* distance base */
dist = (unsigned)(here->val);
dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
#if REGISTER_WIDTH == 32
if (bits < op) {
#ifdef ALLOWS_UNALIGNED
hold |= (*(uint16_t *)in << bits);
bits += 16;
in += 2;
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
if (bits < op) { // this is NEVER true
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
#endif // ALLOWS_UNALIGNED
}
#endif // 32-bit CPU
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
@@ -267,7 +306,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
{
uint8_t *pEnd = out+len;
int overlap = (int)(intptr_t)(out-from);
if (overlap > 4) { // overlap of source/dest won't impede normal copy
if (overlap >= 4) { // overlap of source/dest won't impede normal copy
while (out < pEnd) {
*(uint32_t *)out = *(uint32_t *)from;
out += 4;
@@ -275,15 +314,10 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
}
// correct for possible overshoot of destination ptr
out = pEnd;
} else if (overlap == 1 || overlap == 4) { // copy 1/4-byte patterns
uint32_t pattern;
if (overlap == 1) {
pattern = *from;
pattern = pattern | (pattern << 8);
pattern = pattern | (pattern << 16);
} else {
pattern = *(uint32_t *)from;
}
} else if (overlap == 1) { // copy 1-byte pattern
uint32_t pattern = *from;
pattern = pattern | (pattern << 8);
pattern = pattern | (pattern << 16);
while (out < pEnd) {
*(uint32_t *)out = pattern;
out += 4;
@@ -311,7 +345,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
here = dcode + here->val + (hold & ((1U << op) - 1));
here = dcode[here.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
@@ -321,7 +355,7 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
here = lcode + here->val + (hold & ((1U << op) - 1));
here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
@@ -337,10 +371,10 @@ void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
// len = bits >> 3;
// in -= len;
// bits -= len << 3;
// hold &= (1 << bits) - 1;
/* update state and return */
strm->next_in = in;

File diff suppressed because it is too large Load Diff

View File

@@ -13,47 +13,43 @@
the crc code when it is not needed. For shared libraries, gzip decoding
should be left enabled. */
#ifndef NO_GZIP
#define GUNZIP
# define GUNZIP
#endif
#ifndef __INFLATE_H__
#define __INFLATE_H__
/* Possible inflate modes between inflate() calls */
typedef enum
{
PNG_HEADER = 16180, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY_, /* i/o: same as COPY below, but only first time in */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN_, /* i: same as LEN below, but only first time in */
LEN, /* i: waiting for length/lit/eob code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
typedef enum {
HEAD = 16180, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */
EXLEN, /* i: waiting for extra length (gzip) */
EXTRA, /* i: waiting for extra bytes (gzip) */
NAME, /* i: waiting for end of file name (gzip) */
COMMENT, /* i: waiting for end of comment (gzip) */
HCRC, /* i: waiting for header crc (gzip) */
DICTID, /* i: waiting for dictionary check value */
DICT, /* waiting for inflateSetDictionary() call */
TYPE, /* i: waiting for type bits, including last-flag bit */
TYPEDO, /* i: same, but skip check to exit inflate on new block */
STORED, /* i: waiting for stored size (length and complement) */
COPY_, /* i/o: same as COPY below, but only first time in */
COPY, /* i/o: waiting for input or output to copy stored block */
TABLE, /* i: waiting for dynamic block table lengths */
LENLENS, /* i: waiting for code length code lengths */
CODELENS, /* i: waiting for length/lit and distance code lengths */
LEN_, /* i: same as LEN below, but only first time in */
LEN, /* i: waiting for length/lit/eob code */
LENEXT, /* i: waiting for length extra bits */
DIST, /* i: waiting for distance code */
DISTEXT, /* i: waiting for distance extra bits */
MATCH, /* o: waiting for output space to copy string */
LIT, /* o: waiting for output space to write literal */
CHECK, /* i: waiting for 32-bit check value */
LENGTH, /* i: waiting for 32-bit length (gzip) */
DONE, /* finished check, done -- remain here until reset */
BAD, /* got a data error -- remain here until reset */
MEM, /* got an inflate() memory error -- remain here until reset */
SYNC /* looking for synchronization bytes to restart inflate() */
} inflate_mode;
/*
@@ -62,7 +58,7 @@ typedef enum
(most modes can go to BAD or MEM on error -- not shown for clarity)
Process header:
PNG_HEADER -> (gzip) or (zlib) or (raw)
HEAD -> (gzip) or (zlib) or (raw)
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
HCRC -> TYPE
(zlib) -> DICTID or TYPE
@@ -83,50 +79,48 @@ typedef enum
/* State maintained between inflate() calls -- approximately 7K bytes, not
including the allocated sliding window, which is up to 32K bytes. */
struct inflate_state
{
z_streamp strm; /* pointer back to this zlib stream */
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
bit 2 true to validate check value */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
uint64_t hold; /* input bit accumulator */
// unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
int sane; /* if false, allow invalid distance too far */
int back; /* bits back of last unprocessed length/lit */
unsigned was; /* initial length of match */
struct inflate_state {
z_streamp strm; /* pointer back to this zlib stream */
inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
bit 2 true to validate check value */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
/* sliding window */
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
uint64_t hold; /* input bit accumulator */
// unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in "in" */
/* for string and stored block copying */
unsigned length; /* literal or length of data to copy */
unsigned offset; /* distance back to copy string from */
/* for table and code decoding */
unsigned extra; /* extra bits needed */
/* fixed and dynamic code tables */
code const FAR *lencode; /* starting table for length/literal codes */
code const FAR *distcode; /* starting table for distance codes */
unsigned lenbits; /* index bits for lencode */
unsigned distbits; /* index bits for distcode */
/* dynamic table building */
unsigned ncode; /* number of code length code lengths */
unsigned nlen; /* number of length code lengths */
unsigned ndist; /* number of distance code lengths */
unsigned have; /* number of code lengths in lens[] */
code FAR *next; /* next available space in codes[] */
unsigned short lens[320]; /* temporary storage for code lengths */
unsigned short work[288]; /* work area for code table building */
code codes[ENOUGH]; /* space for code tables */
int sane; /* if false, allow invalid distance too far */
int back; /* bits back of last unprocessed length/lit */
unsigned was; /* initial length of match */
};
#endif // __INFLATE_H__

View File

@@ -29,7 +29,13 @@ const char inflate_copyright[] =
table index bits. It will differ if the request is greater than the
longest code or if it is less than the shortest code.
*/
int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)
int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
codetype type;
unsigned short FAR *lens;
unsigned codes;
code FAR * FAR *table;
unsigned FAR *bits;
unsigned short FAR *work;
{
unsigned len; /* a code's length in bits */
unsigned sym; /* index of code symbols */

View File

@@ -7,8 +7,6 @@
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
#ifndef __INFTREES_H__
#define __INFTREES_H__
/* Structure for decoding tables. Each entry provides either the
information needed to do the operation requested by the code that
@@ -62,4 +60,3 @@ typedef enum {
int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work));
#endif // __INFTREES_H__

View File

@@ -60,41 +60,21 @@ static const uint16_t usGrayTo565[] = {0x0000,0x0000,0x0000,0x0000,0x0020,0x0020
// C interface
//
#ifndef __cplusplus
// Forward references
PNG_STATIC int32_t readFLASH(PNGFILE *pFile, uint8_t *pBuf, int32_t iLen);
PNG_STATIC int32_t seekMem(PNGFILE *pFile, int32_t iPosition);
PNG_STATIC int PNGInit(PNGIMAGE *pPNG);
// C API
int PNG_openRAM(PNGIMAGE *pPNG, uint8_t *pData, int iDataSize, PNG_DRAW_CALLBACK *pfnDraw)
{
pPNG->iError = PNG_SUCCESS;
pPNG->pfnRead = readFLASH;
pPNG->pfnRead = readMem;
pPNG->pfnSeek = seekMem;
pPNG->pfnDraw = pfnDraw;
pPNG->pfnOpen = NULL;
pPNG->pfnClose = NULL;
pPNG->PNGFile.iSize = iDataSize;
pPNG->PNGFile.pData = pData;
pPNG->PNGFile.iPos = 0;
return PNGInit(pPNG);
} /* PNG_openRAM() */
#ifdef __LINUX__
int32_t readFile(PNGFILE *handle, uint8_t *buffer, int32_t length) {
if (!handle->fHandle) return 0;
return (int32_t)fread(buffer, 1, length, (FILE *)handle->fHandle);
}
int32_t seekFile(PNGFILE *handle, int32_t position) {
if (!handle->fHandle) return 0;
return fseek((FILE *)handle->fHandle, position, SEEK_SET);
}
void closeFile(void *handle) {
if (handle) {
FILE *f = (FILE *)handle;
fclose(f);
}
}
int PNG_openFile(PNGIMAGE *pPNG, const char *szFilename, PNG_DRAW_CALLBACK *pfnDraw)
{
pPNG->iError = PNG_SUCCESS;
@@ -239,15 +219,6 @@ PNG_STATIC uint8_t PNGMakeMask(PNGDRAW *pDraw, uint8_t *pMask, uint8_t ucThresho
} // switch on pixel type
return cHasOpaque; // let the caller know if any pixels are opaque
} /* PNGMakeMask() */
#ifdef ARDUINO_ESP32S3_DEV
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void s3_rgb565(uint8_t *pSrc, uint8_t *pDest, int iCount, bool bBigEndian);
#ifdef __cplusplus
};
#endif
#endif
//
// Convert a line of native PNG pixels into RGB565
// handles all standard pixel types
@@ -257,39 +228,18 @@ PNG_STATIC void PNGRGB565(PNGDRAW *pDraw, uint16_t *pPixels, int iEndiannes, uin
{
int x, j;
uint16_t usPixel, *pDest = pPixels;
uint8_t c=0, a, *pPal, *s = pDraw->pPixels;
uint8_t c, a, *pPal, *s = pDraw->pPixels;
switch (pDraw->iPixelType) {
case PNG_PIXEL_GRAY_ALPHA:
if (u32Bkgd != 0xffffffff) {
// gray level of background color choice
uint8_t u8BG = (uint8_t)(((u32Bkgd & 0xff) + ((u32Bkgd >> 7) & 0x1fe) + ((u32Bkgd >> 16) & 0xff)) / 4);
uint16_t usBG = usGrayTo565[u8BG];
for (x=0; x<pDraw->iWidth; x++) {
c = *s++; // gray level
a = *s++;
if (a == 0) {
usPixel = usBG;
} else if (a == 255) { // fully opaque
usPixel = usGrayTo565[c];
} else { // mix the colors
usPixel = (c * a) + (u8BG * (255-a));
usPixel = usGrayTo565[(usPixel >> 8)];
}
if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
usPixel = __builtin_bswap16(usPixel);
*pDest++ = usPixel;
} // for x
} else {
for (x=0; x<pDraw->iWidth; x++) {
c = *s++; // gray level
a = *s++;
j = (a * c) >> 8; // multiply by the alpha
usPixel = usGrayTo565[j];
if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
usPixel = __builtin_bswap16(usPixel);
*pDest++ = usPixel;
}
for (x=0; x<pDraw->iWidth; x++) {
c = *s++; // gray level
a = *s++;
j = (a * c) >> 8; // multiply by the alpha
usPixel = usGrayTo565[j];
if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
usPixel = __builtin_bswap16(usPixel);
*pDest++ = usPixel;
}
break;
case PNG_PIXEL_GRAYSCALE:
@@ -387,49 +337,18 @@ PNG_STATIC void PNGRGB565(PNGDRAW *pDraw, uint16_t *pPixels, int iEndiannes, uin
switch (pDraw->iBpp) {
case 8: // 8-bit palette also supports palette alpha
if (pDraw->iHasAlpha) { // use the alpha to modify the palette
if (u32Bkgd != 0xffffffff) { // user wants to blend it with a background color
uint32_t b_r, b_g, b_b;
b_r = u32Bkgd & 0xff; b_g = (u32Bkgd & 0xff00) >> 8;
b_b = (u32Bkgd >> 16) & 0xff;
uint16_t u16Clr = (u32Bkgd & 0xf8) << 8;
u16Clr |= ((u32Bkgd & 0xfc00) >> 5);
u16Clr |= ((u32Bkgd & 0xf80000) >> 19);
for (x=0; x<pDraw->iWidth; x++) {
int a;
c = *s++;
a = pDraw->pPalette[768+c]; // get alpha
if (a == 0) { // pure BGColor
usPixel = u16Clr;
} else if (a == 255) { // opaque
pPal = &pDraw->pPalette[c * 3];
usPixel = ((pPal[2] * a) >> 11); // blue
usPixel |= (((pPal[1] * a) >> 10) << 5); // green
usPixel |= (((pPal[0] * a) >> 11) << 11); // red
} else { // need to mix the bg & fg colors
pPal = &pDraw->pPalette[c * 3];
usPixel = ((((pPal[2] * a) + (b_b * (255-a)))) >> 11); // blue
usPixel |= ((((pPal[1] * a) + (b_g * (255-a)))>> 10) << 5); // green
usPixel |= ((((pPal[0] * a) + (b_r * (255-a)))>> 11) << 11); // red
} // need to mix with alpha
if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
usPixel = __builtin_bswap16(usPixel);
*pDest++ = usPixel;
} // for x
} else { // alpha 0 = black
for (x=0; x<pDraw->iWidth; x++) {
int a;
c = *s++;
a = pDraw->pPalette[768+c]; // get alpha
pPal = &pDraw->pPalette[c * 3];
usPixel = ((pPal[2] * a) >> 11); // blue
usPixel |= (((pPal[1] * a) >> 10) << 5); // green
usPixel |= (((pPal[0] * a) >> 11) << 11); // red
if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
usPixel = __builtin_bswap16(usPixel);
*pDest++ = usPixel;
} // for x
}
for (x=0; x<pDraw->iWidth; x++) {
int a;
c = *s++;
a = pDraw->pPalette[768+c]; // get alpha
pPal = &pDraw->pPalette[c * 3];
usPixel = ((pPal[2] * a) >> 11); // blue
usPixel |= (((pPal[1] * a) >> 10) << 5); // green
usPixel |= (((pPal[0] * a) >> 11) << 11); // red
if (iEndiannes == PNG_RGB565_BIG_ENDIAN)
usPixel = __builtin_bswap16(usPixel);
*pDest++ = usPixel;
} // for x
} else {
for (x=0; x<pDraw->iWidth; x++) {
c = *s++;
@@ -525,9 +444,6 @@ PNG_STATIC void PNGRGB565(PNGDRAW *pDraw, uint16_t *pPixels, int iEndiannes, uin
s += 4; // skip alpha
}
} else { // ignore alpha
#ifdef ARDUINO_ESP32S3_DEV
s3_rgb565(s, (uint8_t *)pDest, pDraw->iWidth, (iEndiannes == PNG_RGB565_BIG_ENDIAN));
#else
for (x=0; x<pDraw->iWidth; x++) {
usPixel = (s[2] >> 3); // blue
usPixel |= ((s[1] >> 2) << 5); // green
@@ -537,7 +453,6 @@ PNG_STATIC void PNGRGB565(PNGDRAW *pDraw, uint16_t *pPixels, int iEndiannes, uin
*pDest++ = usPixel;
s += 4; // skip alpha
}
#endif
}
break;
}
@@ -591,8 +506,8 @@ PNG_STATIC int PNGParseInfo(PNGIMAGE *pPage)
pPage->iHasAlpha = pPage->iInterlaced = 0;
// Read a few bytes to just parse the size/pixel info
iBytesRead = (*pPage->pfnRead)(&pPage->PNGFile, s, 33);
if (iBytesRead < 33) { // a PNG file this tiny? probably bad
iBytesRead = (*pPage->pfnRead)(&pPage->PNGFile, s, 32);
if (iBytesRead < 32) { // a PNG file this tiny? probably bad
pPage->iError = PNG_INVALID_FILE;
return pPage->iError;
}
@@ -602,17 +517,6 @@ PNG_STATIC int PNGParseInfo(PNGIMAGE *pPage)
return pPage->iError;
}
if (MOTOLONG(&s[12]) == 0x49484452/*'IHDR'*/) {
int len = MOTOLONG(&s[8]);
if (len != 13) {
pPage->iError = PNG_INVALID_FILE;
return pPage->iError;
}
int crc = (int)crc32(0, &s[12], len+4);
int hdrcrc = MOTOLONG(&s[16+len]);
if (len != 13 || crc != hdrcrc) {
pPage->iError = PNG_INVALID_FILE;
return pPage->iError;
}
pPage->iWidth = MOTOLONG(&s[16]);
pPage->iHeight = MOTOLONG(&s[20]);
pPage->ucBpp = s[24]; // bits per pixel
@@ -725,7 +629,7 @@ PNG_STATIC void DeFilter(uint8_t *pCurr, uint8_t *pPrev, int iWidth, int iPitch)
b = *pPrev++;
p = b - c;
pc = a - c;
// assume no native ABS() instruction
// asume no native ABS() instruction
pa = p < 0 ? -p : p;
pb = pc < 0 ? -pc : pc;
pc = (p + pc) < 0 ? -(p + pc) : p + pc;
@@ -773,13 +677,8 @@ PNG_STATIC int DecodePNG(PNGIMAGE *pPage, void *pUser, int iOptions)
return 0;
}
// Use internal buffer to maintain the current and previous lines
y = (int)(intptr_t)&pPage->ucPixels[0];
y &= 15; // make sure we're 16-byte aligned, -1 for filter byte
y += (15 - y);
pCurr = &pPage->ucPixels[y]; // so that the pixels are 16-byte aligned
y += pPage->iPitch + 1; // both lines are 16-byte (minus 1)
y += (15 - (y & 15));
pPrev = &pPage->ucPixels[y];
pCurr = pPage->ucPixels;
pPrev = &pPage->ucPixels[pPage->iPitch+1];
pPage->iError = PNG_SUCCESS;
// Start decoding the image
bDone = FALSE;
@@ -792,7 +691,7 @@ PNG_STATIC int DecodePNG(PNGIMAGE *pPage, void *pUser, int iOptions)
// Insert the memory pointer here to avoid having to use malloc() inside zlib
state = (struct inflate_state FAR *)pPage->ucZLIB;
d_stream.state = (struct internal_state FAR *)state;
state->window = &pPage->ucZLIB[sizeof(struct inflate_state)]; // point to 32k dictionary buffer
state->window = &pPage->ucZLIB[sizeof(inflate_state)]; // point to 32k dictionary buffer
err = inflateInit(&d_stream);
#ifdef FUTURE
// if (inpage->cCompression == PIL_COMP_IPHONE_FLATE)
@@ -803,27 +702,18 @@ PNG_STATIC int DecodePNG(PNGIMAGE *pPage, void *pUser, int iOptions)
iFileOffset = 8; // skip PNG file signature
iOffset = 0; // internal buffer offset starts at 0
iBytesRead = 0; // We haven't read yet anything
// Read some data to start
(*pPage->pfnSeek)(&pPage->PNGFile, iFileOffset);
iBytesRead = (*pPage->pfnRead)(&pPage->PNGFile, s, PNG_FILE_BUF_SIZE);
iFileOffset += iBytesRead;
y = 0;
d_stream.avail_out = 0;
d_stream.next_out = pPage->pImage;
// continue until fully decoded
// parse the markers until the next data block
while (!bDone && y < pPage->iHeight)
while (y < pPage->iHeight) { // continue until fully decoded
// parse the markers until the next data block
while (!bDone)
{
if (iOffset > iBytesRead-8) { // need to read more data
iFileOffset += (iOffset - iBytesRead);
(*pPage->pfnSeek)(&pPage->PNGFile, iFileOffset);
iBytesRead = (*pPage->pfnRead)(&pPage->PNGFile, s, PNG_FILE_BUF_SIZE);
if (iBytesRead < 8) {
pPage->iError = PNG_DECODE_ERROR;
return 1;
}
iFileOffset += iBytesRead;
iOffset = 0;
}
iLen = MOTOLONG(&s[iOffset]); // chunk length
if (iLen < 0 || iLen + (iFileOffset - iBytesRead) > pPage->PNGFile.iSize) // invalid data
{
@@ -931,10 +821,7 @@ PNG_STATIC int DecodePNG(PNGIMAGE *pPage, void *pUser, int iOptions)
pngd.iHasAlpha = pPage->iHasAlpha;
pngd.iBpp = pPage->ucBpp;
pngd.y = y;
if (!(*pPage->pfnDraw)(&pngd)) { // user code returned 0 from PNGDraw
pPage->iError = PNG_QUIT_EARLY;
return pPage->iError;
}
(*pPage->pfnDraw)(&pngd);
} else {
// copy to destination bitmap
memcpy(&pPage->pImage[y * pPage->iPitch], &pCurr[1], pPage->iPitch);
@@ -959,14 +846,17 @@ PNG_STATIC int DecodePNG(PNGIMAGE *pPage, void *pUser, int iOptions)
y |= 0; // need more data
}
} // while (iLen)
if (iBytesRead) { // data remaining in buffer
// Restore iBytesRead to be total ucFileBuf bytes, not remainder
iBytesRead += iOffset;
} else {
// We consumed everything, so move the pointer to the zero.
// We haven't read CRC for the block, but it doesn't matter as
// pfnSeek will move past it to the next chunk.
iOffset = 0;
if (y != pPage->iHeight && iFileOffset < pPage->PNGFile.iSize) {
// need to read more IDAT chunks
if (iBytesRead) { // data remaining in buffer
// move the data down
memmove(pPage->ucFileBuf, &pPage->ucFileBuf[iOffset], iBytesRead);
iOffset = 0;
} else {
iBytesRead = (*pPage->pfnRead)(&pPage->PNGFile, pPage->ucFileBuf, PNG_FILE_BUF_SIZE);
iFileOffset += iBytesRead;
iOffset = 0;
}
}
break;
// case 0x69545874: //'iTXt'
@@ -999,6 +889,14 @@ PNG_STATIC int DecodePNG(PNGIMAGE *pPage, void *pUser, int iOptions)
#endif
} // switch
iOffset += (iLen + 4); // skip data + CRC
if (iOffset > iBytesRead-8) { // need to read more data
iFileOffset += (iOffset - iBytesRead);
(*pPage->pfnSeek)(&pPage->PNGFile, iFileOffset);
iBytesRead = (*pPage->pfnRead)(&pPage->PNGFile, s, PNG_FILE_BUF_SIZE);
iFileOffset += iBytesRead;
iOffset = 0;
}
} // while !bDone
} // while y < height
err = inflateEnd(&d_stream);
return pPage->iError;

View File

@@ -1,63 +0,0 @@
//
// ESP32-S3 SIMD optimized code
// Written by Larry Bank
// Copyright (c) 2024 BitBank Software, Inc.
// written April 17, 2024
//
#ifdef ARDUINO_ARCH_ESP32
#include "dsps_fft2r_platform.h"
#if (dsps_fft2r_sc16_aes3_enabled == 1)
.text
.align 4
// Convert N pixels of RGBA (RGB8888) to RGB565
// A2 A3 A4 A5
// Call as void s3_rgb565(uint8_t *pSrc, uint8_t *pDest, int iCount, bool bBigEndian);
.global s3_rgb565
.type s3_rgb565,@function
s3_rgb565:
# no idea what this frequency keyword does
# .frequency 1.000 0.000
entry a1,16
addi.n a4,a4,7 # process pixels in groups of 8
movi.n a6,-8
and a4,a4,a6
.top_rgb565:
ee.vld.128.ip q0,a2,16 # load 4 pixels into Q0
ee.vld.128.ip q1,a2,16 # load another 4 pixels into Q1
ee.xorq q4,q4,q4 # destination reg set to 0s
ee.vcmp.eq.s16 q2,q2,q2 # create FFs
ee.vunzip.16 q0,q1 # interleave RG and BA from Q0/Q1
ee.vsubs.s16 q3,q4,q2 # make 16-bit 1's in q3
movi.n a6,10 # load the shift register with 10 (for green)
wsr.sar a6 # put it in the SAR (shift amount register)
ee.vmul.u16 q5,q0,q3 # shift green into lower 6 bits of q5
movi.n a6,3 # shift value 3 for red and blue
wsr.sar a6
ee.vmul.s16 q6,q0,q3 # shift red into lower 5 bits of q6
ee.vmul.s16 q7,q1,q3 # shift blue into lower 5 bits of q7
movi.n a6,5
wsr.sar a6 # set shift to 5
ee.vsl.32 q4,q3 # q4 = 0x00200020...
ee.vsubs.s16 q4,q4,q3 # Now q4 has the r/b mask of 0x001f001f...
ee.andq q6,q4,q6 # mask off 5 bits of red
ee.andq q7,q4,q7 # mask off 5 bits of blue
ee.vsl.32 q5,q5 # shift green left 5
movi.n a6,11
wsr.sar a6 # set shift to 11
ee.vsl.32 q6,q6 # shift red left 11
ee.orq q6,q6,q5 # combine red+green
ee.orq q6,q6,q7 # combine rg with b
mv.qr q5,q6 # in case we're generating little endian output
beqi a5,0,.rgb565_out # RGB565 little endian?
ee.vunzip.8 q6,q5 # swap the byte order to be big-endian
ee.vzip.8 q5,q6
.rgb565_out:
ee.vst.128.ip q5,a3,16 # store 8 RGB565 pixels
addi.n a4,a4,-8
bnez.n a4,.top_rgb565
retw.n
#endif // dsps_fft2r_sc16_aes3_enabled
#endif // ESP32

View File

@@ -8,10 +8,6 @@
#ifndef ZCONF_H
#define ZCONF_H
#ifdef __GNUC__
#pragma GCC optimize("O2")
#endif
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.

View File

@@ -24,12 +24,12 @@ z_const char * const z_errmsg[10] = {
};
const char * ZEXPORT zlibVersion(void)
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
uLong ZEXPORT zlibCompileFlags(void)
uLong ZEXPORT zlibCompileFlags()
{
uLong flags;
@@ -119,7 +119,8 @@ uLong ZEXPORT zlibCompileFlags(void)
# endif
int ZLIB_INTERNAL z_verbose = verbose;
void ZLIB_INTERNAL z_error (char * m)
void ZLIB_INTERNAL z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
exit(1);
@@ -129,7 +130,8 @@ void ZLIB_INTERNAL z_error (char * m)
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(int err)
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
@@ -300,7 +302,10 @@ extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
(void)opaque;
// return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
@@ -308,7 +313,9 @@ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
return Z_NULL; // DEBUG - no longer used
}
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
void ZLIB_INTERNAL zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
(void)opaque;
// free(ptr); // DEBUG - no longer used

View File

@@ -24,7 +24,6 @@
#if defined(STDC) && !defined(Z_SOLO)
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
# include <stddef.h>
# include <stdint.h>
# endif
# include <string.h>
# include <stdlib.h>
@@ -160,7 +159,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define OS_CODE 18
#endif
#if defined( __APPLE__ ) && !(defined(MACOS) || defined(TARGET_OS_MAC))
#ifdef __APPLE__
# define OS_CODE 19
#endif