xref: /plan9/sys/src/cmd/gs/libpng/pngrio.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier 
27dd7cddfSDavid du Colombier /* pngrio.c - functions for data input
37dd7cddfSDavid du Colombier  *
4*593dc095SDavid du Colombier  * libpng 1.2.8 - December 3, 2004
57dd7cddfSDavid du Colombier  * For conditions of distribution and use, see copyright notice in png.h
6*593dc095SDavid du Colombier  * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7*593dc095SDavid du Colombier  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8*593dc095SDavid du Colombier  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
97dd7cddfSDavid du Colombier  *
10*593dc095SDavid du Colombier  * This file provides a location for all input.  Users who need
11*593dc095SDavid du Colombier  * special handling are expected to write a function that has the same
12*593dc095SDavid du Colombier  * arguments as this and performs a similar function, but that possibly
13*593dc095SDavid du Colombier  * has a different input method.  Note that you shouldn't change this
147dd7cddfSDavid du Colombier  * function, but rather write a replacement function and then make
157dd7cddfSDavid du Colombier  * libpng use it at run time with png_set_read_fn(...).
167dd7cddfSDavid du Colombier  */
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier #define PNG_INTERNAL
197dd7cddfSDavid du Colombier #include "png.h"
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier /* Read the data from whatever input you are using.  The default routine
227dd7cddfSDavid du Colombier    reads from a file pointer.  Note that this routine sometimes gets called
237dd7cddfSDavid du Colombier    with very small lengths, so you should implement some kind of simple
247dd7cddfSDavid du Colombier    buffering if you are using unbuffered reads.  This should never be asked
257dd7cddfSDavid du Colombier    to read more then 64K on a 16 bit machine. */
26*593dc095SDavid du Colombier void /* PRIVATE */
png_read_data(png_structp png_ptr,png_bytep data,png_size_t length)277dd7cddfSDavid du Colombier png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
287dd7cddfSDavid du Colombier {
29*593dc095SDavid du Colombier    png_debug1(4,"reading %d bytes\n", (int)length);
307dd7cddfSDavid du Colombier    if (png_ptr->read_data_fn != NULL)
317dd7cddfSDavid du Colombier       (*(png_ptr->read_data_fn))(png_ptr, data, length);
327dd7cddfSDavid du Colombier    else
337dd7cddfSDavid du Colombier       png_error(png_ptr, "Call to NULL read function");
347dd7cddfSDavid du Colombier }
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier #if !defined(PNG_NO_STDIO)
37*593dc095SDavid du Colombier /* This is the function that does the actual reading of data.  If you are
387dd7cddfSDavid du Colombier    not reading from a standard C stream, you should create a replacement
397dd7cddfSDavid du Colombier    read_data function and use it at run time with png_set_read_fn(), rather
407dd7cddfSDavid du Colombier    than changing the library. */
417dd7cddfSDavid du Colombier #ifndef USE_FAR_KEYWORD
42*593dc095SDavid du Colombier void PNGAPI
png_default_read_data(png_structp png_ptr,png_bytep data,png_size_t length)437dd7cddfSDavid du Colombier png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
447dd7cddfSDavid du Colombier {
457dd7cddfSDavid du Colombier    png_size_t check;
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier    /* fread() returns 0 on error, so it is OK to store this in a png_size_t
487dd7cddfSDavid du Colombier     * instead of an int, which is what fread() actually returns.
497dd7cddfSDavid du Colombier     */
50*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
51*593dc095SDavid du Colombier    if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
52*593dc095SDavid du Colombier       check = 0;
53*593dc095SDavid du Colombier #else
547dd7cddfSDavid du Colombier    check = (png_size_t)fread(data, (png_size_t)1, length,
55*593dc095SDavid du Colombier       (png_FILE_p)png_ptr->io_ptr);
56*593dc095SDavid du Colombier #endif
577dd7cddfSDavid du Colombier 
587dd7cddfSDavid du Colombier    if (check != length)
597dd7cddfSDavid du Colombier       png_error(png_ptr, "Read Error");
607dd7cddfSDavid du Colombier }
617dd7cddfSDavid du Colombier #else
627dd7cddfSDavid du Colombier /* this is the model-independent version. Since the standard I/O library
637dd7cddfSDavid du Colombier    can't handle far buffers in the medium and small models, we have to copy
647dd7cddfSDavid du Colombier    the data.
657dd7cddfSDavid du Colombier */
667dd7cddfSDavid du Colombier 
677dd7cddfSDavid du Colombier #define NEAR_BUF_SIZE 1024
687dd7cddfSDavid du Colombier #define MIN(a,b) (a <= b ? a : b)
697dd7cddfSDavid du Colombier 
70*593dc095SDavid du Colombier static void /* PRIVATE */
png_default_read_data(png_structp png_ptr,png_bytep data,png_size_t length)717dd7cddfSDavid du Colombier png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
727dd7cddfSDavid du Colombier {
737dd7cddfSDavid du Colombier    int check;
747dd7cddfSDavid du Colombier    png_byte *n_data;
75*593dc095SDavid du Colombier    png_FILE_p io_ptr;
767dd7cddfSDavid du Colombier 
777dd7cddfSDavid du Colombier    /* Check if data really is near. If so, use usual code. */
787dd7cddfSDavid du Colombier    n_data = (png_byte *)CVT_PTR_NOCHECK(data);
79*593dc095SDavid du Colombier    io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
807dd7cddfSDavid du Colombier    if ((png_bytep)n_data == data)
817dd7cddfSDavid du Colombier    {
82*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
83*593dc095SDavid du Colombier       if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
84*593dc095SDavid du Colombier          check = 0;
85*593dc095SDavid du Colombier #else
867dd7cddfSDavid du Colombier       check = fread(n_data, 1, length, io_ptr);
87*593dc095SDavid du Colombier #endif
887dd7cddfSDavid du Colombier    }
897dd7cddfSDavid du Colombier    else
907dd7cddfSDavid du Colombier    {
917dd7cddfSDavid du Colombier       png_byte buf[NEAR_BUF_SIZE];
927dd7cddfSDavid du Colombier       png_size_t read, remaining, err;
937dd7cddfSDavid du Colombier       check = 0;
947dd7cddfSDavid du Colombier       remaining = length;
957dd7cddfSDavid du Colombier       do
967dd7cddfSDavid du Colombier       {
977dd7cddfSDavid du Colombier          read = MIN(NEAR_BUF_SIZE, remaining);
98*593dc095SDavid du Colombier #if defined(_WIN32_WCE)
99*593dc095SDavid du Colombier          if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
100*593dc095SDavid du Colombier             err = 0;
101*593dc095SDavid du Colombier #else
1027dd7cddfSDavid du Colombier          err = fread(buf, (png_size_t)1, read, io_ptr);
103*593dc095SDavid du Colombier #endif
1047dd7cddfSDavid du Colombier          png_memcpy(data, buf, read); /* copy far buffer to near buffer */
1057dd7cddfSDavid du Colombier          if(err != read)
1067dd7cddfSDavid du Colombier             break;
1077dd7cddfSDavid du Colombier          else
1087dd7cddfSDavid du Colombier             check += err;
1097dd7cddfSDavid du Colombier          data += read;
1107dd7cddfSDavid du Colombier          remaining -= read;
1117dd7cddfSDavid du Colombier       }
1127dd7cddfSDavid du Colombier       while (remaining != 0);
1137dd7cddfSDavid du Colombier    }
1147dd7cddfSDavid du Colombier    if ((png_uint_32)check != (png_uint_32)length)
1157dd7cddfSDavid du Colombier       png_error(png_ptr, "read Error");
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier #endif
1187dd7cddfSDavid du Colombier #endif
1197dd7cddfSDavid du Colombier 
1207dd7cddfSDavid du Colombier /* This function allows the application to supply a new input function
1217dd7cddfSDavid du Colombier    for libpng if standard C streams aren't being used.
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier    This function takes as its arguments:
1247dd7cddfSDavid du Colombier    png_ptr      - pointer to a png input data structure
1257dd7cddfSDavid du Colombier    io_ptr       - pointer to user supplied structure containing info about
1267dd7cddfSDavid du Colombier                   the input functions.  May be NULL.
127*593dc095SDavid du Colombier    read_data_fn - pointer to a new input function that takes as its
1287dd7cddfSDavid du Colombier                   arguments a pointer to a png_struct, a pointer to
1297dd7cddfSDavid du Colombier                   a location where input data can be stored, and a 32-bit
130*593dc095SDavid du Colombier                   unsigned int that is the number of bytes to be read.
1317dd7cddfSDavid du Colombier                   To exit and output any fatal error messages the new write
1327dd7cddfSDavid du Colombier                   function should call png_error(png_ptr, "Error msg"). */
133*593dc095SDavid du Colombier void PNGAPI
png_set_read_fn(png_structp png_ptr,png_voidp io_ptr,png_rw_ptr read_data_fn)1347dd7cddfSDavid du Colombier png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
1357dd7cddfSDavid du Colombier    png_rw_ptr read_data_fn)
1367dd7cddfSDavid du Colombier {
1377dd7cddfSDavid du Colombier    png_ptr->io_ptr = io_ptr;
1387dd7cddfSDavid du Colombier 
1397dd7cddfSDavid du Colombier #if !defined(PNG_NO_STDIO)
1407dd7cddfSDavid du Colombier    if (read_data_fn != NULL)
1417dd7cddfSDavid du Colombier       png_ptr->read_data_fn = read_data_fn;
1427dd7cddfSDavid du Colombier    else
1437dd7cddfSDavid du Colombier       png_ptr->read_data_fn = png_default_read_data;
1447dd7cddfSDavid du Colombier #else
1457dd7cddfSDavid du Colombier    png_ptr->read_data_fn = read_data_fn;
1467dd7cddfSDavid du Colombier #endif
1477dd7cddfSDavid du Colombier 
1487dd7cddfSDavid du Colombier    /* It is an error to write to a read device */
149*593dc095SDavid du Colombier    if (png_ptr->write_data_fn != NULL)
150*593dc095SDavid du Colombier    {
1517dd7cddfSDavid du Colombier       png_ptr->write_data_fn = NULL;
152*593dc095SDavid du Colombier       png_warning(png_ptr,
153*593dc095SDavid du Colombier          "It's an error to set both read_data_fn and write_data_fn in the ");
154*593dc095SDavid du Colombier       png_warning(png_ptr,
155*593dc095SDavid du Colombier          "same structure.  Resetting write_data_fn to NULL.");
156*593dc095SDavid du Colombier    }
1577dd7cddfSDavid du Colombier 
1587dd7cddfSDavid du Colombier #if defined(PNG_WRITE_FLUSH_SUPPORTED)
1597dd7cddfSDavid du Colombier    png_ptr->output_flush_fn = NULL;
160*593dc095SDavid du Colombier #endif
1617dd7cddfSDavid du Colombier }
162