blob: 10e919dd03819f62ba53a85acfcb4e4be176d9c8 [file] [log] [blame]
Guy Schalnate5a37791996-06-05 15:50:50 -05001
2/* pngwio.c - functions for data output
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Cosmin Trutaa8738932018-07-28 18:47:21 -04004 * Copyright (c) 2018 Cosmin Truta
Cosmin Truta46aedd82018-07-15 23:58:00 -04005 * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson
Cosmin Trutaa8738932018-07-28 18:47:21 -04006 * Copyright (c) 1996-1997 Andreas Dilger
7 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06008 *
Glenn Randers-Pehrsonbfbf8652009-06-26 21:46:52 -05009 * This code is released under the libpng license.
Glenn Randers-Pehrsonc332bbc2009-06-25 13:43:50 -050010 * For conditions of distribution and use, see the disclaimer
Glenn Randers-Pehrson037023b2009-06-24 10:27:36 -050011 * and license in png.h
Glenn Randers-Pehrson3e61d792009-06-24 09:31:28 -050012 *
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -050013 * This file provides a location for all output. Users who need
14 * special handling are expected to write functions that have the same
15 * arguments as these and perform similar functions, but that possibly
16 * use different output methods. Note that you shouldn't change these
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060017 * functions, but rather write replacement functions and then change
18 * them at run time with png_set_write_fn(...).
19 */
Guy Schalnate5a37791996-06-05 15:50:50 -050020
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -050021#include "pngpriv.h"
Guy Schalnate5a37791996-06-05 15:50:50 -050022
Glenn Randers-Pehrsonc3cd22b2010-03-08 21:10:25 -060023#ifdef PNG_WRITE_SUPPORTED
24
Guy Schalnate5a37791996-06-05 15:50:50 -050025/* Write the data to whatever output you are using. The default routine
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050026 * writes to a file pointer. Note that this routine sometimes gets called
27 * with very small lengths, so you should implement some kind of simple
28 * buffering if you are using unbuffered writes. This should never be asked
Glenn Randers-Pehrson8b83ff32015-08-13 20:57:18 -050029 * to write more than 64K on a 16-bit machine.
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050030 */
Guy Schalnate5a37791996-06-05 15:50:50 -050031
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050032void /* PRIVATE */
Cosmin Trutaa74aa9a2018-06-17 22:37:44 -040033png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length)
Guy Schalnate5a37791996-06-05 15:50:50 -050034{
Glenn Randers-Pehrsone600c512010-08-18 07:25:46 -050035 /* NOTE: write_data_fn must not change the buffer! */
Andreas Dilger47a0c421997-05-16 02:46:07 -050036 if (png_ptr->write_data_fn != NULL )
John Bowler40b26032011-12-22 08:09:15 -060037 (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
Glenn Randers-Pehrsondd706042016-07-15 11:20:46 -050038 length);
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050039
Guy Schalnate5a37791996-06-05 15:50:50 -050040 else
41 png_error(png_ptr, "Call to NULL write function");
42}
43
Glenn Randers-Pehrsondbd40142009-08-31 08:42:02 -050044#ifdef PNG_STDIO_SUPPORTED
Glenn Randers-Pehrson8686fff1998-05-21 09:27:50 -050045/* This is the function that does the actual writing of data. If you are
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050046 * not writing to a standard C stream, you should create a replacement
47 * write_data function and use it at run time with png_set_write_fn(), rather
48 * than changing the library.
49 */
Glenn Randers-Pehrsoneae8e362010-03-12 17:36:53 -060050void PNGCBAPI
Cosmin Trutaa74aa9a2018-06-17 22:37:44 -040051png_default_write_data(png_structp png_ptr, png_bytep data, size_t length)
Guy Schalnate5a37791996-06-05 15:50:50 -050052{
Cosmin Trutaa74aa9a2018-06-17 22:37:44 -040053 size_t check;
Guy Schalnate5a37791996-06-05 15:50:50 -050054
Glenn Randers-Pehrsond8eb62f2009-05-30 20:19:20 -050055 if (png_ptr == NULL)
56 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050057
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050058 check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050059
Guy Schalnate5a37791996-06-05 15:50:50 -050060 if (check != length)
Guy Schalnate5a37791996-06-05 15:50:50 -050061 png_error(png_ptr, "Write Error");
Guy Schalnate5a37791996-06-05 15:50:50 -050062}
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -060063#endif
Guy Schalnate5a37791996-06-05 15:50:50 -050064
65/* This function is called to output any data pending writing (normally
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050066 * to disk). After png_flush is called, there should be no data pending
67 * writing in any buffers.
68 */
Glenn Randers-Pehrsondbd40142009-08-31 08:42:02 -050069#ifdef PNG_WRITE_FLUSH_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050070void /* PRIVATE */
John Bowler5d567862011-12-24 09:12:00 -060071png_flush(png_structrp png_ptr)
Guy Schalnate5a37791996-06-05 15:50:50 -050072{
Andreas Dilger47a0c421997-05-16 02:46:07 -050073 if (png_ptr->output_flush_fn != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -050074 (*(png_ptr->output_flush_fn))(png_ptr);
75}
76
Glenn Randers-Pehrson6f6a91a2010-03-06 13:54:59 -060077# ifdef PNG_STDIO_SUPPORTED
Glenn Randers-Pehrsoneae8e362010-03-12 17:36:53 -060078void PNGCBAPI
Guy Schalnate5a37791996-06-05 15:50:50 -050079png_default_flush(png_structp png_ptr)
80{
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -050081 png_FILE_p io_ptr;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050082
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050083 if (png_ptr == NULL)
84 return;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -050085
John Bowlerbaeb6d12011-11-26 18:21:02 -060086 io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
Glenn Randers-Pehrson8fb550c2009-03-21 08:15:32 -050087 fflush(io_ptr);
Guy Schalnate5a37791996-06-05 15:50:50 -050088}
Glenn Randers-Pehrson6f6a91a2010-03-06 13:54:59 -060089# endif
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -060090#endif
Guy Schalnate5a37791996-06-05 15:50:50 -050091
92/* This function allows the application to supply new output functions for
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050093 * libpng if standard C streams aren't being used.
94 *
95 * This function takes as its arguments:
96 * png_ptr - pointer to a png output data structure
97 * io_ptr - pointer to user supplied structure containing info about
98 * the output functions. May be NULL.
99 * write_data_fn - pointer to a new output function that takes as its
100 * arguments a pointer to a png_struct, a pointer to
101 * data to be written, and a 32-bit unsigned int that is
102 * the number of bytes to be written. The new write
103 * function should call png_error(png_ptr, "Error msg")
104 * to exit and output any fatal error messages. May be
105 * NULL, in which case libpng's default function will
106 * be used.
107 * flush_data_fn - pointer to a new flush function that takes as its
108 * arguments a pointer to a png_struct. After a call to
109 * the flush function, there should be no data in any buffers
110 * or pending transmission. If the output method doesn't do
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500111 * any buffering of output, a function prototype must still be
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500112 * supplied although it doesn't have to do anything. If
113 * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
114 * time, output_flush_fn will be ignored, although it must be
115 * supplied for compatibility. May be NULL, in which case
116 * libpng's default function will be used, if
117 * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
118 * a good idea if io_ptr does not point to a standard
119 * *FILE structure.
120 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500121void PNGAPI
John Bowler5d567862011-12-24 09:12:00 -0600122png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
Glenn Randers-Pehrson6f6a91a2010-03-06 13:54:59 -0600123 png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
Guy Schalnate5a37791996-06-05 15:50:50 -0500124{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500125 if (png_ptr == NULL)
126 return;
127
Guy Schalnate5a37791996-06-05 15:50:50 -0500128 png_ptr->io_ptr = io_ptr;
129
Glenn Randers-Pehrsondbd40142009-08-31 08:42:02 -0500130#ifdef PNG_STDIO_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -0500131 if (write_data_fn != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500132 png_ptr->write_data_fn = write_data_fn;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500133
Guy Schalnate5a37791996-06-05 15:50:50 -0500134 else
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -0500135 png_ptr->write_data_fn = png_default_write_data;
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600136#else
137 png_ptr->write_data_fn = write_data_fn;
138#endif
Guy Schalnate5a37791996-06-05 15:50:50 -0500139
Glenn Randers-Pehrsondbd40142009-08-31 08:42:02 -0500140#ifdef PNG_WRITE_FLUSH_SUPPORTED
Glenn Randers-Pehrson6f6a91a2010-03-06 13:54:59 -0600141# ifdef PNG_STDIO_SUPPORTED
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500142
Andreas Dilger47a0c421997-05-16 02:46:07 -0500143 if (output_flush_fn != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500144 png_ptr->output_flush_fn = output_flush_fn;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500145
Guy Schalnate5a37791996-06-05 15:50:50 -0500146 else
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -0500147 png_ptr->output_flush_fn = png_default_flush;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500148
Glenn Randers-Pehrson6f6a91a2010-03-06 13:54:59 -0600149# else
Glenn Randers-Pehrson70e3f541998-01-03 22:40:55 -0600150 png_ptr->output_flush_fn = output_flush_fn;
Glenn Randers-Pehrson6f6a91a2010-03-06 13:54:59 -0600151# endif
Glenn Randers-Pehrsonc9120502013-11-22 14:58:04 -0600152#else
153 PNG_UNUSED(output_flush_fn)
Glenn Randers-Pehrsoncda68df2014-11-06 22:11:39 -0600154#endif /* WRITE_FLUSH */
Guy Schalnate5a37791996-06-05 15:50:50 -0500155
Glenn Randers-Pehrson88ecac62013-12-28 12:52:59 -0600156#ifdef PNG_READ_SUPPORTED
Guy Schalnate5a37791996-06-05 15:50:50 -0500157 /* It is an error to read while writing a png file */
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500158 if (png_ptr->read_data_fn != NULL)
159 {
160 png_ptr->read_data_fn = NULL;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500161
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500162 png_warning(png_ptr,
Glenn Randers-Pehrson92a3ef42010-03-31 21:50:21 -0500163 "Can't set both read_data_fn and write_data_fn in the"
164 " same structure");
Glenn Randers-Pehrsonf7d1a171998-06-06 15:31:35 -0500165 }
Glenn Randers-Pehrson88ecac62013-12-28 12:52:59 -0600166#endif
Guy Schalnate5a37791996-06-05 15:50:50 -0500167}
Glenn Randers-Pehrsoncda68df2014-11-06 22:11:39 -0600168#endif /* WRITE */