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