/* timepng.c
 *
 * Copyright (c) 2013,2016 John Cunningham Bowler
 *
 * Last changed in libpng 1.6.22 [May 26, 2016]
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
 *
 * Load an arbitrary number of PNG files (from the command line, or, if there
 * are no arguments on the command line, from stdin) then run a time test by
 * reading each file by row or by image (possibly with transforms in the latter
 * case).  The only output is a time as a floating point number of seconds with
 * 9 decimal digits.
 */
#define _POSIX_C_SOURCE 199309L /* for clock_gettime */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>

#include <time.h>

#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
#  include <config.h>
#endif

/* Define the following to use this test against your installed libpng, rather
 * than the one being built here:
 */
#ifdef PNG_FREESTANDING_TESTS
#  include <png.h>
#else
#  include "../../png.h"
#endif

/* The following is to support direct compilation of this file as C++ */
#ifdef __cplusplus
#  define voidcast(type, value) static_cast<type>(value)
#else
#  define voidcast(type, value) (value)
#endif /* __cplusplus */

/* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime.  It
 * need not be supported even when clock_gettime is available.  It returns the
 * 'CPU' time the process has consumed.  'CPU' time is assumed to include time
 * when the CPU is actually blocked by a pending cache fill but not time
 * waiting for page faults.  The attempt is to get a measure of the actual time
 * the implementation takes to read a PNG ignoring the potentially very large IO
 * overhead.
 */
#if defined (CLOCK_PROCESS_CPUTIME_ID) && defined(PNG_STDIO_SUPPORTED) &&\
    defined(PNG_EASY_ACCESS_SUPPORTED) &&\
    (PNG_LIBPNG_VER >= 10700 ? defined(PNG_READ_PNG_SUPPORTED) :\
     defined (PNG_SEQUENTIAL_READ_SUPPORTED) &&\
     defined(PNG_INFO_IMAGE_SUPPORTED))

typedef struct
{
   FILE *input;
   FILE *output;
}  io_data;

static PNG_CALLBACK(void, read_and_copy,
      (png_structp png_ptr, png_bytep buffer, png_size_t cb))
{
   io_data *io = (io_data*)png_get_io_ptr(png_ptr);

   if (fread(buffer, cb, 1, io->input) != 1)
      png_error(png_ptr, strerror(errno));

   if (fwrite(buffer, cb, 1, io->output) != 1)
   {
      perror("temporary file");
      fprintf(stderr, "temporary file PNG write failed\n");
      exit(1);
   }
}

static void read_by_row(png_structp png_ptr, png_infop info_ptr,
      FILE *write_ptr, FILE *read_ptr)
{
   /* These don't get freed on error, this is fine; the program immediately
    * exits.
    */
   png_bytep row = NULL, display = NULL;
   io_data io_copy;

   if (write_ptr != NULL)
   {
      /* Set up for a copy to the temporary file: */
      io_copy.input = read_ptr;
      io_copy.output = write_ptr;
      png_set_read_fn(png_ptr, &io_copy, read_and_copy);
   }

   png_read_info(png_ptr, info_ptr);

   {
      png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);

      row = voidcast(png_bytep,malloc(rowbytes));
      display = voidcast(png_bytep,malloc(rowbytes));

      if (row == NULL || display == NULL)
         png_error(png_ptr, "OOM allocating row buffers");

      {
         png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
         int passes = png_set_interlace_handling(png_ptr);
         int pass;

         png_start_read_image(png_ptr);

         for (pass = 0; pass < passes; ++pass)
         {
            png_uint_32 y = height;

            /* NOTE: this trashes the row each time; interlace handling won't
             * work, but this avoids memory thrashing for speed testing and is
             * somewhat representative of an application that works row-by-row.
             */
            while (y-- > 0)
               png_read_row(png_ptr, row, display);
         }
      }
   }

   /* Make sure to read to the end of the file: */
   png_read_end(png_ptr, info_ptr);

   /* Free this up: */
   free(row);
   free(display);
}

