blob: e4c96a7c146b0ce7b88445736d1b796bffc64fec [file] [log] [blame]
Guy Schalnate5a37791996-06-05 15:50:50 -05001
2/* pngwio.c - functions for data output
3
Andreas Dilger47a0c421997-05-16 02:46:07 -05004 libpng 1.0 beta 6 - version 0.96
Guy Schalnate5a37791996-06-05 15:50:50 -05005 For conditions of distribution and use, see copyright notice in png.h
6 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
Andreas Dilger47a0c421997-05-16 02:46:07 -05007 Copyright (c) 1996, 1997 Andreas Dilger
8 May 12, 1997
Guy Schalnate5a37791996-06-05 15:50:50 -05009
10 This file provides a location for all output. Users which need
11 special handling are expected to write functions which have the same
12 arguments as these, and perform similar functions, but possibly use
13 different output methods. Note that you shouldn't change these
14 functions, but rather write replacement functions and then change
15 them at run time with png_set_write_fn(...) */
16
17#define PNG_INTERNAL
18#include "png.h"
19
20/* Write the data to whatever output you are using. The default routine
21 writes to a file pointer. Note that this routine sometimes gets called
22 with very small lengths, so you should implement some kind of simple
23 buffering if you are using unbuffered writes. This should never be asked
Andreas Dilger47a0c421997-05-16 02:46:07 -050024 to write more then 64K on a 16 bit machine. */
Guy Schalnate5a37791996-06-05 15:50:50 -050025
26void
Andreas Dilger47a0c421997-05-16 02:46:07 -050027png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Guy Schalnate5a37791996-06-05 15:50:50 -050028{
Andreas Dilger47a0c421997-05-16 02:46:07 -050029 if (png_ptr->write_data_fn != NULL )
Guy Schalnate5a37791996-06-05 15:50:50 -050030 (*(png_ptr->write_data_fn))(png_ptr, data, length);
31 else
32 png_error(png_ptr, "Call to NULL write function");
33}
34
35/* This is the function which does the actual writing of data. If you are
36 not writing to a standard C stream, you should create a replacement
37 write_data function and use it at run time with png_set_write_fn(), rather
38 than changing the library. */
39#ifndef USE_FAR_KEYWORD
40static void
Andreas Dilger47a0c421997-05-16 02:46:07 -050041png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Guy Schalnate5a37791996-06-05 15:50:50 -050042{
43 png_uint_32 check;
44
Andreas Dilger47a0c421997-05-16 02:46:07 -050045 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
Guy Schalnate5a37791996-06-05 15:50:50 -050046 if (check != length)
47 {
48 png_error(png_ptr, "Write Error");
49 }
50}
51#else
52/* this is the model-independent version. Since the standard I/O library
53 can't handle far buffers in the medium and small models, we have to copy
54 the data.
55*/
56
57#define NEAR_BUF_SIZE 1024
58#define MIN(a,b) (a <= b ? a : b)
59
Guy Schalnate5a37791996-06-05 15:50:50 -050060static void
Andreas Dilger47a0c421997-05-16 02:46:07 -050061png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
Guy Schalnate5a37791996-06-05 15:50:50 -050062{
63 png_uint_32 check;
Andreas Dilger47a0c421997-05-16 02:46:07 -050064 png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060065 FILE *io_ptr;
Guy Schalnate5a37791996-06-05 15:50:50 -050066
67 /* Check if data really is near. If so, use usual code. */
Andreas Dilger47a0c421997-05-16 02:46:07 -050068 near_data = (png_byte *)CVT_PTR_NOCHECK(data);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060069 io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -050070 if ((png_bytep)near_data == data)
Guy Schalnate5a37791996-06-05 15:50:50 -050071 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050072 check = fwrite(near_data, 1, length, io_ptr);
Guy Schalnate5a37791996-06-05 15:50:50 -050073 }
74 else
75 {
76 png_byte buf[NEAR_BUF_SIZE];
77 png_size_t written, remaining, err;
78 check = 0;
Andreas Dilger47a0c421997-05-16 02:46:07 -050079 remaining = length;
Guy Schalnate5a37791996-06-05 15:50:50 -050080 do
81 {
82 written = MIN(NEAR_BUF_SIZE, remaining);
83 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060084 err = fwrite(buf, 1, written, io_ptr);
Guy Schalnate5a37791996-06-05 15:50:50 -050085 if (err != written)
86 break;
87 else
88 check += err;
89 data += written;
90 remaining -= written;
91 }
92 while (remaining != 0);
93 }
94 if (check != length)
95 {
96 png_error(png_ptr, "Write Error");
97 }
98}
99
100#endif
101
102/* This function is called to output any data pending writing (normally
103 to disk). After png_flush is called, there should be no data pending
104 writing in any buffers. */
105#if defined(PNG_WRITE_FLUSH_SUPPORTED)
106void
107png_flush(png_structp png_ptr)
108{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500109 if (png_ptr->output_flush_fn != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500110 (*(png_ptr->output_flush_fn))(png_ptr);
111}
112
113static void
114png_default_flush(png_structp png_ptr)
115{
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600116 FILE *io_ptr;
117 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
Andreas Dilger47a0c421997-05-16 02:46:07 -0500118 if (io_ptr != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600119 fflush(io_ptr);
Guy Schalnate5a37791996-06-05 15:50:50 -0500120}
121#endif
122
123/* This function allows the application to supply new output functions for
124 libpng if standard C streams aren't being used.
125
126 This function takes as its arguments:
127 png_ptr - pointer to a png output data structure
128 io_ptr - pointer to user supplied structure containing info about
129 the output functions. May be NULL.
130 write_data_fn - pointer to a new output function which takes as its
131 arguments a pointer to a png_struct, a pointer to
132 data to be written, and a 32-bit unsigned int which is
133 the number of bytes to be written. The new write
134 function should call png_error(png_ptr, "Error msg")
135 to exit and output any fatal error messages.
136 flush_data_fn - pointer to a new flush function which takes as its
137 arguments a pointer to a png_struct. After a call to
138 the flush function, there should be no data in any buffers
139 or pending transmission. If the output method doesn't do
140 any buffering of ouput, a function prototype must still be
141 supplied although it doesn't have to do anything. If
142 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
143 time, output_flush_fn will be ignored, although it must be
144 supplied for compatibility. */
145void
146png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
147 png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
148{
149 png_ptr->io_ptr = io_ptr;
150
Andreas Dilger47a0c421997-05-16 02:46:07 -0500151 if (write_data_fn != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500152 png_ptr->write_data_fn = write_data_fn;
153 else
154 png_ptr->write_data_fn = png_default_write_data;
155
156#if defined(PNG_WRITE_FLUSH_SUPPORTED)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500157 if (output_flush_fn != NULL)
Guy Schalnate5a37791996-06-05 15:50:50 -0500158 png_ptr->output_flush_fn = output_flush_fn;
159 else
160 png_ptr->output_flush_fn = png_default_flush;
161#endif /* PNG_WRITE_FLUSH_SUPPORTED */
162
163 /* It is an error to read while writing a png file */
164 png_ptr->read_data_fn = NULL;
165}
166
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600167#if defined(USE_FAR_KEYWORD)
168#if defined(_MSC_VER)
169void *far_to_near(png_structp png_ptr,png_voidp ptr, int check)
170{
171 void *near_ptr;
172 void FAR *far_ptr;
173 FP_OFF(near_ptr) = FP_OFF(ptr);
174 far_ptr = (void FAR *)near_ptr;
175 if(check != 0)
176 if(FP_SEG(ptr) != FP_SEG(far_ptr))
177 png_error(png_ptr,"segment lost in conversion");
178 return(near_ptr);
179}
180# else
181void *far_to_near(png_structp png_ptr,png_voidp ptr, int check)
182{
183 void *near_ptr;
184 void FAR *far_ptr;
185 near_ptr = (void FAR *)ptr;
186 far_ptr = (void FAR *)near_ptr;
187 if(check != 0)
188 if(far_ptr != ptr)
189 png_error(png_ptr,"segment lost in conversion");
190 return(near_ptr);
191}
192# endif
193# endif