18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pngrio.c - functions for data input
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Last changed in libpng 1.2.13 November 13, 2006
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in png.h
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1998-2006 Glenn Randers-Pehrson
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This file provides a location for all input.  Users who need
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * special handling are expected to write a function that has the same
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * arguments as this and performs a similar function, but that possibly
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * has a different input method.  Note that you shouldn't change this
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * function, but rather write a replacement function and then make
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * libpng use it at run time with png_set_read_fn(...).
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_INTERNAL
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "png.h"
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_SUPPORTED)
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Read the data from whatever input you are using.  The default routine
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   reads from a file pointer.  Note that this routine sometimes gets called
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   with very small lengths, so you should implement some kind of simple
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   buffering if you are using unbuffered reads.  This should never be asked
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   to read more then 64K on a 16 bit machine. */
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(4,"reading %d bytes\n", (int)length);
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->read_data_fn != NULL)
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (*(png_ptr->read_data_fn))(png_ptr, data, length);
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Call to NULL read function");
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_STDIO)
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* This is the function that does the actual reading of data.  If you are
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   not reading from a standard C stream, you should create a replacement
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   read_data function and use it at run time with png_set_read_fn(), rather
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   than changing the library. */
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef USE_FAR_KEYWORD
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t check;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(png_ptr == NULL) return;
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* fread() returns 0 on error, so it is OK to store this in a png_size_t
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * instead of an int, which is what fread() actually returns.
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    */
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(_WIN32_WCE)
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      check = 0;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   check = (png_size_t)fread(data, (png_size_t)1, length,
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_FILE_p)png_ptr->io_ptr);
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (check != length)
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Read Error");
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this is the model-independent version. Since the standard I/O library
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   can't handle far buffers in the medium and small models, we have to copy
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the data.
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEAR_BUF_SIZE 1024
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MIN(a,b) (a <= b ? a : b)
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void PNGAPI
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int check;
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte *n_data;
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_FILE_p io_ptr;
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(png_ptr == NULL) return;
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Check if data really is near. If so, use usual code. */
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   n_data = (png_byte *)CVT_PTR_NOCHECK(data);
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_bytep)n_data == data)
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(_WIN32_WCE)
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         check = 0;
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      check = fread(n_data, 1, length, io_ptr);
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[NEAR_BUF_SIZE];
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_size_t read, remaining, err;
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      check = 0;
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      remaining = length;
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         read = MIN(NEAR_BUF_SIZE, remaining);
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(_WIN32_WCE)
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            err = 0;
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         err = fread(buf, (png_size_t)1, read, io_ptr);
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_memcpy(data, buf, read); /* copy far buffer to near buffer */
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if(err != read)
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            check += err;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         data += read;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         remaining -= read;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      while (remaining != 0);
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_uint_32)check != (png_uint_32)length)
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "read Error");
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* This function allows the application to supply a new input function
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for libpng if standard C streams aren't being used.
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   This function takes as its arguments:
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr      - pointer to a png input data structure
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   io_ptr       - pointer to user supplied structure containing info about
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  the input functions.  May be NULL.
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   read_data_fn - pointer to a new input function that takes as its
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  arguments a pointer to a png_struct, a pointer to
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  a location where input data can be stored, and a 32-bit
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  unsigned int that is the number of bytes to be read.
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  To exit and output any fatal error messages the new write
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  function should call png_error(png_ptr, "Error msg"). */
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_rw_ptr read_data_fn)
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(png_ptr == NULL) return;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->io_ptr = io_ptr;
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_STDIO)
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (read_data_fn != NULL)
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->read_data_fn = read_data_fn;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->read_data_fn = png_default_read_data;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->read_data_fn = read_data_fn;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* It is an error to write to a read device */
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->write_data_fn != NULL)
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->write_data_fn = NULL;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr,
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         "It's an error to set both read_data_fn and write_data_fn in the ");
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr,
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         "same structure.  Resetting write_data_fn to NULL.");
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_FLUSH_SUPPORTED)
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->output_flush_fn = NULL;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_SUPPORTED */
168