diff --git a/png.c b/png.c index 88cf9e743a..f6f0ece04e 100644 --- a/png.c +++ b/png.c @@ -699,6 +699,9 @@ png_get_io_ptr(png_const_structrp png_ptr) * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a * function of your own because "FILE *" isn't necessarily available. */ +#ifdef png_init_io +#undef png_init_io +#endif void PNGAPI png_init_io(png_structrp png_ptr, png_FILE_p fp) { @@ -711,6 +714,36 @@ png_init_io(png_structrp png_ptr, png_FILE_p fp) } # endif +void PNGAPI +png_init_io2(png_structrp png_ptr, png_FILE_p fp, png_fread_ptr fread_fn, + png_fwrite_ptr fwrite_fn, png_fflush_ptr fflush_fn) +{ + if (png_ptr->read_data_fn != NULL) + { + png_init_read_io(png_ptr, fp, fread_fn); + } + else + { + png_init_write_io(png_ptr, fp, fwrite_fn, fflush_fn); + } +} + +void PNGAPI +png_init_read_io(png_structrp png_ptr, png_FILE_p fp, png_fread_ptr fread_fn) +{ + png_debug(1, "in png_init_read_io"); + png_set_read_fn2(png_ptr, fp, png_default_read_data, fread_fn); +} + +void PNGAPI +png_init_write_io(png_structrp png_ptr, png_FILE_p fp, png_fwrite_ptr fwrite_fn, + png_fflush_ptr fflush_fn) +{ + png_debug(1, "in png_init_write_io"); + png_set_write_fn2(png_ptr, fp, png_default_write_data, png_default_flush, + fwrite_fn, fflush_fn); +} + # ifdef PNG_SAVE_INT_32_SUPPORTED /* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 * defines a cast of a signed integer to an unsigned integer either to preserve diff --git a/png.h b/png.h index cba3e889e2..2a7fdec713 100644 --- a/png.h +++ b/png.h @@ -811,6 +811,12 @@ typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, int)); +typedef PNG_CALLBACK(size_t, *png_fread_ptr, (png_voidp, png_size_t, + png_size_t, png_FILE_p)); +typedef PNG_CALLBACK(size_t, *png_fwrite_ptr, (png_const_voidp, png_size_t, + png_size_t, png_FILE_p)); +typedef PNG_CALLBACK(int, *png_fflush_ptr, (png_FILE_p)); + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); @@ -1589,6 +1595,29 @@ PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, #ifdef PNG_STDIO_SUPPORTED /* Initialize the input/output for the PNG file to the default functions. */ PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); +PNG_EXPORT(250, void, png_init_io2, (png_structrp png_ptr, png_FILE_p fp, + png_fread_ptr fread_fn, png_fwrite_ptr fwrite_fn, + png_fflush_ptr fflush_fn)); + +static inline png_size_t +png_fread_(png_voidp buf, png_size_t sz, png_size_t count, png_FILE_p fp) +{ + return fread(buf, sz, count, fp); +} + +static inline png_size_t +png_fwrite_(png_const_voidp buf, png_size_t sz, png_size_t count, png_FILE_p fp) +{ + return fwrite(buf, sz, count, fp); +} + +static inline int png_fflush_(png_FILE_p fp) +{ + return fflush(fp); +} + +#define png_init_io(png_ptr, fp) png_init_io2((png_ptr), (fp), png_fread_, \ + png_fwrite_, png_fflush_) #endif /* Replace the (error and abort), and warning functions with user @@ -1618,10 +1647,18 @@ PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); +/* Initialize the output for the PNG file. */ +PNG_EXPORT(251, void, png_init_write_io, (png_structrp png_ptr, png_FILE_p fp, + png_fwrite_ptr fwrite_fn, png_fflush_ptr fflush_fn)); + /* Replace the default data input function with a user supplied one. */ PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn)); +/* Initialize the input for the PNG file. */ +PNG_EXPORT(252, void, png_init_read_io, (png_structrp png_ptr, png_FILE_p fp, + png_fread_ptr fread_fn)); + /* Return the user pointer associated with the I/O functions */ PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); @@ -3266,7 +3303,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, * one to use is one more than this.) */ #ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(249); + PNG_EXPORT_LAST_ORDINAL(252); #endif #ifdef __cplusplus diff --git a/pngpriv.h b/pngpriv.h index a7851cd5c5..c1a8609d8d 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -1054,6 +1054,14 @@ PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, png_bytep data, png_size_t length),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_set_read_fn2, (png_structrp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn, png_fread_ptr fread_fn), + PNG_EMPTY); + +PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_set_write_fn2, (png_structrp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn, + png_fwrite_ptr fwrite_fn, png_fflush_ptr fflush_fn), PNG_EMPTY); + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, png_bytep buffer, png_size_t length),PNG_EMPTY); diff --git a/pngrio.c b/pngrio.c index 7e26e855ca..07444d8903 100644 --- a/pngrio.c +++ b/pngrio.c @@ -40,7 +40,6 @@ png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) png_error(png_ptr, "Call to NULL read function"); } -#ifdef PNG_STDIO_SUPPORTED /* This is the function that does the actual reading of data. If you are * not reading from a standard C stream, you should create a replacement * read_data function and use it at run time with png_set_read_fn(), rather @@ -51,18 +50,47 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; - if (png_ptr == NULL) + if (png_ptr == NULL || png_ptr->fread_fn == NULL) return; /* fread() returns 0 on error, so it is OK to store this in a png_size_t * instead of an int, which is what fread() actually returns. */ - check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); + check = png_ptr->fread_fn(data, 1, length, png_voidcast(png_FILE_p, + png_ptr->io_ptr)); if (check != length) png_error(png_ptr, "Read Error"); } + +void /* PRIVATE */ +png_set_read_fn2(png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn, png_fread_ptr fread_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = io_ptr; + png_ptr->read_data_fn = read_data_fn; + png_ptr->fread_fn = fread_fn; + +#ifdef PNG_WRITE_SUPPORTED + /* It is an error to write to a read device */ + if (png_ptr->write_data_fn != NULL) + { + png_ptr->write_data_fn = NULL; + png_ptr->fwrite_fn = NULL; + png_warning(png_ptr, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } +#endif + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = NULL; + png_ptr->fflush_fn = NULL; #endif +} /* This function allows the application to supply a new input function * for libpng if standard C streams aren't being used. @@ -87,34 +115,14 @@ void PNGAPI png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn) { - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - + png_fread_ptr fread_fn = NULL; #ifdef PNG_STDIO_SUPPORTED - if (read_data_fn != NULL) - png_ptr->read_data_fn = read_data_fn; - - else - png_ptr->read_data_fn = png_default_read_data; -#else - png_ptr->read_data_fn = read_data_fn; -#endif - -#ifdef PNG_WRITE_SUPPORTED - /* It is an error to write to a read device */ - if (png_ptr->write_data_fn != NULL) + if (read_data_fn == NULL) { - png_ptr->write_data_fn = NULL; - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); + read_data_fn = png_default_read_data; + fread_fn = png_fread_; } #endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->output_flush_fn = NULL; -#endif + png_set_read_fn2(png_ptr, io_ptr, read_data_fn, fread_fn); } #endif /* READ */ diff --git a/pngstruct.h b/pngstruct.h index afef2c028e..07313d8695 100644 --- a/pngstruct.h +++ b/pngstruct.h @@ -478,6 +478,12 @@ struct png_struct_def #if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) png_colorspace colorspace; #endif +#endif + + png_fread_ptr fread_fn; /* function for reading input data */ + png_fwrite_ptr fwrite_fn; /* function for writing output data */ +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_fflush_ptr fflush_fn; /* Function for flushing output */ #endif }; #endif /* PNGSTRUCT_H */ diff --git a/pngwio.c b/pngwio.c index 37c7c3a7f0..84156fcce5 100644 --- a/pngwio.c +++ b/pngwio.c @@ -52,10 +52,10 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; - if (png_ptr == NULL) + if (png_ptr == NULL || png_ptr->fwrite_fn == NULL) return; - check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); + check = png_ptr->fwrite_fn(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); if (check != length) png_error(png_ptr, "Write Error"); @@ -74,21 +74,54 @@ png_flush(png_structrp png_ptr) (*(png_ptr->output_flush_fn))(png_ptr); } -# ifdef PNG_STDIO_SUPPORTED void PNGCBAPI png_default_flush(png_structp png_ptr) { png_FILE_p io_ptr; - if (png_ptr == NULL) + if (png_ptr == NULL || png_ptr->fflush_fn == NULL) return; io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); - fflush(io_ptr); + png_ptr->fflush_fn(io_ptr); } -# endif #endif +void /* PRIVATE */ +png_set_write_fn2(png_structrp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn, + png_fwrite_ptr fwrite_fn, png_fflush_ptr fflush_fn) +{ + if (png_ptr == NULL) + return; + + png_ptr->io_ptr = io_ptr; + + png_ptr->write_data_fn = write_data_fn; + png_ptr->fwrite_fn = fwrite_fn; + +#ifdef PNG_WRITE_FLUSH_SUPPORTED + png_ptr->output_flush_fn = output_flush_fn; + png_ptr->fflush_fn = fflush_fn; +#else + PNG_UNUSED(output_flush_fn) + PNG_UNUSED(fflush_fn) +#endif /* WRITE_FLUSH */ + +#ifdef PNG_READ_SUPPORTED + /* It is an error to read while writing a png file */ + if (png_ptr->read_data_fn != NULL) + { + png_ptr->read_data_fn = NULL; + png_ptr->fread_fn = NULL; + + png_warning(png_ptr, + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); + } +#endif +} + /* This function allows the application to supply new output functions for * libpng if standard C streams aren't being used. * @@ -122,47 +155,24 @@ void PNGAPI png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) { - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - + png_fwrite_ptr fwrite_fn = NULL; + png_fflush_ptr fflush_fn = NULL; #ifdef PNG_STDIO_SUPPORTED - if (write_data_fn != NULL) - png_ptr->write_data_fn = write_data_fn; - - else - png_ptr->write_data_fn = png_default_write_data; -#else - png_ptr->write_data_fn = write_data_fn; + if (write_data_fn == NULL) + { + write_data_fn = png_default_write_data; + fwrite_fn = png_fwrite_; + } #endif -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED - - if (output_flush_fn != NULL) - png_ptr->output_flush_fn = output_flush_fn; - - else - png_ptr->output_flush_fn = png_default_flush; - -# else - png_ptr->output_flush_fn = output_flush_fn; -# endif -#else - PNG_UNUSED(output_flush_fn) -#endif /* WRITE_FLUSH */ - -#ifdef PNG_READ_SUPPORTED - /* It is an error to read while writing a png file */ - if (png_ptr->read_data_fn != NULL) +#if defined(PNG_WRITE_FLUSH_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) + if (output_flush_fn == NULL) { - png_ptr->read_data_fn = NULL; - - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); + output_flush_fn = png_default_flush; + fflush_fn = png_fflush_; } #endif + png_set_write_fn2(png_ptr, io_ptr, write_data_fn, output_flush_fn, + fwrite_fn, fflush_fn); } #endif /* WRITE */ diff --git a/scripts/symbols.def b/scripts/symbols.def index 2a97f4bd34..d42dc9f0bc 100644 --- a/scripts/symbols.def +++ b/scripts/symbols.def @@ -254,3 +254,6 @@ EXPORTS png_set_eXIf @247 png_get_eXIf_1 @248 png_set_eXIf_1 @249 + png_init_io2 @250 + png_init_write_io @251 + png_init_read_io @252