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