1 :
2 : /* pngwio.c - functions for data output
3 : *
4 : * Last changed in libpng 1.5.0 [January 6, 2011]
5 : * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 : * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 : * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 : *
9 : * This code is released under the libpng license.
10 : * For conditions of distribution and use, see the disclaimer
11 : * and license in png.h
12 : *
13 : * 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
17 : * functions, but rather write replacement functions and then change
18 : * them at run time with png_set_write_fn(...).
19 : */
20 :
21 : #include "pngpriv.h"
22 :
23 : #ifdef PNG_WRITE_SUPPORTED
24 :
25 : /* Write the data to whatever output you are using. The default routine
26 : * 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
29 : * to write more than 64K on a 16 bit machine.
30 : */
31 :
32 : void /* PRIVATE */
33 358 : png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length)
34 : {
35 : /* NOTE: write_data_fn must not change the buffer! */
36 358 : if (png_ptr->write_data_fn != NULL )
37 358 : (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length);
38 :
39 : else
40 0 : png_error(png_ptr, "Call to NULL write function");
41 358 : }
42 :
43 : #ifdef PNG_STDIO_SUPPORTED
44 : /* This is the function that does the actual writing of data. If you are
45 : * not writing to a standard C stream, you should create a replacement
46 : * write_data function and use it at run time with png_set_write_fn(), rather
47 : * than changing the library.
48 : */
49 : #ifndef USE_FAR_KEYWORD
50 : void PNGCBAPI
51 0 : png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
52 : {
53 : png_size_t check;
54 :
55 0 : if (png_ptr == NULL)
56 0 : return;
57 :
58 0 : check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
59 :
60 0 : if (check != length)
61 0 : png_error(png_ptr, "Write Error");
62 : }
63 : #else
64 : /* This is the model-independent version. Since the standard I/O library
65 : * can't handle far buffers in the medium and small models, we have to copy
66 : * the data.
67 : */
68 :
69 : #define NEAR_BUF_SIZE 1024
70 : #define MIN(a,b) (a <= b ? a : b)
71 :
72 : void PNGCBAPI
73 : png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
74 : {
75 : png_uint_32 check;
76 : png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
77 : png_FILE_p io_ptr;
78 :
79 : if (png_ptr == NULL)
80 : return;
81 :
82 : /* Check if data really is near. If so, use usual code. */
83 : near_data = (png_byte *)CVT_PTR_NOCHECK(data);
84 : io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
85 :
86 : if ((png_bytep)near_data == data)
87 : {
88 : check = fwrite(near_data, 1, length, io_ptr);
89 : }
90 :
91 : else
92 : {
93 : png_byte buf[NEAR_BUF_SIZE];
94 : png_size_t written, remaining, err;
95 : check = 0;
96 : remaining = length;
97 :
98 : do
99 : {
100 : written = MIN(NEAR_BUF_SIZE, remaining);
101 : png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
102 : err = fwrite(buf, 1, written, io_ptr);
103 :
104 : if (err != written)
105 : break;
106 :
107 : else
108 : check += err;
109 :
110 : data += written;
111 : remaining -= written;
112 : }
113 : while (remaining != 0);
114 : }
115 :
116 : if (check != length)
117 : png_error(png_ptr, "Write Error");
118 : }
119 :
120 : #endif
121 : #endif
122 :
123 : /* This function is called to output any data pending writing (normally
124 : * to disk). After png_flush is called, there should be no data pending
125 : * writing in any buffers.
126 : */
127 : #ifdef PNG_WRITE_FLUSH_SUPPORTED
128 : void /* PRIVATE */
129 0 : png_flush(png_structp png_ptr)
130 : {
131 0 : if (png_ptr->output_flush_fn != NULL)
132 0 : (*(png_ptr->output_flush_fn))(png_ptr);
133 0 : }
134 :
135 : # ifdef PNG_STDIO_SUPPORTED
136 : void PNGCBAPI
137 0 : png_default_flush(png_structp png_ptr)
138 : {
139 : png_FILE_p io_ptr;
140 :
141 0 : if (png_ptr == NULL)
142 0 : return;
143 :
144 0 : io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
145 0 : fflush(io_ptr);
146 : }
147 : # endif
148 : #endif
149 :
150 : /* This function allows the application to supply new output functions for
151 : * libpng if standard C streams aren't being used.
152 : *
153 : * This function takes as its arguments:
154 : * png_ptr - pointer to a png output data structure
155 : * io_ptr - pointer to user supplied structure containing info about
156 : * the output functions. May be NULL.
157 : * write_data_fn - pointer to a new output function that takes as its
158 : * arguments a pointer to a png_struct, a pointer to
159 : * data to be written, and a 32-bit unsigned int that is
160 : * the number of bytes to be written. The new write
161 : * function should call png_error(png_ptr, "Error msg")
162 : * to exit and output any fatal error messages. May be
163 : * NULL, in which case libpng's default function will
164 : * be used.
165 : * flush_data_fn - pointer to a new flush function that takes as its
166 : * arguments a pointer to a png_struct. After a call to
167 : * the flush function, there should be no data in any buffers
168 : * or pending transmission. If the output method doesn't do
169 : * any buffering of output, a function prototype must still be
170 : * supplied although it doesn't have to do anything. If
171 : * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
172 : * time, output_flush_fn will be ignored, although it must be
173 : * supplied for compatibility. May be NULL, in which case
174 : * libpng's default function will be used, if
175 : * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
176 : * a good idea if io_ptr does not point to a standard
177 : * *FILE structure.
178 : */
179 : void PNGAPI
180 52 : png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
181 : png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
182 : {
183 52 : if (png_ptr == NULL)
184 0 : return;
185 :
186 52 : png_ptr->io_ptr = io_ptr;
187 :
188 : #ifdef PNG_STDIO_SUPPORTED
189 52 : if (write_data_fn != NULL)
190 26 : png_ptr->write_data_fn = write_data_fn;
191 :
192 : else
193 26 : png_ptr->write_data_fn = png_default_write_data;
194 : #else
195 : png_ptr->write_data_fn = write_data_fn;
196 : #endif
197 :
198 : #ifdef PNG_WRITE_FLUSH_SUPPORTED
199 : # ifdef PNG_STDIO_SUPPORTED
200 :
201 52 : if (output_flush_fn != NULL)
202 0 : png_ptr->output_flush_fn = output_flush_fn;
203 :
204 : else
205 52 : png_ptr->output_flush_fn = png_default_flush;
206 :
207 : # else
208 : png_ptr->output_flush_fn = output_flush_fn;
209 : # endif
210 : #endif /* PNG_WRITE_FLUSH_SUPPORTED */
211 :
212 : /* It is an error to read while writing a png file */
213 52 : if (png_ptr->read_data_fn != NULL)
214 : {
215 0 : png_ptr->read_data_fn = NULL;
216 :
217 : png_warning(png_ptr,
218 : "Can't set both read_data_fn and write_data_fn in the"
219 : " same structure");
220 : }
221 : }
222 :
223 : #ifdef USE_FAR_KEYWORD
224 : # ifdef _MSC_VER
225 : void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
226 : {
227 : void *near_ptr;
228 : void FAR *far_ptr;
229 : FP_OFF(near_ptr) = FP_OFF(ptr);
230 : far_ptr = (void FAR *)near_ptr;
231 :
232 : if (check != 0)
233 : if (FP_SEG(ptr) != FP_SEG(far_ptr))
234 : png_error(png_ptr, "segment lost in conversion");
235 :
236 : return(near_ptr);
237 : }
238 : # else
239 : void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check)
240 : {
241 : void *near_ptr;
242 : void FAR *far_ptr;
243 : near_ptr = (void FAR *)ptr;
244 : far_ptr = (void FAR *)near_ptr;
245 :
246 : if (check != 0)
247 : if (far_ptr != ptr)
248 : png_error(png_ptr, "segment lost in conversion");
249 :
250 : return(near_ptr);
251 : }
252 : # endif
253 : #endif
254 : #endif /* PNG_WRITE_SUPPORTED */
|