mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-27 10:10:57 +00:00
Moving zlib stream interface
Moving the zlib streaming interface out of archive_file and into trans_stream, including updating the png support to use the new trans_stream interface. archive_file_zlib itself still needs updating.
This commit is contained in:
parent
f27476b4ef
commit
ac50e17f50
@ -977,7 +977,9 @@ endif
|
||||
|
||||
# Compression/Archive
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file.o
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file.o \
|
||||
$(LIBRETRO_COMM_DIR)/streams/trans_stream.o \
|
||||
$(LIBRETRO_COMM_DIR)/streams/trans_stream_pipe.o
|
||||
|
||||
ifeq ($(HAVE_7ZIP),1)
|
||||
CFLAGS += -I$(DEPS_DIR)/7zip
|
||||
@ -1003,7 +1005,8 @@ endif
|
||||
|
||||
|
||||
ifeq ($(HAVE_ZLIB), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file_zlib.o
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file_zlib.o \
|
||||
$(LIBRETRO_COMM_DIR)/streams/trans_stream_zlib.o
|
||||
OBJ += $(ZLIB_OBJS)
|
||||
DEFINES += -DHAVE_ZLIB
|
||||
HAVE_COMPRESSION = 1
|
||||
|
@ -424,17 +424,8 @@ static uint32_t sevenzip_stream_crc32_calculate(uint32_t crc,
|
||||
const struct file_archive_file_backend sevenzip_backend = {
|
||||
sevenzip_stream_new,
|
||||
sevenzip_stream_free,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
sevenzip_stream_decompress_data_to_file_init,
|
||||
sevenzip_stream_decompress_data_to_file_iterate,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
sevenzip_stream_crc32_calculate,
|
||||
sevenzip_file_read,
|
||||
sevenzip_parse_file_init,
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <boolean.h>
|
||||
#include <formats/image.h>
|
||||
#include <formats/rpng.h>
|
||||
#include <file/archive_file.h>
|
||||
#include <streams/trans_stream.h>
|
||||
|
||||
#include "rpng_internal.h"
|
||||
|
||||
@ -112,7 +112,8 @@ struct rpng_process
|
||||
unsigned pos;
|
||||
} pass;
|
||||
void *stream;
|
||||
const struct file_archive_file_backend *stream_backend;
|
||||
size_t avail_in, avail_out, total_out;
|
||||
const struct trans_stream_backend *stream_backend;
|
||||
};
|
||||
|
||||
struct rpng
|
||||
@ -538,7 +539,7 @@ static int png_reverse_filter_init(const struct png_ihdr *ihdr,
|
||||
png_pass_geom(&pngp->ihdr, pngp->pass.width,
|
||||
pngp->pass.height, NULL, NULL, &pngp->pass.size);
|
||||
|
||||
if (pngp->pass.size > pngp->stream_backend->stream_get_total_out(pngp->stream))
|
||||
if (pngp->pass.size > pngp->total_out)
|
||||
{
|
||||
free(pngp->data);
|
||||
return -1;
|
||||
@ -554,7 +555,7 @@ static int png_reverse_filter_init(const struct png_ihdr *ihdr,
|
||||
|
||||
png_pass_geom(ihdr, ihdr->width, ihdr->height, &pngp->bpp, &pngp->pitch, &pass_size);
|
||||
|
||||
if (pngp->stream_backend->stream_get_total_out(pngp->stream) < pass_size)
|
||||
if (pngp->total_out < pass_size)
|
||||
return -1;
|
||||
|
||||
pngp->restore_buf_size = 0;
|
||||
@ -711,7 +712,7 @@ static int png_reverse_filter_adam7_iterate(uint32_t **data_,
|
||||
pngp->inflate_buf += pngp->pass.size;
|
||||
pngp->adam7_restore_buf_size += pngp->pass.size;
|
||||
|
||||
pngp->stream_backend->stream_decrement_total_out(pngp->stream, pngp->pass.size);
|
||||
pngp->total_out -= pngp->pass.size;
|
||||
|
||||
png_reverse_filter_adam7_deinterlace_pass(data,
|
||||
ihdr, pngp->data, pngp->pass.width, pngp->pass.height, &passes[pngp->pass.pos]);
|
||||
@ -768,30 +769,31 @@ static int png_reverse_filter_iterate(rpng_t *rpng, uint32_t **data)
|
||||
static int rpng_load_image_argb_process_inflate_init(rpng_t *rpng,
|
||||
uint32_t **data, unsigned *width, unsigned *height)
|
||||
{
|
||||
int zstatus;
|
||||
bool zstatus;
|
||||
enum trans_stream_error terror;
|
||||
uint32_t rd, wn;
|
||||
struct rpng_process *process = (struct rpng_process*)rpng->process;
|
||||
bool to_continue = (process->stream_backend->stream_get_avail_in(process->stream) > 0
|
||||
&& process->stream_backend->stream_get_avail_out(process->stream) > 0);
|
||||
bool to_continue = (process->avail_in > 0
|
||||
&& process->avail_out > 0);
|
||||
|
||||
if (!to_continue)
|
||||
goto end;
|
||||
|
||||
zstatus = process->stream_backend->stream_decompress_data_to_file_iterate(process->stream);
|
||||
zstatus = process->stream_backend->trans(process->stream, false, &rd, &wn, &terror);
|
||||
|
||||
switch (zstatus)
|
||||
{
|
||||
case 1:
|
||||
goto end;
|
||||
case -1:
|
||||
goto error;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!zstatus && terror != TRANS_STREAM_ERROR_BUFFER_FULL)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
process->avail_in -= rd;
|
||||
process->avail_out -= wn;
|
||||
process->total_out += wn;
|
||||
|
||||
if (terror)
|
||||
return 0;
|
||||
|
||||
end:
|
||||
process->stream_backend->stream_free(process->stream);
|
||||
process->stream = NULL;
|
||||
|
||||
*width = rpng->ihdr.width;
|
||||
*height = rpng->ihdr.height;
|
||||
@ -870,7 +872,7 @@ static struct rpng_process *rpng_process_init(rpng_t *rpng, unsigned *width, uns
|
||||
if (!process)
|
||||
return NULL;
|
||||
|
||||
process->stream_backend = file_archive_get_zlib_file_backend();
|
||||
process->stream_backend = trans_stream_get_zlib_inflate_backend();
|
||||
|
||||
png_pass_geom(&rpng->ihdr, rpng->ihdr.width,
|
||||
rpng->ihdr.height, NULL, NULL, &process->inflate_buf_size);
|
||||
@ -885,23 +887,22 @@ static struct rpng_process *rpng_process_init(rpng_t *rpng, unsigned *width, uns
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!process->stream_backend->stream_decompress_init(process->stream))
|
||||
{
|
||||
free(process);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inflate_buf = (uint8_t*)malloc(process->inflate_buf_size);
|
||||
if (!inflate_buf)
|
||||
goto error;
|
||||
|
||||
process->inflate_buf = inflate_buf;
|
||||
process->stream_backend->stream_set(
|
||||
process->avail_in = rpng->idat_buf.size;
|
||||
process->avail_out = process->inflate_buf_size;
|
||||
process->total_out = 0;
|
||||
process->stream_backend->set_in(
|
||||
process->stream,
|
||||
rpng->idat_buf.size,
|
||||
process->inflate_buf_size,
|
||||
rpng->idat_buf.data,
|
||||
process->inflate_buf);
|
||||
rpng->idat_buf.size);
|
||||
process->stream_backend->set_out(
|
||||
process->stream,
|
||||
process->inflate_buf,
|
||||
process->inflate_buf_size);
|
||||
|
||||
return process;
|
||||
|
||||
@ -1130,7 +1131,8 @@ void rpng_free(rpng_t *rpng)
|
||||
{
|
||||
if (rpng->process->stream_backend)
|
||||
rpng->process->stream_backend->stream_free(rpng->process->stream);
|
||||
free(rpng->process->stream);
|
||||
else
|
||||
free(rpng->process->stream);
|
||||
}
|
||||
free(rpng->process);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include <encodings/crc32.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <file/archive_file.h>
|
||||
#include <streams/trans_stream.h>
|
||||
|
||||
#include "rpng_internal.h"
|
||||
|
||||
@ -213,7 +213,7 @@ static bool rpng_save_image(const char *path,
|
||||
bool ret = true;
|
||||
struct png_ihdr ihdr = {0};
|
||||
|
||||
const struct file_archive_file_backend *stream_backend = NULL;
|
||||
const struct trans_stream_backend *stream_backend = NULL;
|
||||
size_t encode_buf_size = 0;
|
||||
uint8_t *encode_buf = NULL;
|
||||
uint8_t *deflate_buf = NULL;
|
||||
@ -225,11 +225,13 @@ static bool rpng_save_image(const char *path,
|
||||
uint8_t *prev_encoded = NULL;
|
||||
uint8_t *encode_target = NULL;
|
||||
void *stream = NULL;
|
||||
uint32_t total_in = 0;
|
||||
uint32_t total_out = 0;
|
||||
RFILE *file = filestream_open(path, RFILE_MODE_WRITE, -1);
|
||||
if (!file)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend = file_archive_get_zlib_file_backend();
|
||||
stream_backend = trans_stream_get_zlib_deflate_backend();
|
||||
|
||||
if (filestream_write(file, png_magic, sizeof(png_magic)) != sizeof(png_magic))
|
||||
GOTO_END_ERROR();
|
||||
@ -328,26 +330,23 @@ static bool rpng_save_image(const char *path,
|
||||
if (!stream)
|
||||
GOTO_END_ERROR();
|
||||
|
||||
stream_backend->stream_set(
|
||||
stream_backend->set_in(
|
||||
stream,
|
||||
encode_buf_size,
|
||||
encode_buf_size * 2,
|
||||
encode_buf,
|
||||
deflate_buf + 8);
|
||||
encode_buf_size);
|
||||
stream_backend->set_out(
|
||||
stream,
|
||||
deflate_buf + 8,
|
||||
encode_buf_size * 2);
|
||||
|
||||
stream_backend->stream_compress_init(stream, 9);
|
||||
|
||||
if (stream_backend->stream_compress_data_to_file(stream) != 1)
|
||||
if (!stream_backend->trans(stream, true, &total_in, &total_out, NULL))
|
||||
{
|
||||
stream_backend->stream_compress_free(stream);
|
||||
GOTO_END_ERROR();
|
||||
}
|
||||
|
||||
stream_backend->stream_compress_free(stream);
|
||||
|
||||
memcpy(deflate_buf + 4, "IDAT", 4);
|
||||
dword_write_be(deflate_buf + 0, ((uint32_t)stream_backend->stream_get_total_out(stream)));
|
||||
if (!png_write_idat(file, deflate_buf, ((size_t)stream_backend->stream_get_total_out(stream) + 8)))
|
||||
dword_write_be(deflate_buf + 0, ((uint32_t)total_out));
|
||||
if (!png_write_idat(file, deflate_buf, ((size_t)total_out + 8)))
|
||||
GOTO_END_ERROR();
|
||||
|
||||
if (!png_write_iend(file))
|
||||
|
@ -121,19 +121,9 @@ struct file_archive_file_backend
|
||||
{
|
||||
void *(*stream_new)(void);
|
||||
void (*stream_free)(void *);
|
||||
void (*stream_set)(void *, uint32_t, uint32_t,
|
||||
const uint8_t *, uint8_t *);
|
||||
uint32_t (*stream_get_avail_in)(void*);
|
||||
uint32_t (*stream_get_avail_out)(void*);
|
||||
uint64_t (*stream_get_total_out)(void*);
|
||||
void (*stream_decrement_total_out)(void *, unsigned);
|
||||
bool (*stream_decompress_init)(void *);
|
||||
bool (*stream_decompress_data_to_file_init)(
|
||||
file_archive_file_handle_t *, const uint8_t *, uint32_t, uint32_t);
|
||||
int (*stream_decompress_data_to_file_iterate)(void *);
|
||||
void (*stream_compress_init)(void *, int);
|
||||
void (*stream_compress_free)(void *);
|
||||
int (*stream_compress_data_to_file)(void *);
|
||||
uint32_t (*stream_crc_calculate)(uint32_t, const uint8_t *, size_t);
|
||||
int (*compressed_file_read)(const char *path, const char *needle, void **buf,
|
||||
const char *optional_outfile);
|
||||
|
@ -38,9 +38,10 @@
|
||||
enum trans_stream_error
|
||||
{
|
||||
TRANS_STREAM_ERROR_NONE = 0,
|
||||
TRANS_STREAM_ERROR_ALLOCATION_FAILURE,
|
||||
TRANS_STREAM_ERROR_INVALID,
|
||||
TRANS_STREAM_ERROR_BUFFER_FULL,
|
||||
TRANS_STREAM_ERROR_AGAIN, /* more work to do */
|
||||
TRANS_STREAM_ERROR_ALLOCATION_FAILURE, /* malloc failure */
|
||||
TRANS_STREAM_ERROR_INVALID, /* invalid state */
|
||||
TRANS_STREAM_ERROR_BUFFER_FULL, /* output buffer full */
|
||||
TRANS_STREAM_ERROR_OTHER
|
||||
};
|
||||
|
||||
|
@ -60,7 +60,7 @@ static void zlib_deflate_set_in(void *data, const uint8_t *in, uint32_t in_size)
|
||||
z->z.avail_in = in_size;
|
||||
if (!z->inited)
|
||||
{
|
||||
deflateInit(&z->z, Z_DEFAULT_COMPRESSION);
|
||||
deflateInit(&z->z, 9);
|
||||
z->inited = true;
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,7 @@ static void zlib_inflate_set_in(void *data, const uint8_t *in, uint32_t in_size)
|
||||
z->z.avail_in = in_size;
|
||||
if (!z->inited)
|
||||
{
|
||||
deflateInit(&z->z, Z_DEFAULT_COMPRESSION);
|
||||
inflateInit(&z->z);
|
||||
z->inited = true;
|
||||
}
|
||||
}
|
||||
@ -89,46 +89,61 @@ static bool zlib_deflate_trans(
|
||||
uint32_t *rd, uint32_t *wn,
|
||||
enum trans_stream_error *error)
|
||||
{
|
||||
int ret;
|
||||
int zret;
|
||||
bool ret;
|
||||
uint32_t pre_avail_in, pre_avail_out;
|
||||
struct zlib_trans_stream *zt = (struct zlib_trans_stream *) data;
|
||||
z_stream *z = &zt->z;
|
||||
|
||||
if (!zt->inited)
|
||||
{
|
||||
deflateInit(z, Z_DEFAULT_COMPRESSION);
|
||||
deflateInit(z, 9);
|
||||
zt->inited = true;
|
||||
}
|
||||
|
||||
pre_avail_in = z->avail_in;
|
||||
pre_avail_out = z->avail_out;
|
||||
ret = deflate(z, flush ? Z_FINISH : Z_NO_FLUSH);
|
||||
zret = deflate(z, flush ? Z_FINISH : Z_NO_FLUSH);
|
||||
|
||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||
if (zret == Z_OK)
|
||||
{
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_AGAIN;
|
||||
}
|
||||
else if (zret == Z_STREAM_END)
|
||||
{
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_OTHER;
|
||||
return false;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
*error = TRANS_STREAM_ERROR_NONE;
|
||||
if (z->avail_out == 0)
|
||||
{
|
||||
/* Filled buffer, maybe an error */
|
||||
if (z->avail_in != 0)
|
||||
*error = TRANS_STREAM_ERROR_BUFFER_FULL;
|
||||
{
|
||||
ret = false;
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_BUFFER_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
*rd = z->avail_in - pre_avail_in;
|
||||
*wn = z->avail_out - pre_avail_out;
|
||||
*rd = pre_avail_in - z->avail_in;
|
||||
*wn = pre_avail_out - z->avail_out;
|
||||
|
||||
if (flush && !*error)
|
||||
if (flush && zret == Z_STREAM_END)
|
||||
{
|
||||
deflateEnd(z);
|
||||
zt->inited = false;
|
||||
}
|
||||
|
||||
return !*error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool zlib_inflate_trans(
|
||||
@ -136,7 +151,8 @@ static bool zlib_inflate_trans(
|
||||
uint32_t *rd, uint32_t *wn,
|
||||
enum trans_stream_error *error)
|
||||
{
|
||||
int ret;
|
||||
int zret;
|
||||
bool ret;
|
||||
uint32_t pre_avail_in, pre_avail_out;
|
||||
struct zlib_trans_stream *zt = (struct zlib_trans_stream *) data;
|
||||
z_stream *z = &zt->z;
|
||||
@ -149,33 +165,47 @@ static bool zlib_inflate_trans(
|
||||
|
||||
pre_avail_in = z->avail_in;
|
||||
pre_avail_out = z->avail_out;
|
||||
ret = inflate(z, flush ? Z_FINISH : Z_NO_FLUSH);
|
||||
zret = inflate(z, flush ? Z_FINISH : Z_NO_FLUSH);
|
||||
|
||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||
if (zret == Z_OK)
|
||||
{
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_AGAIN;
|
||||
}
|
||||
else if (zret == Z_STREAM_END)
|
||||
{
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_OTHER;
|
||||
return false;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
*error = TRANS_STREAM_ERROR_NONE;
|
||||
if (z->avail_out == 0)
|
||||
{
|
||||
/* Filled buffer, maybe an error */
|
||||
if (z->avail_in != 0)
|
||||
*error = TRANS_STREAM_ERROR_BUFFER_FULL;
|
||||
{
|
||||
ret = false;
|
||||
if (error)
|
||||
*error = TRANS_STREAM_ERROR_BUFFER_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
*rd = z->avail_in - pre_avail_in;
|
||||
*wn = z->avail_out - pre_avail_out;
|
||||
*rd = pre_avail_in - z->avail_in;
|
||||
*wn = pre_avail_out - z->avail_out;
|
||||
|
||||
if (flush && !*error)
|
||||
if (flush && zret == Z_STREAM_END)
|
||||
{
|
||||
inflateEnd(z);
|
||||
zt->inited = false;
|
||||
}
|
||||
|
||||
return !*error;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct trans_stream_backend zlib_deflate_backend = {
|
||||
|
Loading…
Reference in New Issue
Block a user