
/* pngerror.c - stub functions for i/o and memory allocation
 *
 * libpng 0.99e
 * For conditions of distribution and use, see copyright notice in png.h
 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
 * Copyright (c) 1996, 1997 Andreas Dilger
 * Copyright (c) 1998, Glenn Randers-Pehrson
 * February 28, 1998
 *
 * This file provides a location for all error handling.  Users which
 * need special error handling are expected to write replacement functions
 * and use png_set_error_fn() to use those functions.  See the instructions
 * at each function.
 */

#define PNG_INTERNAL
#include "png.h"

static void png_default_error PNGARG((png_structp png_ptr,
                                      png_const_charp message));
static void png_default_warning PNGARG((png_structp png_ptr,
                                        png_const_charp message));

/* This function is called whenever there is a fatal error.  This function
 * should not be changed.  If there is a need to handle errors differently,
 * you should supply a replacement error function and use png_set_error_fn()
 * to replace the error function at run-time.
 */
void
png_error(png_structp png_ptr, png_const_charp message)
{
   if (png_ptr->error_fn != NULL)
      (*(png_ptr->error_fn))(png_ptr, message);

   /* if the following returns or doesn't exist, use the default function,
      which will not return */
   png_default_error(png_ptr, message);
}

/* This function is called whenever there is a non-fatal error.  This function
 * should not be changed.  If there is a need to handle warnings differently,
 * you should supply a replacement warning function and use
 * png_set_error_fn() to replace the warning function at run-time.
 */
void
png_warning(png_structp png_ptr, png_const_charp message)
{
   if (png_ptr->warning_fn != NULL)
      (*(png_ptr->warning_fn))(png_ptr, message);
   else
      png_default_warning(png_ptr, message);
}

/* These utilities are used internally to build an error message which relates
 * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
 * this is used to prefix the message.  The message is limited in length
 * to 63 bytes, the name characters are output as hex digits wrapped in []
 * if the character is invalid.
 */
#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
static const char png_digit[16] = {
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};

static void
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp message)
{
   int iout = 0, iin = 0;

   while (iin < 4) {
      int c = png_ptr->chunk_name[iin++];
      if (isnonalpha(c)) {
         buffer[iout++] = '[';
         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
         buffer[iout++] = png_digit[c & 0xf];
         buffer[iout++] = ']';
      } else {
         buffer[iout++] = c;
      }
   }

   if (message == NULL)
      buffer[iout] = 0;
   else {
      buffer[iout++] = ':';
      buffer[iout++] = ' ';
      png_memcpy(buffer+iout, message, 64);
      buffer[iout+63] = 0;
   }
}

void
png_chunk_error(png_structp png_ptr, png_const_charp message)
{
   char msg[16+64];
   png_format_buffer(png_ptr, msg, message);
   png_error(png_ptr, msg);
}

void
png_chunk_warning(png_structp png_ptr, png_const_charp message)
{
   char msg[16+64];
   png_format_buffer(png_ptr, msg, message);
   png_warning(png_ptr, msg);
}

/* This is the default error handling function.  Note that replacements for
 * this function MUST NOT RETURN, or the program will likely crash.  This
 * function is used by default, or if the program supplies NULL for the
 * error function pointer in png_set_error_fn().
 */
static void
png_default_error(png_structp png_ptr, png_const_charp message)
{
#ifndef PNG_NO_STDIO
   fprintf(stderr, "libpng error: %s\n", message);
#endif

#ifdef USE_FAR_KEYWORD
   {
      jmp_buf jmpbuf;
      png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
      longjmp(jmpbuf, 1);
   }
#else
   longjmp(png_ptr->jmpbuf, 1);
#endif
}

/* This function is called when there is a warning, but the library thinks
 * it can continue anyway.  Replacement functions don't have to do anything
 * here if you don't want to.  In the default configuration, png_ptr is
 * not used, but it is passed in case it may be useful.
 */
static void
png_default_warning(png_structp png_ptr, png_const_charp message)
{
   if (png_ptr == NULL)
      return;

#ifndef PNG_NO_STDIO
   fprintf(stderr, "libpng warning: %s\n", message);
#endif
}

/* This function is called when the application wants to use another method
 * of handling errors and warnings.  Note that the error function MUST NOT
 * return to the calling routine or serious problems will occur.  The return
 * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
 */
void
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
   png_error_ptr error_fn, png_error_ptr warning_fn)
{
   png_ptr->error_ptr = error_ptr;
   png_ptr->error_fn = error_fn;
   png_ptr->warning_fn = warning_fn;
}


/* This function returns a pointer to the error_ptr associated with the user
 * functions.  The application should free any memory associated with this
 * pointer before png_write_destroy and png_read_destroy are called.
 */
png_voidp
png_get_error_ptr(png_structp png_ptr)
{
   return ((png_voidp)png_ptr->error_ptr);
}



