convert project from libpng to libspng / https://libspng.org/

This commit is contained in:
dinkc64 2023-11-01 09:56:25 -04:00
parent 550c26bf87
commit fdc87360f6
10 changed files with 7752 additions and 412 deletions

View File

@ -1,4 +1,4 @@
alldir += burner burner/win32 dep/kaillera/client dep/libs/libpng dep/libs/lib7z dep/libs/zlib intf intf/video \
alldir += burner burner/win32 dep/kaillera/client dep/libs/libspng dep/libs/lib7z dep/libs/zlib intf intf/video \
intf/video/scalers intf/video/win32 intf/audio intf/audio/win32 intf/input intf/input/win32 intf/cd intf/cd/win32 \
intf/perfcount intf/perfcount/win32 dep/generated dep/libs/lua
@ -18,8 +18,7 @@ depobj += about.o bzip.o choose_monitor.o cona.o debugger.o drv.o d3dkmt_sync.o
adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o gzwrite.o infback.o inffast.o inflate.o inftrees.o \
trees.o uncompr.o zutil.o \
\
png.o pngerror.o pngget.o pngmem.o pngpread.o pngread.o pngrio.o pngrtran.o pngrutil.o pngset.o pngtrans.o pngwio.o \
pngwrite.o pngwtran.o pngwutil.o \
spng.o \
\
net.o \
\

View File

