blob: 24b63d91ed43d0f3f28e7e0bd494f0952035d680 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Sun designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Sun in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 */
24
25/* pngwio.c - functions for data output
26 *
27 * This file is available under and governed by the GNU General Public
28 * License version 2 only, as published by the Free Software Foundation.
29 * However, the following notice accompanied the original version of this
30 * file and, per its terms, should not be removed:
31 *
32 * Last changed in libpng 1.2.13 November 13, 2006
33 * For conditions of distribution and use, see copyright notice in png.h
34 * Copyright (c) 1998-2002 Glenn Randers-Pehrson
35 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
36 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
37 *
38 * This file provides a location for all output. Users who need
39 * special handling are expected to write functions that have the same
40 * arguments as these and perform similar functions, but that possibly
41 * use different output methods. Note that you shouldn't change these
42 * functions, but rather write replacement functions and then change
43 * them at run time with png_set_write_fn(...).
44 */
45
46#define PNG_INTERNAL
47#include "png.h"
48#ifdef PNG_WRITE_SUPPORTED
49
50/* Write the data to whatever output you are using. The default routine
51 writes to a file pointer. Note that this routine sometimes gets called
52 with very small lengths, so you should implement some kind of simple
53 buffering if you are using unbuffered writes. This should never be asked
54 to write more than 64K on a 16 bit machine. */
55
56void /* PRIVATE */
57png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
58{
59 if (png_ptr->write_data_fn != NULL )
60 (*(png_ptr->write_data_fn))(png_ptr, data, length);
61 else
62 png_error(png_ptr, "Call to NULL write function");
63}
64
65#if !defined(PNG_NO_STDIO)
66/* This is the function that does the actual writing of data. If you are
67 not writing to a standard C stream, you should create a replacement
68 write_data function and use it at run time with png_set_write_fn(), rather
69 than changing the library. */
70#ifndef USE_FAR_KEYWORD
71void PNGAPI
72png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
73{
74 png_uint_32 check;
75
76 if(png_ptr == NULL) return;
77#if defined(_WIN32_WCE)
78 if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
79 check = 0;
80#else
81 check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
82#endif
83 if (check != length)
84 png_error(png_ptr, "Write Error");
85}
86#else
87/* this is the model-independent version. Since the standard I/O library
88 can't handle far buffers in the medium and small models, we have to copy
89 the data.
90*/
91
92#define NEAR_BUF_SIZE 1024
93#define MIN(a,b) (a <= b ? a : b)
94
95void PNGAPI
96png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
97{
98 png_uint_32 check;
99 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
100 png_FILE_p io_ptr;
101
102 if(png_ptr == NULL) return;
103 /* Check if data really is near. If so, use usual code. */
104 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
105 io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
106 if ((png_bytep)near_data == data)
107 {
108#if defined(_WIN32_WCE)
109 if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
110 check = 0;
111#else
112 check = fwrite(near_data, 1, length, io_ptr);
113#endif
114 }
115 else
116 {
117 png_byte buf[NEAR_BUF_SIZE];
118 png_size_t written, remaining, err;
119 check = 0;
120 remaining = length;
121 do
122 {
123 written = MIN(NEAR_BUF_SIZE, remaining);
124 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
125#if defined(_WIN32_WCE)
126 if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
127 err = 0;
128#else
129 err = fwrite(buf, 1, written, io_ptr);
130#endif
131 if (err != written)
132 break;
133 else
134 check += err;
135 data += written;
136 remaining -= written;
137 }
138 while (remaining != 0);
139 }
140 if (check != length)
141 png_error(png_ptr, "Write Error");
142}
143
144#endif
145#endif
146
147/* This function is called to output any data pending writing (normally
148 to disk). After png_flush is called, there should be no data pending
149 writing in any buffers. */
150#if defined(PNG_WRITE_FLUSH_SUPPORTED)
151void /* PRIVATE */
152png_flush(png_structp png_ptr)
153{
154 if (png_ptr->output_flush_fn != NULL)
155 (*(png_ptr->output_flush_fn))(png_ptr);
156}
157
158#if !defined(PNG_NO_STDIO)
159void PNGAPI
160png_default_flush(png_structp png_ptr)
161{
162#if !defined(_WIN32_WCE)
163 png_FILE_p io_ptr;
164#endif
165 if(png_ptr == NULL) return;
166#if !defined(_WIN32_WCE)
167 io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
168 if (io_ptr != NULL)
169 fflush(io_ptr);
170#endif
171}
172#endif
173#endif
174
175/* This function allows the application to supply new output functions for
176 libpng if standard C streams aren't being used.
177
178 This function takes as its arguments:
179 png_ptr - pointer to a png output data structure
180 io_ptr - pointer to user supplied structure containing info about
181 the output functions. May be NULL.
182 write_data_fn - pointer to a new output function that takes as its
183 arguments a pointer to a png_struct, a pointer to
184 data to be written, and a 32-bit unsigned int that is
185 the number of bytes to be written. The new write
186 function should call png_error(png_ptr, "Error msg")
187 to exit and output any fatal error messages.
188 flush_data_fn - pointer to a new flush function that takes as its
189 arguments a pointer to a png_struct. After a call to
190 the flush function, there should be no data in any buffers
191 or pending transmission. If the output method doesn't do
192 any buffering of ouput, a function prototype must still be
193 supplied although it doesn't have to do anything. If
194 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
195 time, output_flush_fn will be ignored, although it must be
196 supplied for compatibility. */
197void PNGAPI
198png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
199 png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
200{
201 if(png_ptr == NULL) return;
202 png_ptr->io_ptr = io_ptr;
203
204#if !defined(PNG_NO_STDIO)
205 if (write_data_fn != NULL)
206 png_ptr->write_data_fn = write_data_fn;
207 else
208 png_ptr->write_data_fn = png_default_write_data;
209#else
210 png_ptr->write_data_fn = write_data_fn;
211#endif
212
213#if defined(PNG_WRITE_FLUSH_SUPPORTED)
214#if !defined(PNG_NO_STDIO)
215 if (output_flush_fn != NULL)
216 png_ptr->output_flush_fn = output_flush_fn;
217 else
218 png_ptr->output_flush_fn = png_default_flush;
219#else
220 png_ptr->output_flush_fn = output_flush_fn;
221#endif
222#endif /* PNG_WRITE_FLUSH_SUPPORTED */
223
224 /* It is an error to read while writing a png file */
225 if (png_ptr->read_data_fn != NULL)
226 {
227 png_ptr->read_data_fn = NULL;
228 png_warning(png_ptr,
229 "Attempted to set both read_data_fn and write_data_fn in");
230 png_warning(png_ptr,
231 "the same structure. Resetting read_data_fn to NULL.");
232 }
233}
234
235#if defined(USE_FAR_KEYWORD)
236#if defined(_MSC_VER)
237void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
238{
239 void *near_ptr;
240 void FAR *far_ptr;
241 FP_OFF(near_ptr) = FP_OFF(ptr);
242 far_ptr = (void FAR *)near_ptr;
243 if(check != 0)
244 if(FP_SEG(ptr) != FP_SEG(far_ptr))
245 png_error(png_ptr,"segment lost in conversion");
246 return(near_ptr);
247}
248# else
249void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
250{
251 void *near_ptr;
252 void FAR *far_ptr;
253 near_ptr = (void FAR *)ptr;
254 far_ptr = (void FAR *)near_ptr;
255 if(check != 0)
256 if(far_ptr != ptr)
257 png_error(png_ptr,"segment lost in conversion");
258 return(near_ptr);
259}
260# endif
261# endif
262#endif /* PNG_WRITE_SUPPORTED */