mirror of
https://github.com/libretro/libretro-common.git
synced 2025-02-26 03:26:24 +00:00
Updates
This commit is contained in:
parent
dee14c1c78
commit
347cf2b016
@ -389,11 +389,11 @@ void fill_pathname(char *out_path, const char *in_path,
|
||||
* present in 'in_path', it will be ignored.
|
||||
*
|
||||
*/
|
||||
void fill_pathname_noext(char *out_path, const char *in_path,
|
||||
size_t fill_pathname_noext(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size)
|
||||
{
|
||||
strlcpy(out_path, in_path, size);
|
||||
strlcat(out_path, replace, size);
|
||||
return strlcat(out_path, replace, size);
|
||||
}
|
||||
|
||||
char *find_last_slash(const char *str)
|
||||
|
@ -24,8 +24,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libretro.h>
|
||||
#include <encodings/crc32.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <streams/interface_stream.h>
|
||||
#include <streams/trans_stream.h>
|
||||
|
||||
#include "rpng_internal.h"
|
||||
@ -37,6 +38,9 @@
|
||||
goto end; \
|
||||
} while(0)
|
||||
|
||||
double DEFLATE_PADDING = 1.1;
|
||||
int PNG_ROUGH_HEADER = 100;
|
||||
|
||||
static void dword_write_be(uint8_t *buf, uint32_t val)
|
||||
{
|
||||
*buf++ = (uint8_t)(val >> 24);
|
||||
@ -45,16 +49,16 @@ static void dword_write_be(uint8_t *buf, uint32_t val)
|
||||
*buf++ = (uint8_t)(val >> 0);
|
||||
}
|
||||
|
||||
static bool png_write_crc(RFILE *file, const uint8_t *data, size_t size)
|
||||
static bool png_write_crc_string(intfstream_t *intf_s, const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t crc_raw[4] = {0};
|
||||
uint32_t crc = encoding_crc32(0, data, size);
|
||||
|
||||
dword_write_be(crc_raw, crc);
|
||||
return filestream_write(file, crc_raw, sizeof(crc_raw)) == sizeof(crc_raw);
|
||||
return intfstream_write(intf_s, crc_raw, sizeof(crc_raw)) == sizeof(crc_raw);
|
||||
}
|
||||
|
||||
static bool png_write_ihdr(RFILE *file, const struct png_ihdr *ihdr)
|
||||
static bool png_write_ihdr_string(intfstream_t *intf_s, const struct png_ihdr *ihdr)
|
||||
{
|
||||
uint8_t ihdr_raw[21];
|
||||
|
||||
@ -83,32 +87,32 @@ static bool png_write_ihdr(RFILE *file, const struct png_ihdr *ihdr)
|
||||
dword_write_be(ihdr_raw + 0, sizeof(ihdr_raw) - 8);
|
||||
dword_write_be(ihdr_raw + 8, ihdr->width);
|
||||
dword_write_be(ihdr_raw + 12, ihdr->height);
|
||||
if (filestream_write(file, ihdr_raw, sizeof(ihdr_raw)) != sizeof(ihdr_raw))
|
||||
if (intfstream_write(intf_s, ihdr_raw, sizeof(ihdr_raw)) != sizeof(ihdr_raw))
|
||||
return false;
|
||||
|
||||
return png_write_crc(file, ihdr_raw + sizeof(uint32_t),
|
||||
return png_write_crc_string(intf_s, ihdr_raw + sizeof(uint32_t),
|
||||
sizeof(ihdr_raw) - sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static bool png_write_idat(RFILE *file, const uint8_t *data, size_t size)
|
||||
static bool png_write_idat_string(intfstream_t* intf_s, const uint8_t *data, size_t size)
|
||||
{
|
||||
if (filestream_write(file, data, size) != (ssize_t)size)
|
||||
if (intfstream_write(intf_s, data, size) != (ssize_t)size)
|
||||
return false;
|
||||
|
||||
return png_write_crc(file, data + sizeof(uint32_t), size - sizeof(uint32_t));
|
||||
return png_write_crc_string(intf_s, data + sizeof(uint32_t), size - sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static bool png_write_iend(RFILE *file)
|
||||
static bool png_write_iend_string(intfstream_t* intf_s)
|
||||
{
|
||||
const uint8_t data[] = {
|
||||
0, 0, 0, 0,
|
||||
'I', 'E', 'N', 'D',
|
||||
};
|
||||
|
||||
if (filestream_write(file, data, sizeof(data)) != sizeof(data))
|
||||
if (intfstream_write(intf_s, data, sizeof(data)) != sizeof(data))
|
||||
return false;
|
||||
|
||||
return png_write_crc(file, data + sizeof(uint32_t),
|
||||
return png_write_crc_string(intf_s, data + sizeof(uint32_t),
|
||||
sizeof(data) - sizeof(uint32_t));
|
||||
}
|
||||
|
||||
@ -199,14 +203,12 @@ static unsigned filter_paeth(uint8_t *target,
|
||||
return count_sad(target, width);
|
||||
}
|
||||
|
||||
static bool rpng_save_image(const char *path,
|
||||
const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch, unsigned bpp)
|
||||
bool rpng_save_image_stream(const uint8_t *data, intfstream_t* intf_s,
|
||||
unsigned width, unsigned height, signed pitch, unsigned bpp)
|
||||
{
|
||||
unsigned h;
|
||||
bool ret = true;
|
||||
struct png_ihdr ihdr = {0};
|
||||
|
||||
bool ret = true;
|
||||
const struct trans_stream_backend *stream_backend = NULL;
|
||||
size_t encode_buf_size = 0;
|
||||
uint8_t *encode_buf = NULL;
|
||||
@ -221,26 +223,24 @@ static bool rpng_save_image(const char *path,
|
||||
void *stream = NULL;
|
||||
uint32_t total_in = 0;
|
||||
uint32_t total_out = 0;
|
||||
RFILE *file = filestream_open(path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
if (!file)
|
||||
|
||||
if (!intf_s)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend = trans_stream_get_zlib_deflate_backend();
|
||||
|
||||
if (filestream_write(file, png_magic, sizeof(png_magic)) != sizeof(png_magic))
|
||||
if (intfstream_write(intf_s, png_magic, sizeof(png_magic)) != sizeof(png_magic))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
ihdr.width = width;
|
||||
ihdr.height = height;
|
||||
ihdr.depth = 8;
|
||||
ihdr.color_type = bpp == sizeof(uint32_t) ? 6 : 2; /* RGBA or RGB */
|
||||
if (!png_write_ihdr(file, &ihdr))
|
||||
if (!png_write_ihdr_string(intf_s, &ihdr))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
encode_buf_size = (width * bpp + 1) * height;
|
||||
encode_buf = (uint8_t*)malloc(encode_buf_size);
|
||||
encode_buf = (uint8_t*)malloc(encode_buf_size);
|
||||
if (!encode_buf)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
@ -339,15 +339,12 @@ static bool rpng_save_image(const char *path,
|
||||
|
||||
memcpy(deflate_buf + 4, "IDAT", 4);
|
||||
dword_write_be(deflate_buf + 0, ((uint32_t)total_out));
|
||||
if (!png_write_idat(file, deflate_buf, ((size_t)total_out + 8)))
|
||||
if (!png_write_idat_string(intf_s, deflate_buf, ((size_t)total_out + 8)))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
if (!png_write_iend(file))
|
||||
if (!png_write_iend_string(intf_s))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
end:
|
||||
if (file)
|
||||
filestream_close(file);
|
||||
free(encode_buf);
|
||||
free(deflate_buf);
|
||||
free(rgba_line);
|
||||
@ -371,13 +368,78 @@ end:
|
||||
bool rpng_save_image_argb(const char *path, const uint32_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
return rpng_save_image(path, (const uint8_t*)data,
|
||||
width, height, pitch, sizeof(uint32_t));
|
||||
bool ret = false;
|
||||
intfstream_t* intf_s = NULL;
|
||||
|
||||
intf_s = intfstream_open_file(path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
ret = rpng_save_image_stream((const uint8_t*) data, intf_s,
|
||||
width, height,
|
||||
(signed) pitch, sizeof(uint32_t));
|
||||
intfstream_close(intf_s);
|
||||
free(intf_s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool rpng_save_image_bgr24(const char *path, const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
return rpng_save_image(path, (const uint8_t*)data,
|
||||
width, height, pitch, 3);
|
||||
bool ret = false;
|
||||
intfstream_t* intf_s = NULL;
|
||||
|
||||
intf_s = intfstream_open_file(path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
ret = rpng_save_image_stream(data, intf_s, width, height,
|
||||
(signed) pitch, 3);
|
||||
intfstream_close(intf_s);
|
||||
free(intf_s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* rpng_save_image_bgr24_string(const uint8_t *data,
|
||||
unsigned width, unsigned height, signed pitch, uint64_t* bytes)
|
||||
{
|
||||
bool ret = false;
|
||||
uint8_t* buf = NULL;
|
||||
uint8_t* output = NULL;
|
||||
int buf_length = 0;
|
||||
intfstream_t* intf_s = NULL;
|
||||
|
||||
buf_length = (int)(width*height*3*DEFLATE_PADDING)+PNG_ROUGH_HEADER;
|
||||
buf = (uint8_t*)malloc(buf_length*sizeof(uint8_t));
|
||||
if (!buf)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
intf_s = intfstream_open_writable_memory(buf,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE,
|
||||
RETRO_VFS_FILE_ACCESS_HINT_NONE,
|
||||
buf_length);
|
||||
|
||||
ret = rpng_save_image_stream((const uint8_t*)data,
|
||||
intf_s, width, height, pitch, 3);
|
||||
|
||||
*bytes = intfstream_get_ptr(intf_s);
|
||||
intfstream_rewind(intf_s);
|
||||
output = (uint8_t*)malloc((*bytes)*sizeof(uint8_t));
|
||||
if (!output)
|
||||
GOTO_END_ERROR();
|
||||
intfstream_read(intf_s, output, *bytes);
|
||||
|
||||
end:
|
||||
if (buf)
|
||||
free(buf);
|
||||
if (intf_s)
|
||||
free(intf_s);
|
||||
if (ret == false)
|
||||
{
|
||||
if (output)
|
||||
free(output);
|
||||
return NULL;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ void fill_str_dated_filename(char *out_filename,
|
||||
* present in 'in_path', it will be ignored.
|
||||
*
|
||||
*/
|
||||
void fill_pathname_noext(char *out_path, const char *in_path,
|
||||
size_t fill_pathname_noext(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size);
|
||||
|
||||
/**
|
||||
|
@ -56,6 +56,9 @@ bool rpng_save_image_argb(const char *path, const uint32_t *data,
|
||||
bool rpng_save_image_bgr24(const char *path, const uint8_t *data,
|
||||
unsigned width, unsigned height, unsigned pitch);
|
||||
|
||||
uint8_t* rpng_save_image_bgr24_string(const uint8_t *data,
|
||||
unsigned width, unsigned height, signed pitch, uint64_t *bytes);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -74,6 +74,8 @@ int64_t intfstream_read(intfstream_internal_t *intf,
|
||||
int64_t intfstream_write(intfstream_internal_t *intf,
|
||||
const void *s, uint64_t len);
|
||||
|
||||
int64_t intfstream_get_ptr(intfstream_internal_t *intf);
|
||||
|
||||
char *intfstream_gets(intfstream_internal_t *intf,
|
||||
char *buffer, uint64_t len);
|
||||
|
||||
@ -100,6 +102,9 @@ intfstream_t* intfstream_open_file(const char *path,
|
||||
intfstream_t *intfstream_open_memory(void *data,
|
||||
unsigned mode, unsigned hints, uint64_t size);
|
||||
|
||||
intfstream_t *intfstream_open_writable_memory(void *data,
|
||||
unsigned mode, unsigned hints, uint64_t size);
|
||||
|
||||
intfstream_t *intfstream_open_chd_track(const char *path,
|
||||
unsigned mode, unsigned hints, int32_t track);
|
||||
|
||||
|
@ -56,6 +56,8 @@ void memstream_set_buffer(uint8_t *buffer, uint64_t size);
|
||||
|
||||
uint64_t memstream_get_last_size(void);
|
||||
|
||||
uint64_t memstream_get_ptr(memstream_t *stream);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -298,6 +298,24 @@ int64_t intfstream_write(intfstream_internal_t *intf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t intfstream_get_ptr(intfstream_internal_t* intf)
|
||||
{
|
||||
if (!intf)
|
||||
return 0;
|
||||
|
||||
switch (intf->type)
|
||||
{
|
||||
case INTFSTREAM_FILE:
|
||||
return -1;
|
||||
case INTFSTREAM_MEMORY:
|
||||
return memstream_get_ptr(intf->memory.fp);
|
||||
case INTFSTREAM_CHD:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *intfstream_gets(intfstream_internal_t *intf,
|
||||
char *buffer, uint64_t len)
|
||||
{
|
||||
@ -441,7 +459,6 @@ intfstream_t *intfstream_open_memory(void *data,
|
||||
info.memory.writable = false;
|
||||
|
||||
fd = (intfstream_t*)intfstream_init(&info);
|
||||
|
||||
if (!fd)
|
||||
return NULL;
|
||||
|
||||
@ -459,6 +476,37 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
intfstream_t *intfstream_open_writable_memory(void *data,
|
||||
unsigned mode, unsigned hints, uint64_t size)
|
||||
{
|
||||
intfstream_info_t info;
|
||||
intfstream_t *fd = NULL;
|
||||
|
||||
info.type = INTFSTREAM_MEMORY;
|
||||
info.memory.buf.data = (uint8_t*)data;
|
||||
info.memory.buf.size = size;
|
||||
info.memory.writable = true;
|
||||
|
||||
fd = (intfstream_t*)intfstream_init(&info);
|
||||
if (!fd)
|
||||
return NULL;
|
||||
|
||||
if (!intfstream_open(fd, NULL, mode, hints))
|
||||
goto error;
|
||||
|
||||
return fd;
|
||||
|
||||
error:
|
||||
if (fd)
|
||||
{
|
||||
intfstream_close(fd);
|
||||
free(fd);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
intfstream_t *intfstream_open_chd_track(const char *path,
|
||||
unsigned mode, unsigned hints, int32_t track)
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ static void memstream_init(memstream_t *stream,
|
||||
|
||||
memstream_t *memstream_open(unsigned writing)
|
||||
{
|
||||
memstream_t *stream;
|
||||
memstream_t *stream;
|
||||
if (!g_buffer || !g_size)
|
||||
return NULL;
|
||||
|
||||
@ -92,6 +92,11 @@ void memstream_close(memstream_t *stream)
|
||||
free(stream);
|
||||
}
|
||||
|
||||
uint64_t memstream_get_ptr(memstream_t *stream)
|
||||
{
|
||||
return stream->ptr;
|
||||
}
|
||||
|
||||
uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes)
|
||||
{
|
||||
uint64_t avail = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user