Skip to content

Commit

Permalink
Generalize image file support for ccv and png2smzx. (#309)
Browse files Browse the repository at this point in the history
* Add image_file.c image loading abstraction (PNG, BMP, NetPBM, farbfeld, raw; file or stdin).
* Relicense ccv to GPL 2+ (with permission of Lancer-X).
* Add image_file unit tests.
  • Loading branch information
AliceLR committed Jul 18, 2021
1 parent a0fce42 commit 786682a
Show file tree
Hide file tree
Showing 56 changed files with 2,476 additions and 288 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -149,6 +149,7 @@ unit/.build/
unit/editor/.build/
unit/io/.build/
unit/network/.build/
unit/utils/.build/
/*.js
/*.js.mem
/*.js.orig.js
Expand Down
5 changes: 1 addition & 4 deletions Makefile
Expand Up @@ -492,17 +492,14 @@ ifeq (${BUILD_UTILS},1)
${MKDIR} ${build}/utils
${CP} ${checkres} ${downver} ${build}/utils
${CP} ${hlp2txt} ${txt2hlp} ${build}/utils
${CP} ${ccv} ${build}/utils
${CP} ${ccv} ${png2smzx} ${build}/utils
@if [ -f "${checkres}.debug" ]; then cp ${checkres}.debug ${build}/utils; fi
@if [ -f "${downver}.debug" ]; then cp ${downver}.debug ${build}/utils; fi
@if [ -f "${hlp2txt}.debug" ]; then cp ${hlp2txt}.debug ${build}/utils; fi
@if [ -f "${txt2hlp}.debug" ]; then cp ${txt2hlp}.debug ${build}/utils; fi
@if [ -f "${ccv}.debug" ]; then cp ${ccv}.debug ${build}/utils; fi
ifeq (${LIBPNG},1)
${CP} ${png2smzx} ${build}/utils
@if [ -f "${png2smzx}.debug" ]; then cp ${png2smzx}.debug ${build}/utils; fi
endif
endif

${build}/docs: ${build}
${MKDIR} -p ${build}/docs
Expand Down
1 change: 1 addition & 0 deletions arch/install.inc
Expand Up @@ -178,6 +178,7 @@ ifeq (${BUILD_UTILS},1)
${DESTDIR}${BINDIR}/downver \
${DESTDIR}${BINDIR}/hlp2txt \
${DESTDIR}${BINDIR}/txt2hlp \
${DESTDIR}${BINDIR}/png2smzx \
${DESTDIR}${BINDIR}/ccv
endif
@echo Done.
9 changes: 9 additions & 0 deletions docs/changelog.txt
Expand Up @@ -150,6 +150,13 @@ USERS
intermediate render and skipping pixel checks for blank chars.
+ libxmp playback improvements for GDM, AMF, and OctaMED modules
as well as general stability improvements.
+ ccv and png2smzx now both support the following image formats:
PNG (with libpng enabled), BMP (uncompressed, RLE8, RLE4),
NetPBM (PBM, PGM, PPM, PNM, PAM), farbfeld. png2smzx will now
build when libpng support is disabled, though it won't support
loading PNGs with this configuration.
+ ccv and png2smzx now both support streaming image data from
stdin using the input filename "-".
- Removed GL4ES from the GLSL blacklist.
- Removed 3DS CIA support. (asie)

Expand Down Expand Up @@ -177,6 +184,8 @@ DEVELOPERS
+ Replaced the macro-based mixers in sampled_stream.c with more
maintainable template-based mixers.
+ Updated libxmp to 4.5.0.
+ Relicensed ccv from GPL 3 to GPL 2+ to match the rest of MZX.
(Lancer-X)


November 22nd, 2020 - MZX 2.92f
Expand Down
64 changes: 44 additions & 20 deletions src/pngops.c
Expand Up @@ -61,7 +61,7 @@ int png_write_screen(uint8_t *pixels, struct rgb_color *pal, int count,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);

pal_ptr = cmalloc(count * sizeof(png_color));
pal_ptr = (png_colorp)cmalloc(count * sizeof(png_color));
if(!pal_ptr)
goto exit_free_close;

Expand All @@ -77,7 +77,7 @@ int png_write_screen(uint8_t *pixels, struct rgb_color *pal, int count,
png_write_info(png_ptr, info_ptr);
png_set_packing(png_ptr);

row_ptrs = cmalloc(sizeof(png_bytep) * 350);
row_ptrs = (png_bytep *)cmalloc(sizeof(png_bytep) * 350);
if(!row_ptrs)
goto exit_free_close;

Expand Down Expand Up @@ -137,7 +137,7 @@ int png_write_screen_32bpp(uint32_t *pixels, const char *name)
png_write_info(png_ptr, info_ptr);
png_set_packing(png_ptr);

row_ptrs = cmalloc(sizeof(png_bytep) * 350);
row_ptrs = (png_bytep *)cmalloc(sizeof(png_bytep) * 350);
if(!row_ptrs)
goto exit_free_close;

Expand Down Expand Up @@ -165,33 +165,41 @@ int png_write_screen_32bpp(uint32_t *pixels, const char *name)

#ifdef NEED_PNG_READ_FILE

void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
static boolean png_check_stream(FILE *fp)
{
png_byte header[8];

if(fread(header, 1, 8, fp) < 8)
return false;

if(png_sig_cmp(header, 0, 8))
return false;

return true;
}

/**
* If `checked` is true, the first 8 bytes of the stream have already been
* read and verified to be the PNG signature.
*/
void *png_read_stream(FILE *fp, png_uint_32 *_w, png_uint_32 *_h, boolean checked,
check_w_h_constraint_t constraint, rgba_surface_allocator_t allocator)
{
png_uint_32 i, w, h, stride;
png_byte header[8];
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_bytep * volatile row_ptrs = NULL;
void * volatile s = NULL;
void *pixels;
int type;
int bpp;
FILE *f;

f = fopen_unsafe(name, "rb");
if(!f)
if(!checked && !png_check_stream(fp))
goto exit_out;

if(fread(header, 1, 8, f) < 8)
goto exit_close;

if(png_sig_cmp(header, 0, 8))
goto exit_close;

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
goto exit_close;
goto exit_out;

info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr)
Expand All @@ -200,14 +208,14 @@ void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
if(setjmp(png_jmpbuf(png_ptr)))
goto exit_free_close;

png_init_io(png_ptr, f);
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bpp, &type, NULL, NULL, NULL);