@ -52,10 +52,6 @@ typedef struct tagIMAGE {
#include "burner_qt.h"
#endif
#if defined (INCLUDE_LIB_PNGH)
#include "png.h"
#endif
// ---------------------------------------------------------------------------
// OS independent functionality

View File

@ -1,7 +1,8 @@
#include "burner.h"
#include "png.h"
#include "spng.h"
#define PNG_SIG_CHECK_BYTES (8)
#define PNG_SIG_LEN (8)
const UINT8 PNG_SIG[8] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
int bPngImageOrientation = 0;
@ -23,7 +24,7 @@ INT32 img_alloc(IMAGE* img)
img->rowbytes = ((DWORD)img->width * 24 + 31) / 32 * 4;
img->imgbytes = img->rowbytes * img->height;
img->rowptr = (BYTE**)malloc((size_t)img->height * sizeof(BYTE*));
img->rowptr = (BYTE**)malloc((size_t)img->height*4 * sizeof(BYTE*));
if (img->bmpbits == NULL) {
img->flags |= IMG_FREE;
@ -403,16 +404,21 @@ static INT32 img_process(IMAGE* img, UINT32 width, UINT32 height, INT32 /*preset
return 0;
}
int png_sig_check(UINT8 *sig)
{
return memcmp(sig, PNG_SIG, PNG_SIG_LEN);
}
bool PNGIsImage(FILE* fp)
{
if (fp) {
UINT8 pngsig[PNG_SIG_CHECK_BYTES];
UINT8 pngsig[PNG_SIG_LEN];
fseek(fp, 0, SEEK_SET);
fread(pngsig, 1, PNG_SIG_CHECK_BYTES, fp);
fread(pngsig, 1, PNG_SIG_LEN, fp);
fseek(fp, 0, SEEK_SET);
if (png_sig_cmp(pngsig, 0, PNG_SIG_CHECK_BYTES) == 0) {
if (png_sig_check(pngsig) == 0) {
return true;
}
}
@ -420,78 +426,105 @@ bool PNGIsImage(FILE* fp)
return false;
}
const char *color_type_str(int color_type)
{
switch(color_type)
{
case SPNG_COLOR_TYPE_GRAYSCALE: return "grayscale";
case SPNG_COLOR_TYPE_TRUECOLOR: return "truecolor";
case SPNG_COLOR_TYPE_INDEXED: return "indexed color";
case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA: return "grayscale with alpha";
case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA: return "truecolor with alpha";
default: return "(invalid)";
}
}
INT32 PNGLoad(IMAGE* img, FILE* fp, INT32 nPreset)
{
IMAGE temp_img;
png_uint_32 width = 0, height = 0;
INT32 bit_depth, color_type;
INT32 width = 0, height = 0;
int ret;
if (fp) {
// check signature
UINT8 pngsig[PNG_SIG_CHECK_BYTES];
fread(pngsig, 1, PNG_SIG_CHECK_BYTES, fp);
if (png_sig_cmp(pngsig, 0, PNG_SIG_CHECK_BYTES)) {
UINT8 pngsig[PNG_SIG_LEN];
fread(pngsig, 1, PNG_SIG_LEN, fp);
if (png_sig_check(pngsig)) {
return 1;
}
rewind(fp);
spng_ctx *ctx = NULL;
struct spng_ihdr ihdr;
ctx = spng_ctx_new(0);
spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
size_t limit = 1024 * 1024 * 64;
spng_set_chunk_limits(ctx, limit, limit);
spng_set_png_file(ctx, fp);
ret = spng_get_ihdr(ctx, &ihdr);
if (ret) {
spng_ctx_free(ctx);
return 1;
}
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
return 1;
}
#if 0
// debuggy stuff
const char *color_name = color_type_str(ihdr.color_type);
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return 1;
}
bprintf(0, _T("width: %u\n"
"height: %u\n"
"bit depth: %u\n"
"color type: %u - %S\n"),
ihdr.width, ihdr.height, ihdr.bit_depth, ihdr.color_type, color_name);
bprintf(0, _T("compression method: %u\n"
"filter method: %u\n"
"interlace method: %u\n"),
ihdr.compression_method, ihdr.filter_method, ihdr.interlace_method);
struct spng_plte plte = { 0 };
ret = spng_get_plte(ctx, &plte);
if (!ret) bprintf(0, _T("palette entries: %u\n"), plte.n_entries);
#endif
size_t image_size, image_width_bytes;
int fmt = (ihdr.color_type == SPNG_COLOR_TYPE_INDEXED) ? SPNG_FMT_RGB8 : SPNG_FMT_PNG;
ret = spng_decoded_image_size(ctx, fmt, &image_size);
ret = spng_decode_image(ctx, NULL, 0, fmt, SPNG_DECODE_PROGRESSIVE);
image_width_bytes = image_size / ihdr.height; // it's the width * 3 (1 for each RGB)
memset(&temp_img, 0, sizeof(IMAGE));
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, PNG_SIG_CHECK_BYTES);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
temp_img.width = ihdr.width;
temp_img.height = ihdr.height;
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return 1;
}
// Instruct libpng to convert the image to 24-bit RGB format
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(png_ptr);
}
if (bit_depth == 16) {
png_set_strip_16(png_ptr);
}
if (color_type & PNG_COLOR_MASK_ALPHA) {
png_set_strip_alpha(png_ptr);
}
temp_img.width = width;
temp_img.height = height;
// Initialize our img structure
if (img_alloc(&temp_img)) {
//longjmp(png_ptr->jmpbuf, 1);
png_jmpbuf(png_ptr);
}
// If bad things happen in libpng we need to do img_free(&temp_img) as well
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
img_free(&temp_img);
spng_ctx_free(ctx);
return 1;
}
// Read the .PNG image
png_set_bgr(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_read_image(png_ptr, temp_img.rowptr);
png_read_end(png_ptr, (png_infop)NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
struct spng_row_info row_info = {0};
do {
if ((ret = spng_get_row_info(ctx, &row_info)) != 0) break;
ret = spng_decode_row(ctx, temp_img.rowptr[row_info.row_num], image_width_bytes);
for (int i = 0; i < temp_img.width * 3; i += 3) {
int r = temp_img.rowptr[row_info.row_num][i + 0];
int g = temp_img.rowptr[row_info.row_num][i + 1];
int b = temp_img.rowptr[row_info.row_num][i + 2];
temp_img.rowptr[row_info.row_num][i + 0] = b;
temp_img.rowptr[row_info.row_num][i + 1] = g;
temp_img.rowptr[row_info.row_num][i + 2] = r;
}
} while (ret == 0);
spng_ctx_free(ctx);
} else {
#ifdef BUILD_WIN32
@ -530,228 +563,39 @@ INT32 PNGLoad(IMAGE* img, FILE* fp, INT32 nPreset)
INT32 PNGGetInfo(IMAGE* img, FILE *fp)
{
IMAGE temp_img;
png_uint_32 width = 0, height = 0;
INT32 bit_depth, color_type;
IMAGE temp_img = { 0, 0, 0, 0, NULL, NULL, 0 };
if (fp) {
// check signature
UINT8 pngsig[PNG_SIG_CHECK_BYTES];
fread(pngsig, 1, PNG_SIG_CHECK_BYTES, fp);
if (png_sig_cmp(pngsig, 0, PNG_SIG_CHECK_BYTES)) {
UINT8 pngsig[PNG_SIG_LEN];
fread(pngsig, 1, PNG_SIG_LEN, fp);
if (png_sig_check(pngsig)) {
return 1;
}
rewind(fp);
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
return 1;
}
spng_ctx *ctx = NULL;
struct spng_ihdr ihdr;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
ctx = spng_ctx_new(0);
spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE);
size_t limit = 1024 * 1024 * 64;
spng_set_chunk_limits(ctx, limit, limit);
spng_set_png_file(ctx, fp);
int ret = spng_get_ihdr(ctx, &ihdr);
if (ret) {
// can't decode header info's - bad png
return 1;
}
memset(&temp_img, 0, sizeof(IMAGE));
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, PNG_SIG_CHECK_BYTES);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
temp_img.width = ihdr.width;
temp_img.height = ihdr.height;
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return 1;
}
temp_img.width = width;
temp_img.height = height;
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return 1;
}
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
spng_ctx_free(ctx);
}
memcpy(img, &temp_img, sizeof(IMAGE));
img_free(&temp_img);
return 0;
}
// ----- Memory PNG v.00001
struct ImageSource
{
UINT8 *data;
int size;
int offset;
};
bool PNGIsImageBuffer(unsigned char* buffer, int bufferLength)
{
if (buffer && bufferLength >= PNG_SIG_CHECK_BYTES && png_sig_cmp(buffer, 0, PNG_SIG_CHECK_BYTES) == 0) {
return true;
}
return false;
}
static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
{
ImageSource* isource = (ImageSource*)png_get_io_ptr(png_ptr);
if (isource == NULL) {
return;
}
if ((int)(isource->offset + length) <= isource->size)
{
memcpy(data, isource->data + isource->offset, length);
isource->offset += length;
}
else
png_error(png_ptr, "pngReaderCallback failed");
}
INT32 PNGLoadBuffer(IMAGE* img, unsigned char* buffer, int bufferLength, INT32 nPreset)
{
IMAGE temp_img;
png_uint_32 width = 0, height = 0;
INT32 bit_depth, color_type;
if (png_sig_cmp(buffer, 0, PNG_SIG_CHECK_BYTES)) {
return 1;
}
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
return 1;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return 1;
}
static ImageSource imgsource;
imgsource.data = buffer;
imgsource.size = bufferLength;
imgsource.offset = 0;
png_set_read_fn(png_ptr, &imgsource, pngReadCallback);
memset(&temp_img, 0, sizeof(IMAGE));
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return 1;
}
// Instruct libpng to convert the image to 24-bit RGB format
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(png_ptr);
}
if (bit_depth == 16) {
png_set_strip_16(png_ptr);
}
if (color_type & PNG_COLOR_MASK_ALPHA) {
png_set_strip_alpha(png_ptr);
}
temp_img.width = width;
temp_img.height = height;
// Initialize our img structure
if (img_alloc(&temp_img)) {
//longjmp(png_ptr->jmpbuf, 1);
png_jmpbuf(png_ptr);
}
// If bad things happen in libpng we need to do img_free(&temp_img) as well
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
img_free(&temp_img);
return 1;
}
// Read the .PNG image
png_set_bgr(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_read_image(png_ptr, temp_img.rowptr);
png_read_end(png_ptr, (png_infop)NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
if (img_process(&temp_img, img->width ? img->width : temp_img.width, img->height ? img->height : temp_img.height, nPreset, false)) {
img_free(&temp_img);
return 1;
}
bPngImageOrientation = 0;
if (height && width && height > width) bPngImageOrientation = 1;
memcpy(img, &temp_img, sizeof(IMAGE));
return 0;
}
INT32 PNGGetInfoBuffer(IMAGE* img, unsigned char* buffer, int bufferLength)
{
IMAGE temp_img;
png_uint_32 width = 0, height = 0;
INT32 bit_depth, color_type;
if (png_sig_cmp(buffer, 0, PNG_SIG_CHECK_BYTES)) {
return 1;
}
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
return 1;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return 1;
}
ImageSource imgsource;
imgsource.data = buffer;
imgsource.size = bufferLength;
imgsource.offset = 0;
png_set_read_fn(png_ptr, &imgsource, pngReadCallback);
memset(&temp_img, 0, sizeof(IMAGE));
png_set_sig_bytes(png_ptr, PNG_SIG_CHECK_BYTES);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return 1;
}
temp_img.width = width;
temp_img.height = height;
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
return 1;
}
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
memcpy(img, &temp_img, sizeof(IMAGE));
img_free(&temp_img);

View File

@ -1,4 +1,5 @@
#include "burner.h"
#include "spng.h"
#define SSHOT_NOERROR 0
#define SSHOT_ERROR_BPP_NOTSUPPORTED 1
@ -12,56 +13,33 @@
#endif
static UINT8* pSShot = NULL;
static UINT8* pConvertedImage = NULL;
static png_bytep* pSShotImageRows = NULL;
static UINT8* pFreeMe[3] = { NULL, NULL, NULL };
static FILE* ff = NULL;
static void free_temp_imagen()
{
// free temp memory from the conversion processeses
for (int i = 0; i < 3; i++) {
if (pFreeMe[i]) {
free(pFreeMe[i]);
pFreeMe[i] = NULL;
}
}
}
INT32 MakeScreenShot()
{
char szAuthor[256]; char szDescription[256]; char szCopyright[256]; char szSoftware[256]; char szSource[256];
png_text text_ptr[8] = { { 0, 0, 0, 0, 0, 0, 0 }, };
char szAuthor[256]; char szDescription[256]; char szCopyright[256]; char szTime[256]; char szSoftware[256]; char szSource[256];
spng_text text_ptr[8];
INT32 num_text = 8;
time_t currentTime;
tm* tmTime;
png_time_struct png_time_now;
char szSShotName[MAX_PATH] = { 0, };
INT32 w, h;
// do our PNG construct things
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
return SSHOT_LIBPNG_ERROR;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return SSHOT_LIBPNG_ERROR;
}
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_write_struct(&png_ptr, &info_ptr);
if (pConvertedImage) {
free(pConvertedImage);
pConvertedImage = NULL;
}
if (pSShotImageRows) {
free(pSShotImageRows);
pSShotImageRows = NULL;
}
if (ff) {
fclose(ff);
remove(szSShotName);
}
return SSHOT_LIBPNG_ERROR;
}
if (pVidImage == NULL) {
return SSHOT_OTHER_ERROR;
}
@ -78,6 +56,8 @@ INT32 MakeScreenShot()
if (nVidImageBPP < 4) {
UINT8* pTemp = (UINT8*)malloc(w * h * sizeof(INT32));
pFreeMe[0] = pTemp;
if (nVidImageBPP == 2) {
for (INT32 i = 0; i < h * w; i++) {
UINT16 nColour = ((UINT16*)pSShot)[i];
@ -113,15 +93,15 @@ INT32 MakeScreenShot()
}
}
pConvertedImage = pTemp;
pSShot = pConvertedImage;
pSShot = pTemp;
}
// Rotate and flip the image
if (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL) {
UINT8* pTemp = (UINT8*)malloc(w * h * sizeof(INT32));
pFreeMe[1] = pTemp;
for (INT32 x = 0; x < h; x++) {
if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) {
for (INT32 y = 0; y < w; y++) {
@ -139,6 +119,8 @@ INT32 MakeScreenShot()
else if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) { // fixed rotation by regret
UINT8* pTemp = (UINT8*)malloc(w * h * sizeof(INT32));
pFreeMe[1] = pTemp;
for (INT32 y = h - 1; y >= 0; y--) {
for (INT32 x = w - 1; x >= 0; x--) {
((UINT32*)pTemp)[(w - x - 1) + (h - y - 1) * w] = ((UINT32*)pSShot)[x + y * w];
@ -148,28 +130,45 @@ INT32 MakeScreenShot()
pSShot = pTemp;
}
{
UINT8* pTemp = (UINT8*)malloc(w * h * 3); // bgrbgrbgr...
pFreeMe[2] = pTemp;
// convert (int*)argb to bgr as needed by libspng
for (int i = 0; i < w * h; i++) {
int r = pSShot[i * 4 + 0]; // (int)ARGB (little endian)
int g = pSShot[i * 4 + 1];
int b = pSShot[i * 4 + 2];
pTemp[i * 3 + 0] = b; // BGR (byte order)
pTemp[i * 3 + 1] = g;
pTemp[i * 3 + 2] = r;
}
pSShot = pTemp;
}
// Get the time
time(&currentTime);
tmTime = localtime(&currentTime);
png_convert_from_time_t(&png_time_now, currentTime);
//png_convert_from_time_t(&png_time_now, currentTime);
#if defined(BUILD_SDL2) && !defined(SDL_WINDOWS)
SSHOT_DIRECTORY = SDL_GetPrefPath("fbneo", "screenshots");
#endif
// construct our filename -> "romname-mm-dd-hms.png"
sprintf(szSShotName,"%s%s-%.2d-%.2d-%.2d%.2d%.2d.png", SSHOT_DIRECTORY, BurnDrvGetTextA(DRV_NAME), tmTime->tm_mon + 1, tmTime->tm_mday, tmTime->tm_hour, tmTime->tm_min, tmTime->tm_sec);
//sprintf(szTime,"%.2d-%.2d-%.2d %.2d:%.2d:%.2d", tmTime->tm_mon + 1, tmTime->tm_mday, tmTime->tm_year, tmTime->tm_hour, tmTime->tm_min, tmTime->tm_sec);
sprintf(szTime, "%s", asctime(tmTime));
#if defined(BUILD_SDL2) && !defined(SDL_WINDOWS)
SDL_free(SSHOT_DIRECTORY);
#endif
ff = fopen(szSShotName, "wb");
if (ff == NULL) {
png_destroy_write_struct(&png_ptr, &info_ptr);
if (pConvertedImage) {
free(pConvertedImage);
pConvertedImage = NULL;
}
free_temp_imagen();
return SSHOT_OTHER_ERROR;
}
@ -183,58 +182,57 @@ INT32 MakeScreenShot()
sprintf(szDescription, "Screenshot of %s", DecorateGameName(nBurnDrvActive));
sprintf(szCopyright, "%s %s", BurnDrvGetTextA(DRV_DATE), BurnDrvGetTextA(DRV_MANUFACTURER));
#ifdef _UNICODE
sprintf(szSoftware, APP_TITLE " v%.20ls using LibPNG " PNG_LIBPNG_VER_STRING, szAppBurnVer);
sprintf(szSoftware, APP_TITLE " v%.20ls using LibSPNG v%d.%d.%d", szAppBurnVer, SPNG_VERSION_MAJOR, SPNG_VERSION_MINOR, SPNG_VERSION_PATCH);
#else
sprintf(szSoftware, APP_TITLE " v%.20s using LibPNG " PNG_LIBPNG_VER_STRING, szAppBurnVer);
sprintf(szSoftware, APP_TITLE " v%.20s using LibSPNG v%d.%d.%d", szAppBurnVer, SPNG_VERSION_MAJOR, SPNG_VERSION_MINOR, SPNG_VERSION_PATCH);
#endif
sprintf(szSource, "%s video game hardware", BurnDrvGetTextA(DRV_SYSTEM));
text_ptr[0].key = "Title"; text_ptr[0].text = BurnDrvGetTextA(DRV_FULLNAME);
text_ptr[1].key = "Author"; text_ptr[1].text = szAuthor;
text_ptr[2].key = "Description"; text_ptr[2].text = szDescription;
text_ptr[3].key = "Copyright"; text_ptr[3].text = szCopyright;
// text_ptr[4].key = "Creation Time"; text_ptr[4].text = (char*)png_convert_to_rfc1123(png_ptr, &png_time_now); // deprecated in libpng
text_ptr[4].key = "Creation Time"; png_convert_to_rfc1123_buffer(text_ptr[4].text, &png_time_now);
text_ptr[5].key = "Software"; text_ptr[5].text = szSoftware;
text_ptr[6].key = "Source"; text_ptr[6].text = szSource;
text_ptr[7].key = "Comment"; text_ptr[7].text = "This screenshot was created by running the game in an emulator; it might not accurately reflect the actual hardware the game was designed to run on.";
memset(text_ptr, 0, sizeof(text_ptr));
for (INT32 i = 0; i < num_text; i++) {
text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE;
strcpy(text_ptr[0].keyword, "Title"); text_ptr[0].text = BurnDrvGetTextA(DRV_FULLNAME);
strcpy(text_ptr[1].keyword, "Author"); text_ptr[1].text = szAuthor;
strcpy(text_ptr[2].keyword, "Description"); text_ptr[2].text = szDescription;
strcpy(text_ptr[3].keyword, "Copyright"); text_ptr[3].text = szCopyright;
strcpy(text_ptr[4].keyword, "Creation Time"); text_ptr[4].text = szTime;
strcpy(text_ptr[5].keyword, "Software"); text_ptr[5].text = szSoftware;
strcpy(text_ptr[6].keyword, "Source"); text_ptr[6].text = szSource;
strcpy(text_ptr[7].keyword, "Comment"); text_ptr[7].text = "This screenshot was created by running the game in an emulator; it might not accurately reflect the actual hardware the game was designed to run on.";
for (int i = 0; i < num_text; i++) {
text_ptr[i].type = SPNG_TEXT;
text_ptr[i].length = strlen(text_ptr[i].text);
}
png_set_text(png_ptr, info_ptr, text_ptr, num_text);
// png it on! (dink was here)
spng_ctx *ctx = NULL;
struct spng_ihdr ihdr = { 0 };
png_init_io(png_ptr, ff);
ctx = spng_ctx_new(SPNG_CTX_ENCODER);
spng_set_png_file(ctx, ff);
png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
png_set_bgr(png_ptr);
pSShotImageRows = (png_bytep*)malloc(h * sizeof(png_bytep));
for (INT32 y = 0; y < h; y++) {
pSShotImageRows[y] = pSShot + (y * w * sizeof(INT32));
}
png_write_image(png_ptr, pSShotImageRows);
png_write_end(png_ptr, info_ptr);
if (pSShotImageRows) {
free(pSShotImageRows);
pSShotImageRows = NULL;
int rv = spng_set_text(ctx, &text_ptr[0], num_text);
if (rv) {
bprintf(0, _T("spng_set_text() error: %d / %S\n"), rv, spng_strerror(rv));
}
ihdr.width = w;
ihdr.height = h;
ihdr.color_type = SPNG_COLOR_TYPE_TRUECOLOR;
ihdr.bit_depth = 8;
spng_set_ihdr(ctx, &ihdr);
rv = spng_encode_image(ctx, pSShot, w * h * 3, SPNG_FMT_PNG, SPNG_ENCODE_FINALIZE);
if (rv) {
bprintf(0, _T("spng_encode_image() error: %d / %S\n"), rv, spng_strerror(rv));
}
spng_ctx_free(ctx);
fclose(ff);
png_destroy_write_struct(&png_ptr, &info_ptr);
if (pConvertedImage) {
free(pConvertedImage);
pConvertedImage = NULL;
}
free_temp_imagen();
return SSHOT_NOERROR;
}

View File

@ -348,7 +348,6 @@ extern TCHAR szNeoCDGamesDir[MAX_PATH];
HBITMAP ImageToBitmap(HWND hwnd, IMAGE* img);
HBITMAP PNGLoadBitmap(HWND hWnd, FILE* fp, int nWidth, int nHeight, int nPreset);
HBITMAP PNGLoadBitmapBuffer(HWND hWnd, unsigned char* buffer, int bufferLength, int nWidth, int nHeight, int nPreset);
HBITMAP LoadBitmap(HWND hWnd, FILE* fp, int nWidth, int nHeight, int nPreset);
int NeoCDList_CheckISO(TCHAR* pszFile, void (*pfEntryCallBack)(INT32, TCHAR*));

View File

@ -1,5 +1,4 @@
#include "burner.h"
#include "png.h"
HBITMAP ImageToBitmap(HWND hwnd, IMAGE* img)
{
@ -44,17 +43,6 @@ HBITMAP PNGLoadBitmap(HWND hWnd, FILE* fp, int nWidth, int nHeight, int nPreset)
return ImageToBitmap(hWnd, &img);
}
HBITMAP PNGLoadBitmapBuffer(HWND hWnd, unsigned char* buffer, int bufferLength, int nWidth, int nHeight, int nPreset)
{
IMAGE img = { nWidth, nHeight, 0, 0, NULL, NULL, 0};
if (PNGLoadBuffer(&img, buffer, bufferLength, nPreset)) {
return NULL;
}
return ImageToBitmap(hWnd, &img);
}
HBITMAP LoadBitmap(HWND hWnd, FILE* fp, int nWidth, int nHeight, int nPreset)
{
if (hWnd == NULL || fp == NULL) {

View File

@ -1,9 +1,7 @@
// ----------------------------------------------------------------------------------------------------------
// NEOCDSEL.CPP
#include "burner.h"
#include "png.h"
#include "neocdlist.h"
#include <process.h>
int NeoCDList_Init();
@ -393,12 +391,8 @@ static TCHAR* NeoCDList_ParseCUE(TCHAR* pszFile)
static PNGRESOLUTION GetPNGResolution(TCHAR* szFile)
{
int width = 0;
int height = 0;
PNGRESOLUTION nResolution = { 0, 0 };
png_structp png_ptr;
png_infop info_ptr;
char header[8];
IMAGE img = { 0, 0, 0, 0, NULL, NULL, 0 };
FILE *fp = _tfopen(szFile, _T("rb"));
@ -406,36 +400,12 @@ static PNGRESOLUTION GetPNGResolution(TCHAR* szFile)
return nResolution;
}
fread(header, 1, 8, fp);
PNGGetInfo(&img, fp);
if (png_sig_cmp((png_const_bytep)header, 0, 8)) {
return nResolution;
}
nResolution.nWidth = img.width;
nResolution.nHeight = img.height;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
return nResolution;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
return nResolution;
}
if (setjmp(png_jmpbuf(png_ptr))) {
return nResolution;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
width = png_get_image_width(png_ptr, info_ptr);
height = png_get_image_height(png_ptr, info_ptr);
nResolution.nWidth = width;
nResolution.nHeight = height;
bprintf(0, _T("Png res [%s] %d, %d\n"), szFile, img.width, img.height);
fclose(fp);

6979
src/dep/libs/libspng/spng.c Normal file

File diff suppressed because it is too large Load Diff

537
src/dep/libs/libspng/spng.h Normal file
View File

@ -0,0 +1,537 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef SPNG_H
#define SPNG_H
#define SPNG_STATIC
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SPNG_STATIC)
#if defined(SPNG__BUILD)
#define SPNG_API __declspec(dllexport)
#else
#define SPNG_API __declspec(dllimport)
#endif
#else
#define SPNG_API
#endif
#if defined(_MSC_VER)
#define SPNG_CDECL __cdecl
#else
#define SPNG_CDECL
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#define SPNG_VERSION_MAJOR 0
#define SPNG_VERSION_MINOR 7
#define SPNG_VERSION_PATCH 3
enum spng_errno
{
SPNG_IO_ERROR = -2,
SPNG_IO_EOF = -1,
SPNG_OK = 0,
SPNG_EINVAL,
SPNG_EMEM,
SPNG_EOVERFLOW,
SPNG_ESIGNATURE,
SPNG_EWIDTH,
SPNG_EHEIGHT,
SPNG_EUSER_WIDTH,
SPNG_EUSER_HEIGHT,
SPNG_EBIT_DEPTH,
SPNG_ECOLOR_TYPE,
SPNG_ECOMPRESSION_METHOD,
SPNG_EFILTER_METHOD,
SPNG_EINTERLACE_METHOD,
SPNG_EIHDR_SIZE,
SPNG_ENOIHDR,
SPNG_ECHUNK_POS,
SPNG_ECHUNK_SIZE,
SPNG_ECHUNK_CRC,
SPNG_ECHUNK_TYPE,
SPNG_ECHUNK_UNKNOWN_CRITICAL,
SPNG_EDUP_PLTE,
SPNG_EDUP_CHRM,
SPNG_EDUP_GAMA,
SPNG_EDUP_ICCP,
SPNG_EDUP_SBIT,
SPNG_EDUP_SRGB,
SPNG_EDUP_BKGD,
SPNG_EDUP_HIST,
SPNG_EDUP_TRNS,
SPNG_EDUP_PHYS,
SPNG_EDUP_TIME,
SPNG_EDUP_OFFS,
SPNG_EDUP_EXIF,
SPNG_ECHRM,
SPNG_EPLTE_IDX,
SPNG_ETRNS_COLOR_TYPE,
SPNG_ETRNS_NO_PLTE,
SPNG_EGAMA,
SPNG_EICCP_NAME,
SPNG_EICCP_COMPRESSION_METHOD,
SPNG_ESBIT,
SPNG_ESRGB,
SPNG_ETEXT,
SPNG_ETEXT_KEYWORD,
SPNG_EZTXT,
SPNG_EZTXT_COMPRESSION_METHOD,
SPNG_EITXT,
SPNG_EITXT_COMPRESSION_FLAG,
SPNG_EITXT_COMPRESSION_METHOD,
SPNG_EITXT_LANG_TAG,
SPNG_EITXT_TRANSLATED_KEY,
SPNG_EBKGD_NO_PLTE,
SPNG_EBKGD_PLTE_IDX,
SPNG_EHIST_NO_PLTE,
SPNG_EPHYS,
SPNG_ESPLT_NAME,
SPNG_ESPLT_DUP_NAME,
SPNG_ESPLT_DEPTH,
SPNG_ETIME,
SPNG_EOFFS,
SPNG_EEXIF,
SPNG_EIDAT_TOO_SHORT,
SPNG_EIDAT_STREAM,
SPNG_EZLIB,
SPNG_EFILTER,
SPNG_EBUFSIZ,
SPNG_EIO,
SPNG_EOF,
SPNG_EBUF_SET,
SPNG_EBADSTATE,
SPNG_EFMT,
SPNG_EFLAGS,
SPNG_ECHUNKAVAIL,
SPNG_ENCODE_ONLY,
SPNG_EOI,
SPNG_ENOPLTE,
SPNG_ECHUNK_LIMITS,
SPNG_EZLIB_INIT,
SPNG_ECHUNK_STDLEN,
SPNG_EINTERNAL,
SPNG_ECTXTYPE,
SPNG_ENOSRC,
SPNG_ENODST,
SPNG_EOPSTATE,
SPNG_ENOTFINAL,
};
enum spng_text_type
{
SPNG_TEXT = 1,
SPNG_ZTXT = 2,
SPNG_ITXT = 3
};
enum spng_color_type
{
SPNG_COLOR_TYPE_GRAYSCALE = 0,
SPNG_COLOR_TYPE_TRUECOLOR = 2,
SPNG_COLOR_TYPE_INDEXED = 3,
SPNG_COLOR_TYPE_GRAYSCALE_ALPHA = 4,
SPNG_COLOR_TYPE_TRUECOLOR_ALPHA = 6
};
enum spng_filter
{
SPNG_FILTER_NONE = 0,
SPNG_FILTER_SUB = 1,
SPNG_FILTER_UP = 2,
SPNG_FILTER_AVERAGE = 3,
SPNG_FILTER_PAETH = 4
};
enum spng_filter_choice
{
SPNG_DISABLE_FILTERING = 0,
SPNG_FILTER_CHOICE_NONE = 8,
SPNG_FILTER_CHOICE_SUB = 16,
SPNG_FILTER_CHOICE_UP = 32,
SPNG_FILTER_CHOICE_AVG = 64,
SPNG_FILTER_CHOICE_PAETH = 128,
SPNG_FILTER_CHOICE_ALL = (8|16|32|64|128)
};
enum spng_interlace_method
{
SPNG_INTERLACE_NONE = 0,
SPNG_INTERLACE_ADAM7 = 1
};
/* Channels are always in byte-order */
enum spng_format
{
SPNG_FMT_RGBA8 = 1,
SPNG_FMT_RGBA16 = 2,
SPNG_FMT_RGB8 = 4,
/* Partially implemented, see documentation */
SPNG_FMT_GA8 = 16,
SPNG_FMT_GA16 = 32,
SPNG_FMT_G8 = 64,
/* No conversion or scaling */
SPNG_FMT_PNG = 256,
SPNG_FMT_RAW = 512 /* big-endian (everything else is host-endian) */
};
enum spng_ctx_flags
{
SPNG_CTX_IGNORE_ADLER32 = 1, /* Ignore checksum in DEFLATE streams */
SPNG_CTX_ENCODER = 2 /* Create an encoder context */
};
enum spng_decode_flags
{
SPNG_DECODE_USE_TRNS = 1, /* Deprecated */
SPNG_DECODE_USE_GAMA = 2, /* Deprecated */
SPNG_DECODE_USE_SBIT = 8, /* Undocumented */
SPNG_DECODE_TRNS = 1, /* Apply transparency */
SPNG_DECODE_GAMMA = 2, /* Apply gamma correction */
SPNG_DECODE_PROGRESSIVE = 256 /* Initialize for progressive reads */
};
enum spng_crc_action
{
/* Default for critical chunks */
SPNG_CRC_ERROR = 0,
/* Discard chunk, invalid for critical chunks.
Since v0.6.2: default for ancillary chunks */
SPNG_CRC_DISCARD = 1,
/* Ignore and don't calculate checksum.
Since v0.6.2: also ignores checksums in DEFLATE streams */
SPNG_CRC_USE = 2
};
enum spng_encode_flags
{
SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */
SPNG_ENCODE_FINALIZE = 2, /* Finalize PNG after encoding image */
};
struct spng_ihdr
{
uint32_t width;
uint32_t height;
uint8_t bit_depth;
uint8_t color_type;
uint8_t compression_method;
uint8_t filter_method;
uint8_t interlace_method;
};
struct spng_plte_entry
{
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha; /* Reserved for internal use */
};
struct spng_plte
{
uint32_t n_entries;
struct spng_plte_entry entries[256];
};
struct spng_trns
{
uint16_t gray;
uint16_t red;
uint16_t green;
uint16_t blue;
uint32_t n_type3_entries;
uint8_t type3_alpha[256];
};
struct spng_chrm_int
{
uint32_t white_point_x;
uint32_t white_point_y;
uint32_t red_x;
uint32_t red_y;
uint32_t green_x;
uint32_t green_y;
uint32_t blue_x;
uint32_t blue_y;
};
struct spng_chrm
{
double white_point_x;
double white_point_y;
double red_x;
double red_y;
double green_x;
double green_y;
double blue_x;
double blue_y;
};
struct spng_iccp
{
char profile_name[80];
size_t profile_len;
char *profile;
};
struct spng_sbit
{
uint8_t grayscale_bits;
uint8_t red_bits;
uint8_t green_bits;
uint8_t blue_bits;
uint8_t alpha_bits;
};
struct spng_text
{
char keyword[80];
int type;
size_t length;
char *text;
uint8_t compression_flag; /* iTXt only */
uint8_t compression_method; /* iTXt, ztXt only */
char *language_tag; /* iTXt only */
char *translated_keyword; /* iTXt only */
};
struct spng_bkgd
{
uint16_t gray; /* Only for gray/gray alpha */
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t plte_index; /* Only for indexed color */
};
struct spng_hist
{
uint16_t frequency[256];
};
struct spng_phys
{
uint32_t ppu_x, ppu_y;
uint8_t unit_specifier;
};
struct spng_splt_entry
{
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t alpha;
uint16_t frequency;
};
struct spng_splt
{
char name[80];
uint8_t sample_depth;
uint32_t n_entries;
struct spng_splt_entry *entries;
};
struct spng_time
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
struct spng_offs
{
int32_t x, y;
uint8_t unit_specifier;
};
struct spng_exif
{
size_t length;
char *data;
};
struct spng_chunk
{
size_t offset;
uint32_t length;
uint8_t type[4];
uint32_t crc;
};
enum spng_location
{
SPNG_AFTER_IHDR = 1,
SPNG_AFTER_PLTE = 2,
SPNG_AFTER_IDAT = 8,
};
struct spng_unknown_chunk
{
uint8_t type[4];
size_t length;
void *data;
enum spng_location location;
};
enum spng_option
{
SPNG_KEEP_UNKNOWN_CHUNKS = 1,
SPNG_IMG_COMPRESSION_LEVEL,
SPNG_IMG_WINDOW_BITS,
SPNG_IMG_MEM_LEVEL,
SPNG_IMG_COMPRESSION_STRATEGY,
SPNG_TEXT_COMPRESSION_LEVEL,
SPNG_TEXT_WINDOW_BITS,
SPNG_TEXT_MEM_LEVEL,
SPNG_TEXT_COMPRESSION_STRATEGY,
SPNG_FILTER_CHOICE,
SPNG_CHUNK_COUNT_LIMIT,
SPNG_ENCODE_TO_BUFFER,
};
typedef void* SPNG_CDECL spng_malloc_fn(size_t size);
typedef void* SPNG_CDECL spng_realloc_fn(void* ptr, size_t size);
typedef void* SPNG_CDECL spng_calloc_fn(size_t count, size_t size);
typedef void SPNG_CDECL spng_free_fn(void* ptr);
struct spng_alloc
{
spng_malloc_fn *malloc_fn;
spng_realloc_fn *realloc_fn;
spng_calloc_fn *calloc_fn;
spng_free_fn *free_fn;
};
struct spng_row_info
{
uint32_t scanline_idx;
uint32_t row_num; /* deinterlaced row index */
int pass;
uint8_t filter;
};
typedef struct spng_ctx spng_ctx;
typedef int spng_read_fn(spng_ctx *ctx, void *user, void *dest, size_t length);
typedef int spng_write_fn(spng_ctx *ctx, void *user, void *src, size_t length);
typedef int spng_rw_fn(spng_ctx *ctx, void *user, void *dst_src, size_t length);
SPNG_API spng_ctx *spng_ctx_new(int flags);
SPNG_API spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags);
SPNG_API void spng_ctx_free(spng_ctx *ctx);
SPNG_API int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size);
SPNG_API int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user);
SPNG_API int spng_set_png_file(spng_ctx *ctx, FILE *file);
SPNG_API void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error);
SPNG_API int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height);
SPNG_API int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height);
SPNG_API int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_size);
SPNG_API int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_size);
SPNG_API int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary);
SPNG_API int spng_set_option(spng_ctx *ctx, enum spng_option option, int value);
SPNG_API int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value);
SPNG_API int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len);
/* Decode */
SPNG_API int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags);
/* Progressive decode */
SPNG_API int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_row(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_chunks(spng_ctx *ctx);
/* Encode/decode */
SPNG_API int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info);
/* Encode */
SPNG_API int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags);
/* Progressive encode */
SPNG_API int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len);
SPNG_API int spng_encode_row(spng_ctx *ctx, const void *row, size_t len);
SPNG_API int spng_encode_chunks(spng_ctx *ctx);
SPNG_API int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_get_gama(spng_ctx *ctx, double *gamma);
SPNG_API int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int);
SPNG_API int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent);
SPNG_API int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text);
SPNG_API int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt);
SPNG_API int spng_get_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks);
/* Official extensions */
SPNG_API int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_set_gama(spng_ctx *ctx, double gamma);
SPNG_API int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma);
SPNG_API int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent);
SPNG_API int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text);
SPNG_API int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt);
SPNG_API int spng_set_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks);
/* Official extensions */
SPNG_API int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API const char *spng_strerror(int err);
SPNG_API const char *spng_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* SPNG_H */

View File

@ -59,7 +59,7 @@ YMF278B sound core by R. Belmont & O.Galibert (http://www.mamedev.org).
Uses SMS Plus by Charles MacDonald (http://www.techno-junk.org).
7Z functionality provided by LZMA SDK (http://www.7-zip.org/sdk.html)
PNG functionality provided by libpng (http://www.libpng.org)
PNG functionality provided by libspng (https://libspng.org/)
Zip functionality provided by zlib (http://www.zlib.net).
Uses Xbyak (JIT assembler for x86/x64) by Herumi (https://github.com/herumi/xbyak)
@ -130,3 +130,33 @@ 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.
libspng:
BSD 2-Clause License
Copyright (c) 2018-2023, Randy <randy408@protonmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* 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 HOLDER 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