static PNG_CALLBACK(void, no_warnings, (png_structp png_ptr,
         png_const_charp warning))
{
   (void)png_ptr;
   (void)warning;
}

static int read_png(FILE *fp, png_int_32 transforms, FILE *write_file)
{
   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,
         no_warnings);
   png_infop info_ptr = NULL;

   if (png_ptr == NULL)
      return 0;

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
      return 0;
   }

#  ifdef PNG_BENIGN_ERRORS_SUPPORTED
      png_set_benign_errors(png_ptr, 1/*allowed*/);
#  endif
   png_init_io(png_ptr, fp);

   info_ptr = png_create_info_struct(png_ptr);

   if (info_ptr == NULL)
      png_error(png_ptr, "OOM allocating info structure");

   if (transforms < 0)
      read_by_row(png_ptr, info_ptr, write_file, fp);

   else
      png_read_png(png_ptr, info_ptr, transforms, NULL/*params*/);

   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
   return 1;
}

static int mytime(struct timespec *t)
{
   /* Do the timing using clock_gettime and the per-process timer. */
   if (!clock_gettime(CLOCK_PROCESS_CPUTIME_ID, t))
      return 1;

   perror("CLOCK_PROCESS_CPUTIME_ID");
   fprintf(stderr, "timepng: could not get the time\n");
   return 0;
}

static int perform_one_test(FILE *fp, int nfiles, png_int_32 transforms)
{
   int i;
   struct timespec before, after;

   /* Clear out all errors: */
   rewind(fp);

   if (mytime(&before))
   {
      for (i=0; i<nfiles; ++i)
      {
         if (read_png(fp, transforms, NULL/*write*/))
         {
            if (ferror(fp))
            {
               perror("temporary file");
               fprintf(stderr, "file %d: error reading PNG data\n", i);
               return 0;
            }
         }

         else
         {
            perror("temporary file");
            fprintf(stderr, "file %d: error from libpng\n", i);
            return 0;
         }
      }
   }

   else
      return 0;

   if (mytime(&after))
   {
      /* Work out the time difference and print it - this is the only output,
       * so flush it immediately.
       */
      unsigned long s = after.tv_sec - before.tv_sec;
      long ns = after.tv_nsec - before.tv_nsec;

      if (ns < 0)
      {
         --s;
         ns += 1000000000;

         if (ns < 0)
         {
            fprintf(stderr, "timepng: bad clock from kernel\n");
            return 0;
         }
      }

      printf("%lu.%.9ld\n", s, ns);
      fflush(stdout);
      if (ferror(stdout))
      {
         fprintf(stderr, "timepng: error writing output\n");
         return 0;
      }

      /* Successful return */
      return 1;
   }

   else
      return 0;
}

static int add_one_file(FILE *fp, char *name)
{
   FILE *ip = fopen(name, "rb");

   if (ip != NULL)
   {
      /* Read the file using libpng; this detects errors and also deals with
       * files which contain data beyond the end of the file.
       */
      int ok = 0;
      fpos_t pos;

      if (fgetpos(fp, &pos))
      {
         /* Fatal error reading the start: */
         perror("temporary file");
         fprintf(stderr, "temporary file fgetpos error\n");
         exit(1);
      }

      if (read_png(ip, -1/*by row*/, fp/*output*/))
      {
         if (ferror(ip))
         {
            perror(name);
            fprintf(stderr, "%s: read error\n", name);
         }

         else
            ok = 1; /* read ok */
      }

      else
         fprintf(stderr, "%s: file not added\n", name);

      (void)fclose(ip);

      /* An error in the output is fatal; exit immediately: */
      if (ferror(fp))
      {
         perror("temporary file");
         fprintf(stderr, "temporary file write error\n");
         exit(1);
      }

      if (ok)
         return 1;

      /* Did not read the file successfully, simply rewind the temporary
       * file.  This must happen after the ferror check above to avoid clearing
       * the error.
       */
      if (fsetpos(fp, &pos))
      {
         perror("temporary file");
         fprintf(stderr, "temporary file fsetpos error\n");
         exit(1);
      }
   }

   else
   {
      /* file open error: */
      perror(name);
      fprintf(stderr, "%s: open failed\n", name);
   }

   return 0; /* file not added */
}