if(!constraint(w, h))
{
warn("Requested image '%s' failed dimension checks.\n", name);
warn("Requested image failed dimension checks.\n");
goto exit_free_close;
}

Expand Down Expand Up @@ -235,7 +243,7 @@ void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
png_read_update_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &w, &h, &bpp, &type, NULL, NULL, NULL);

row_ptrs = cmalloc(sizeof(png_bytep) * h);
row_ptrs = (png_bytep *)cmalloc(sizeof(png_bytep) * h);
if(!row_ptrs)
goto exit_free_close;

Expand All @@ -256,10 +264,26 @@ void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
exit_free_close:
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
free(row_ptrs);
exit_close:
fclose(f);
exit_out:
return s;
}

void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
check_w_h_constraint_t constraint, rgba_surface_allocator_t allocator)
{
void *s;

FILE *fp = fopen_unsafe(name, "rb");
if(!fp)
return NULL;

s = png_read_stream(fp, _w, _h, false, constraint, allocator);
fclose(fp);

if(!s)
warn("Failed to load '%s'\n", name);

return s;
}

#endif // NEED_PNG_READ_FILE
4 changes: 4 additions & 0 deletions src/pngops.h
Expand Up @@ -35,6 +35,7 @@ __M_BEGIN_DECLS

#include "graphics.h"
#include <stdint.h>
#include <stdio.h>

