blob: 904c31960cff629561643571159d72f937ac341c [file] [log] [blame]
Guy Schalnate5a37791996-06-05 15:50:50 -05001
2/* pngwio.c - functions for data output
3
4 libpng 1.0 beta 3 - version 0.89
5 For conditions of distribution and use, see copyright notice in png.h
6 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 May 25, 1996
8
9 This file provides a location for all output. Users which need
10 special handling are expected to write functions which have the same
11 arguments as these, and perform similar functions, but possibly use
12 different output methods. Note that you shouldn't change these
13 functions, but rather write replacement functions and then change
14 them at run time with png_set_write_fn(...) */
15
16#define PNG_INTERNAL
17#include "png.h"
18
19/* Write the data to whatever output you are using. The default routine
20 writes to a file pointer. Note that this routine sometimes gets called
21 with very small lengths, so you should implement some kind of simple
22 buffering if you are using unbuffered writes. This should never be asked
23 to write more then 64K on a 16 bit machine. The cast to png_size_t is
24 there to quiet warnings of certain compilers. */
25
26void
27png_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
28{
29 if (png_ptr->write_data_fn)
30 (*(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
41png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
42{
43 png_uint_32 check;
44
45 check = fwrite(data, 1, (png_size_t)length, (FILE *)(png_ptr->io_ptr));
46 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
60#ifdef _MSC_VER
61/* for FP_OFF */
62#include <dos.h>
63#endif
64
65static void
66png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
67{
68 png_uint_32 check;
69 png_byte *n_data;
70
71 /* Check if data really is near. If so, use usual code. */
72#ifdef _MSC_VER
73 /* do it this way just to quiet warning */
74 FP_OFF(n_data) = FP_OFF(data);
75 if (FP_SEG(n_data) == FP_SEG(data))
76#else
77 /* this works in MSC also but with lost segment warning */
78 n_data = (png_byte *)data;
79 if ((png_bytep)n_data == data)
80#endif
81 {
82 check = fwrite(n_data, 1, (png_size_t)length, (FILE *)(png_ptr->io_ptr));
83 }
84 else
85 {
86 png_byte buf[NEAR_BUF_SIZE];
87 png_size_t written, remaining, err;
88 check = 0;
89 remaining = (png_size_t)length;
90 do
91 {
92 written = MIN(NEAR_BUF_SIZE, remaining);
93 png_memcpy(buf, data, written); /* copy far buffer to near buffer */
94 err = fwrite(buf, 1, written, (FILE *)(png_ptr->io_ptr));
95 if (err != written)
96 break;
97 else
98 check += err;
99 data += written;
100 remaining -= written;
101 }
102 while (remaining != 0);
103 }
104 if (check != length)
105 {
106 png_error(png_ptr, "Write Error");
107 }
108}
109
110#endif
111
112/* This function is called to output any data pending writing (normally
113 to disk). After png_flush is called, there should be no data pending
114 writing in any buffers. */
115#if defined(PNG_WRITE_FLUSH_SUPPORTED)
116void
117png_flush(png_structp png_ptr)
118{
119 if (png_ptr->output_flush_fn)
120 (*(png_ptr->output_flush_fn))(png_ptr);
121}
122
123static void
124png_default_flush(png_structp png_ptr)
125{
126 if ((FILE *)(png_ptr->io_ptr))
127 fflush((FILE *)(png_ptr->io_ptr));
128}
129#endif
130
131/* This function allows the application to supply new output functions for
132 libpng if standard C streams aren't being used.
133
134 This function takes as its arguments:
135 png_ptr - pointer to a png output data structure
136 io_ptr - pointer to user supplied structure containing info about
137 the output functions. May be NULL.
138 write_data_fn - pointer to a new output function which takes as its
139 arguments a pointer to a png_struct, a pointer to
140 data to be written, and a 32-bit unsigned int which is
141 the number of bytes to be written. The new write
142 function should call png_error(png_ptr, "Error msg")
143 to exit and output any fatal error messages.
144 flush_data_fn - pointer to a new flush function which takes as its
145 arguments a pointer to a png_struct. After a call to
146 the flush function, there should be no data in any buffers
147 or pending transmission. If the output method doesn't do
148 any buffering of ouput, a function prototype must still be
149 supplied although it doesn't have to do anything. If
150 PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
151 time, output_flush_fn will be ignored, although it must be
152 supplied for compatibility. */
153void
154png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
155 png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
156{
157 png_ptr->io_ptr = io_ptr;
158
159 if (write_data_fn)
160 png_ptr->write_data_fn = write_data_fn;
161 else
162 png_ptr->write_data_fn = png_default_write_data;
163
164#if defined(PNG_WRITE_FLUSH_SUPPORTED)
165 if (output_flush_fn)
166 png_ptr->output_flush_fn = output_flush_fn;
167 else
168 png_ptr->output_flush_fn = png_default_flush;
169#endif /* PNG_WRITE_FLUSH_SUPPORTED */
170
171 /* It is an error to read while writing a png file */
172 png_ptr->read_data_fn = NULL;
173}
174