mirror of
https://github.com/libretro/FBNeo.git
synced 2024-11-26 18:40:26 +00:00
convert project from libpng to libspng / https://libspng.org/
This commit is contained in:
parent
550c26bf87
commit
fdc87360f6
@ -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 \
|
||||
\
|
||||
|
@ -52,10 +52,6 @@ typedef struct tagIMAGE {
|
||||
#include "burner_qt.h"
|
||||
#endif
|
||||
|
||||
#if defined (INCLUDE_LIB_PNGH)
|
||||
#include "png.h"
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// OS independent functionality
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(¤tTime);
|
||||
tmTime = localtime(¤tTime);
|
||||
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;
|
||||
}
|
||||
|
@ -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*));
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
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
537
src/dep/libs/libspng/spng.h
Normal 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 */
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user