static void
usage(FILE *fp)
{
   if (fp != NULL) fclose(fp);

   fprintf(stderr,
"Usage:\n"
" timepng --assemble <assembly> {files}\n"
"  Read the files into <assembly>, output the count.  Options are ignored.\n"
" timepng --dissemble <assembly> <count> [options]\n"
"  Time <count> files from <assembly>, additional files may not be given.\n"
" Otherwise:\n"
"  Read the files into a temporary file and time the decode\n"
"Transforms:\n"
"  --by-image: read by image with png_read_png\n"
"  --<transform>: implies by-image, use PNG_TRANSFORM_<transform>\n"
"  Otherwise: read by row using png_read_row (to a single row buffer)\n"
   /* ISO C90 string length max 509 */);fprintf(stderr,
"{files}:\n"
"  PNG files to copy into the assembly and time.  Invalid files are skipped\n"
"  with appropriate error messages.  If no files are given the list of files\n"
"  is read from stdin with each file name terminated by a newline\n"
"Output:\n"
"  For --assemble the output is the name of the assembly file followed by the\n"
"  count of the files it contains; the arguments for --dissemble.  Otherwise\n"
"  the output is the total decode time in seconds.\n");

   exit(99);
}

int main(int argc, char **argv)
{
   int ok = 0;
   int err = 0;
   int nfiles = 0;
   int transforms = -1; /* by row */
   const char *assembly = NULL;
   FILE *fp;

   if (argc > 2 && strcmp(argv[1], "--assemble") == 0)
   {
      /* Just build the test file, argv[2] is the file name. */
      assembly = argv[2];
      fp = fopen(assembly, "wb");
      if (fp == NULL)
      {
         perror(assembly);
         fprintf(stderr, "timepng --assemble %s: could not open for write\n",
               assembly);
         usage(NULL);
      }

      argv += 2;
      argc -= 2;
   }

   else if (argc > 3 && strcmp(argv[1], "--dissemble") == 0)
   {
      fp = fopen(argv[2], "rb");

      if (fp == NULL)
      {
         perror(argv[2]);
         fprintf(stderr, "timepng --dissemble %s: could not open for read\n",
               argv[2]);
         usage(NULL);
      }

      nfiles = atoi(argv[3]);
      if (nfiles <= 0)
      {
         fprintf(stderr,
               "timepng --dissemble <file> <count>: %s is not a count\n",
               argv[3]);
         exit(99);
      }
#ifdef __COVERITY__
      else
      {
         nfiles &= PNG_UINT_31_MAX;
      }
#endif

      argv += 3;
      argc -= 3;
   }

   else /* Else use a temporary file */
   {
#ifndef __COVERITY__
      fp = tmpfile();
#else
      /* Experimental. Coverity says tmpfile() is insecure because it
       * generates predictable names.
       *
       * It is possible to satisfy Coverity by using mkstemp(); however,
       * any platform supporting mkstemp() undoubtedly has a secure tmpfile()
       * implementation as well, and doesn't need the fix.  Note that
       * the fix won't work on platforms that don't support mkstemp().
       *
       * https://www.securecoding.cert.org/confluence/display/c/
       * FIO21-C.+Do+not+create+temporary+files+in+shared+directories
       * says that most historic implementations of tmpfile() provide
       * only a limited number of possible temporary file names
       * (usually 26) before file names are recycled. That article also
       * provides a secure solution that unfortunately depends upon mkstemp().
       */
      char tmpfile[] = "timepng-XXXXXX";
      int filedes;
      umask(0177);
      filedes = mkstemp(tmpfile);
      if (filedes < 0)
        fp = NULL;
      else
      {
        fp = fdopen(filedes,"w+");
        /* Hide the filename immediately and ensure that the file does
         * not exist after the program ends
         */
        (void) unlink(tmpfile);
      }
#endif

      if (fp == NULL)
      {
         perror("tmpfile");
         fprintf(stderr, "timepng: could not open the temporary file\n");
         exit(1); /* not a user error */
      }
   }

   /* Handle the transforms: */
   while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-')
   {
      const char *opt = *++argv + 2;

      --argc;

      /* Transforms turn on the by-image processing and maybe set some
       * transforms:
       */
      if (transforms == -1)
         transforms = PNG_TRANSFORM_IDENTITY;

      if (strcmp(opt, "by-image") == 0)
      {
         /* handled above */
      }

#        define OPT(name) else if (strcmp(opt, #name) == 0)\
         transforms |= PNG_TRANSFORM_ ## name

      OPT(STRIP_16);
      OPT(STRIP_ALPHA);
      OPT(PACKING);
      OPT(PACKSWAP);
      OPT(EXPAND);
      OPT(INVERT_MONO);
      OPT(SHIFT);
      OPT(BGR);
      OPT(SWAP_ALPHA);
      OPT(SWAP_ENDIAN);
      OPT(INVERT_ALPHA);
      OPT(STRIP_FILLER);
      OPT(STRIP_FILLER_BEFORE);
      OPT(STRIP_FILLER_AFTER);
      OPT(GRAY_TO_RGB);
      OPT(EXPAND_16);
      OPT(SCALE_16);

      else
      {
         fprintf(stderr, "timepng %s: unrecognized transform\n", opt);
         usage(fp);
      }
   }

   /* Handle the files: */
   if (argc > 1 && nfiles > 0)
      usage(fp); /* Additional files not valid with --dissemble */

   else if (argc > 1)
   {
      int i;

      for (i=1; i<argc; ++i)
      {
         if (nfiles == INT_MAX)
         {
            fprintf(stderr, "%s: skipped, too many files\n", argv[i]);
            break;
         }

         else if (add_one_file(fp, argv[i]))
            ++nfiles;
      }
   }

   else if (nfiles == 0) /* Read from stdin withoout --dissemble */
   {
      char filename[FILENAME_MAX+1];

      while (fgets(filename, FILENAME_MAX+1, stdin))
      {
         size_t len = strlen(filename);

         if (filename[len-1] == '\n')
         {
            filename[len-1] = 0;
            if (nfiles == INT_MAX)
            {
               fprintf(stderr, "%s: skipped, too many files\n", filename);
               break;
            }

            else if (add_one_file(fp, filename))
               ++nfiles;
         }

         else
         {
            fprintf(stderr, "timepng: file name too long: ...%s\n",
               filename+len-32);
            err = 1;
            break;
         }
      }

      if (ferror(stdin))
      {
         fprintf(stderr, "timepng: stdin: read error\n");
         err = 1;
      }
   }

   /* Perform the test, or produce the --assemble output: */
   if (!err)
   {
      if (nfiles > 0)
      {
         if (assembly != NULL)
         {
            if (fflush(fp) && !ferror(fp) && fclose(fp))
            {
               perror(assembly);
               fprintf(stderr, "%s: close failed\n", assembly);
            }

            else
            {
               printf("%s %d\n", assembly, nfiles);
               fflush(stdout);
               ok = !ferror(stdout);
            }
         }

         else
         {
            ok = perform_one_test(fp, nfiles, transforms);
            (void)fclose(fp);
         }
      }

      else
         usage(fp);
   }

   else
      (void)fclose(fp);

   /* Exit code 0 on success. */
   return ok == 0;
}
#else /* !sufficient support */
int main(void) { return 77; }
#endif /* !sufficient support */