int png_write_screen(uint8_t *pixels, struct rgb_color *pal, int count,
const char *name);
Expand All @@ -48,6 +49,9 @@ typedef boolean (*check_w_h_constraint_t)(png_uint_32 w, png_uint_32 h);
typedef void *(*rgba_surface_allocator_t)(png_uint_32 w, png_uint_32 h,
png_uint_32 *stride, void **pixels);

void *png_read_stream(FILE *fp, png_uint_32 *_w, png_uint_32 *_h, boolean checked,
check_w_h_constraint_t constraint, rgba_surface_allocator_t allocator);

void *png_read_file(const char *name, png_uint_32 *_w, png_uint_32 *_h,
check_w_h_constraint_t constraint, rgba_surface_allocator_t allocator);

Expand Down
24 changes: 15 additions & 9 deletions src/utils/Makefile.in
Expand Up @@ -17,6 +17,13 @@ utils_obj = src/utils/.build
utils_cflags := ${LIBPNG_CFLAGS} -DUTILS_LIBSPEC=

zip_objs := ${io_obj}/vio.o ${io_obj}/zip.o ${io_obj}/zip_stream.o
img_objs := ${utils_obj}/image_file.o
img_flags :=

ifneq (${LIBPNG},)
img_objs += ${core_obj}/pngops.o
img_flags += ${LIBPNG_LDFLAGS} ${ZLIB_LDFLAGS}
endif

checkres := ${utils_src}/checkres${BINEXT}
checkres_objs := ${utils_obj}/checkres.o \
Expand All @@ -39,12 +46,14 @@ txt2hlp_objs := ${utils_obj}/txt2hlp.o

png2smzx := ${utils_src}/png2smzx${BINEXT}
png2smzx_objs := ${utils_obj}/png2smzx.o ${utils_obj}/smzxconv.o
png2smzx_objs += ${core_obj}/pngops.o
png2smzx_objs += ${img_objs}
png2smzx_objs += ${io_obj}/path.o ${io_obj}/vio.o
png2smzx_ldflags := ${LIBPNG_LDFLAGS} ${ZLIB_LDFLAGS}
png2smzx_ldflags := ${img_flags}

ccv := ${utils_src}/ccv${BINEXT}
ccv_objs := ${utils_obj}/ccv.o
ccv_objs += ${img_objs}
ccv_ldflags := ${img_flags}

${utils_obj}/%.o: ${utils_src}/%.c src/config.h
$(if ${V},,@echo " CC " $<)
Expand Down Expand Up @@ -91,19 +100,16 @@ ${png2smzx}: ${png2smzx_objs}
${ccv}: ${ccv_objs}
$(if ${V},,@echo " LINK " ${ccv})
${CC} ${ccv_objs} -o ${ccv} \
${ARCH_EXE_LDFLAGS} ${LDFLAGS}
${ARCH_EXE_LDFLAGS} ${LDFLAGS} ${ccv_ldflags}

utils: $(filter-out $(wildcard ${utils_obj}), ${utils_obj})

utils: ${checkres} ${downver} ${hlp2html} ${hlp2txt} ${txt2hlp} ${ccv}

ifeq (${LIBPNG},1)
utils: ${png2smzx}
utils.debug: ${png2smzx}.debug
endif
utils: ${checkres} ${downver} ${hlp2html} ${hlp2txt} ${txt2hlp}
utils: ${ccv} ${png2smzx}

utils.debug: ${checkres}.debug ${downver}.debug ${ccv}.debug
utils.debug: ${hlp2html}.debug ${hlp2txt}.debug ${txt2hlp}.debug
utils.debug: ${png2smzx}.debug

utils_clean:
$(if ${V},,@echo " RM " ${utils_obj})
Expand Down

0 comments on commit 786682a

Please sign in to comment.