/*- iccfrompng
 *
 * COPYRIGHT: Written by John Cunningham Bowler, 2011.
 * To the extent possible under law, the author has waived all copyright and
 * related or neighboring rights to this work.  This work is published from:
 * United States.
 *
 * Extract any icc profiles found in the given PNG files.  This is a simple
 * example of a program which extracts information from the header of a PNG file
 * without processing the image.  Notice that some header information may occur
 * after the image data, textual data and comments are an example; the approach
 * in this file won't work reliably for such data because it only looks for the
 * information in the section of the file that preceeds the image data.
 *
 * Compile and link against libpng and zlib, plus anything else required on the
 * system you use.
 *
 * To use supply a list of PNG files containing iCCP chunks, the chunks will be
 * extracted to a similarly named file with the extension replaced by 'icc',
 * which will be overwritten without warning.
 */
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
#include <stdio.h>

#include <png.h>

static int verbose = 1;
static png_byte no_profile[] = "no profile";

static png_bytep
extract(FILE *fp, png_uint_32 *proflen)
{
   png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
   png_infop info_ptr = NULL;
   png_bytep result = NULL;

   /* Initialize for error or no profile: */
   *proflen = 0;

   if (png_ptr == NULL)
   {
      fprintf(stderr, "iccfrompng: version library mismatch?\n");
      return 0;
   }

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

   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");

   png_read_info(png_ptr, info_ptr);

   {
      png_charp name;
      int compression_type;
      png_bytep profile;

      if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile,
         proflen) & PNG_INFO_iCCP)
      {
         result = malloc(*proflen);
         if (result != NULL)
            memcpy(result, profile, *proflen);

         else
            png_error(png_ptr, "OOM allocating profile buffer");
      }

      else
	result = no_profile;
   }

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

static int
extract_one_file(const char *filename)
{
   int result = 0;
   FILE *fp = fopen(filename, "rb");

   if (fp != NULL)
   {
      png_uint_32 proflen = 0;
      png_bytep profile = extract(fp, &proflen);

      if (profile != NULL && profile != no_profile)
      {
         size_t len;
         char *output;

         {
            const char *ep = strrchr(filename, '.');

            if (ep != NULL)
               len = ep-filename;

            else
               len = strlen(filename);
         }

         output = malloc(len + 5);
         if (output != NULL)
         {
            FILE *of;

            memcpy(output, filename, len);
            strcpy(output+len, ".icc");

            of = fopen(output, "wb");
            if (of != NULL)
            {
               if (fwrite(profile, proflen, 1, of) == 1 &&
                  fflush(of) == 0 &&
                  fclose(of) == 0)
               {
                  if (verbose)
                     printf("%s -> %s\n", filename, output);
                  /* Success return */
                  result = 1;
               }

               else
               {
                  fprintf(stderr, "%s: error writing profile\n", output);
                  if (remove(output))
                     fprintf(stderr, "%s: could not remove file\n", output);
               }
            }

            else
               fprintf(stderr, "%s: failed to open output file\n", output);

            free(output);
         }

         else
            fprintf(stderr, "%s: OOM allocating string!\n", filename);

         free(profile);
      }

      else if (verbose && profile == no_profile)
	printf("%s has no profile\n", filename);
   }

   else
      fprintf(stderr, "%s: could not open file\n", filename);

   return result;
}

int
main(int argc, char **argv)
{
   int i;
   int extracted = 0;

   for (i=1; i<argc; ++i)
   {
      if (strcmp(argv[i], "-q") == 0)
         verbose = 0;

      else if (extract_one_file(argv[i]))
         extracted = 1;
   }

   /* Exit code is true if any extract succeeds */
   return extracted == 0;
}
