Back to index

lightning-sunbird  0.9+nobinonly
pngwio.c
Go to the documentation of this file.
00001 
00002 /* pngwio.c - functions for data output
00003  *
00004  * libpng 1.2.7 - September 12, 2004
00005  * For conditions of distribution and use, see copyright notice in png.h
00006  * Copyright (c) 1998-2004 Glenn Randers-Pehrson
00007  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00008  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00009  *
00010  * This file provides a location for all output.  Users who need
00011  * special handling are expected to write functions that have the same
00012  * arguments as these and perform similar functions, but that possibly
00013  * use different output methods.  Note that you shouldn't change these
00014  * functions, but rather write replacement functions and then change
00015  * them at run time with png_set_write_fn(...).
00016  */
00017 
00018 #define PNG_INTERNAL
00019 #include "png.h"
00020 #ifdef PNG_WRITE_SUPPORTED
00021 
00022 /* Write the data to whatever output you are using.  The default routine
00023    writes to a file pointer.  Note that this routine sometimes gets called
00024    with very small lengths, so you should implement some kind of simple
00025    buffering if you are using unbuffered writes.  This should never be asked
00026    to write more than 64K on a 16 bit machine.  */
00027 
00028 void /* PRIVATE */
00029 png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
00030 {
00031    if (png_ptr->write_data_fn != NULL )
00032       (*(png_ptr->write_data_fn))(png_ptr, data, length);
00033    else
00034       png_error(png_ptr, "Call to NULL write function");
00035 }
00036 
00037 #if !defined(PNG_NO_STDIO)
00038 /* This is the function that does the actual writing of data.  If you are
00039    not writing to a standard C stream, you should create a replacement
00040    write_data function and use it at run time with png_set_write_fn(), rather
00041    than changing the library. */
00042 #ifndef USE_FAR_KEYWORD
00043 void PNGAPI
00044 png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
00045 {
00046    png_uint_32 check;
00047 
00048 #if defined(_WIN32_WCE)
00049    if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
00050       check = 0;
00051 #else
00052    check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
00053 #endif
00054    if (check != length)
00055       png_error(png_ptr, "Write Error");
00056 }
00057 #else
00058 /* this is the model-independent version. Since the standard I/O library
00059    can't handle far buffers in the medium and small models, we have to copy
00060    the data.
00061 */
00062 
00063 #define NEAR_BUF_SIZE 1024
00064 #define MIN(a,b) (a <= b ? a : b)
00065 
00066 void PNGAPI
00067 png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
00068 {
00069    png_uint_32 check;
00070    png_byte *near_data;  /* Needs to be "png_byte *" instead of "png_bytep" */
00071    png_FILE_p io_ptr;
00072 
00073    /* Check if data really is near. If so, use usual code. */
00074    near_data = (png_byte *)CVT_PTR_NOCHECK(data);
00075    io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
00076    if ((png_bytep)near_data == data)
00077    {
00078 #if defined(_WIN32_WCE)
00079       if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
00080          check = 0;
00081 #else
00082       check = fwrite(near_data, 1, length, io_ptr);
00083 #endif
00084    }
00085    else
00086    {
00087       png_byte buf[NEAR_BUF_SIZE];
00088       png_size_t written, remaining, err;
00089       check = 0;
00090       remaining = length;
00091       do
00092       {
00093          written = MIN(NEAR_BUF_SIZE, remaining);
00094          png_memcpy(buf, data, written); /* copy far buffer to near buffer */
00095 #if defined(_WIN32_WCE)
00096          if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
00097             err = 0;
00098 #else
00099          err = fwrite(buf, 1, written, io_ptr);
00100 #endif
00101          if (err != written)
00102             break;
00103          else
00104             check += err;
00105          data += written;
00106          remaining -= written;
00107       }
00108       while (remaining != 0);
00109    }
00110    if (check != length)
00111       png_error(png_ptr, "Write Error");
00112 }
00113 
00114 #endif
00115 #endif
00116 
00117 /* This function is called to output any data pending writing (normally
00118    to disk).  After png_flush is called, there should be no data pending
00119    writing in any buffers. */
00120 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
00121 void /* PRIVATE */
00122 png_flush(png_structp png_ptr)
00123 {
00124    if (png_ptr->output_flush_fn != NULL)
00125       (*(png_ptr->output_flush_fn))(png_ptr);
00126 }
00127 
00128 #if !defined(PNG_NO_STDIO)
00129 void PNGAPI
00130 png_default_flush(png_structp png_ptr)
00131 {
00132 #if !defined(_WIN32_WCE)
00133    png_FILE_p io_ptr;
00134    io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
00135    if (io_ptr != NULL)
00136       fflush(io_ptr);
00137 #endif
00138 }
00139 #endif
00140 #endif
00141 
00142 /* This function allows the application to supply new output functions for
00143    libpng if standard C streams aren't being used.
00144 
00145    This function takes as its arguments:
00146    png_ptr       - pointer to a png output data structure
00147    io_ptr        - pointer to user supplied structure containing info about
00148                    the output functions.  May be NULL.
00149    write_data_fn - pointer to a new output function that takes as its
00150                    arguments a pointer to a png_struct, a pointer to
00151                    data to be written, and a 32-bit unsigned int that is
00152                    the number of bytes to be written.  The new write
00153                    function should call png_error(png_ptr, "Error msg")
00154                    to exit and output any fatal error messages.
00155    flush_data_fn - pointer to a new flush function that takes as its
00156                    arguments a pointer to a png_struct.  After a call to
00157                    the flush function, there should be no data in any buffers
00158                    or pending transmission.  If the output method doesn't do
00159                    any buffering of ouput, a function prototype must still be
00160                    supplied although it doesn't have to do anything.  If
00161                    PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
00162                    time, output_flush_fn will be ignored, although it must be
00163                    supplied for compatibility. */
00164 void PNGAPI
00165 png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
00166    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
00167 {
00168    png_ptr->io_ptr = io_ptr;
00169 
00170 #if !defined(PNG_NO_STDIO)
00171    if (write_data_fn != NULL)
00172       png_ptr->write_data_fn = write_data_fn;
00173    else
00174       png_ptr->write_data_fn = png_default_write_data;
00175 #else
00176    png_ptr->write_data_fn = write_data_fn;
00177 #endif
00178 
00179 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
00180 #if !defined(PNG_NO_STDIO)
00181    if (output_flush_fn != NULL)
00182       png_ptr->output_flush_fn = output_flush_fn;
00183    else
00184       png_ptr->output_flush_fn = png_default_flush;
00185 #else
00186    png_ptr->output_flush_fn = output_flush_fn;
00187 #endif
00188 #endif /* PNG_WRITE_FLUSH_SUPPORTED */
00189 
00190    /* It is an error to read while writing a png file */
00191    if (png_ptr->read_data_fn != NULL)
00192    {
00193       png_ptr->read_data_fn = NULL;
00194       png_warning(png_ptr,
00195          "Attempted to set both read_data_fn and write_data_fn in");
00196       png_warning(png_ptr,
00197          "the same structure.  Resetting read_data_fn to NULL.");
00198    }
00199 }
00200 
00201 #if defined(USE_FAR_KEYWORD)
00202 #if defined(_MSC_VER)
00203 void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
00204 {
00205    void *near_ptr;
00206    void FAR *far_ptr;
00207    FP_OFF(near_ptr) = FP_OFF(ptr);
00208    far_ptr = (void FAR *)near_ptr;
00209    if(check != 0)
00210       if(FP_SEG(ptr) != FP_SEG(far_ptr))
00211          png_error(png_ptr,"segment lost in conversion");
00212    return(near_ptr);
00213 }
00214 #  else
00215 void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
00216 {
00217    void *near_ptr;
00218    void FAR *far_ptr;
00219    near_ptr = (void FAR *)ptr;
00220    far_ptr = (void FAR *)near_ptr;
00221    if(check != 0)
00222       if(far_ptr != ptr)
00223          png_error(png_ptr,"segment lost in conversion");
00224    return(near_ptr);
00225 }
00226 #   endif
00227 #   endif
00228 #endif /* PNG_WRITE_SUPPORTED */