/* example.c - an example of using libpng */

/* this is an example of how to use libpng to read and write
   png files.  The file libpng.txt is much more verbose then
   this.  If you have not read it, do so first.  This was
   designed to be a starting point of an implementation.
   This is not officially part of libpng, and therefore
   does not require a copyright notice.
   */

#include <png.h>

/* check to see if a file is a png file using png_check_sig() */
int check_png(char *file_name)
{
   FILE *fp;
   char buf[8];
   int ret;

   fp = fopen(file_name, "rb");
   if (!fp)
      return 0;
   ret = fread(buf, 1, 8, fp);
   fclose(fp);

   if (ret != 8)
      return 0;

   ret = png_check_sig(buf, 8);

   return (ret);
}

/* read a png file.  You may want to return an error code if the read
   fails (depending upon the failure). */
void read_png(char *file_name)
{
   FILE *fp;
   png_struct *png_ptr;
   png_info *info_ptr;

   /* open the file */
   fp = fopen(file_name, "rb");
   if (!fp)
      return;

   /* allocate the necessary structures */
   png_ptr = malloc(sizeof (png_struct));
   if (!png_ptr)
   {
      fclose(fp);
      return;
   }

   info_ptr = malloc(sizeof (png_info));
   if (!info_ptr)
   {
      fclose(fp);
      free(png_ptr);
      return;
   }

   /* set error handling */
   if (setjmp(png_ptr->jmpbuf))
   {
      png_read_destroy(png_ptr, info_ptr, (png_info *)0);
      fclose(fp);
      free(png_ptr);
      free(info_ptr);
      /* If we get here, we had a problem reading the file */
      return;
   }

   /* initialize the structures, info first for error handling */
   png_info_init(info_ptr);
   png_read_init(png_ptr);

   /* set up the input control */
   png_init_io(png_ptr, fp);

   /* read the file information */
   png_read_info(png_ptr, info_ptr);

   /* allocate the memory to hold the image using the fields
      of png_info. */

   /* set up the transformations you want.  Note that these are
      all optional.  Only call them if you want them */

   /* expand paletted colors into true rgb */
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
      info_ptr->bit_depth < 8)
      png_set_expand(png_ptr);

   /* expand grayscale images to the full 8 bits */
   if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
      info_ptr->bit_depth < 8)
      png_set_expand(png_ptr);

   /* expand images with transparency to full alpha channels */
   if (info_ptr->valid & PNG_INFO_tRNS)
      png_set_expand(png_ptr);

   /* Set the background color to draw transparent and alpha
      images over */
   png_color_16 my_background;

   if (info_ptr->valid & PNG_INFO_bKGD)
      png_set_background(png_ptr, &(info_ptr->background),
         PNG_GAMMA_FILE, 1, 1.0);
   else
      png_set_background(png_ptr, &my_background,
         PNG_GAMMA_SCREEN, 0, 1.0);

   /* tell libpng to handle the gamma conversion for you */
   if (info_ptr->valid & PNG_INFO_gAMA)
      png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma);
   else
      png_set_gamma(png_ptr, screen_gamma, 0.45);

   /* tell libpng to strip 16 bit depth files down to 8 bits */
   if (info_ptr->bit_depth == 16)
      png_set_strip_16(png_ptr);

   /* dither rgb files down to 8 bit palettes & reduce palettes
      to the number of colors available on your screen */
   if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
   {
      if (info_ptr->valid & PNG_INFO_PLTE)
         png_set_dither(png_ptr, info_ptr->palette,
            info_ptr->num_palette, max_screen_colors,
               info_ptr->histogram);
      else
      {
         png_color std_color_cube[MAX_SCREEN_COLORS] =
            {/* ... colors ... */};

         png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
            MAX_SCREEN_COLORS, NULL);
      }
   }

   /* invert monocrome files */
   if (info_ptr->bit_depth == 1 &&
      info_ptr->color_type == PNG_COLOR_GRAY)
      png_set_invert(png_ptr);

   /* shift the pixels down to their true bit depth */
   if (info_ptr->valid & PNG_INFO_sBIT &&
      info_ptr->bit_depth > info_ptr->sig_bit)
      png_set_shift(png_ptr, &(info_ptr->sig_bit));

   /* pack pixels into bytes */
   if (info_ptr->bit_depth < 8)
      png_set_packing(png_ptr);

   /* flip the rgb pixels to bgr */
   if (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
      info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
      png_set_bgr(png_ptr);

   /* swap bytes of 16 bit files to least significant bit first */
   if (info_ptr->bit_depth == 16)
      png_set_swap(png_ptr);

   /* add a filler byte to store rgb files as rgbx */
   if (info_ptr->bit_depth == 8 &&
      info_ptr->color_type == PNG_COLOR_TYPE_RGB)
      png_set_rgbx(png_ptr);

   /* optional call to update palette with transformations */
   png_start_read_image(png_ptr);

   /* the easiest way to read the image */
   void *row_pointers[height];
   png_read_image(png_ptr, row_pointers);

   /* the other way to read images - deal with interlacing */

   /* turn on interlace handling */
   if (info_ptr->interlace_type)
      number_passes = png_set_interlace_handling(png_ptr);
   else
      number_passes = 1;

   for (pass = 0; pass < number_passes; pass++)
   {
      /* Read the image using the "sparkle" effect. */
      png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);

      /* If you are only reading on row at a time, this works */
      for (y = 0; y < height; y++)
      {
         char *row_pointers = row[y];
         png_read_rows(png_ptr, &row_pointers, NULL, 1);
      }

      /* to get the rectangle effect, use the third parameter */
      png_read_rows(png_ptr, NULL, row_pointers, number_of_rows);

      /* if you want to display the image after every pass, do
         so here */
   }

   /* read the rest of the file, getting any additional chunks
      in info_ptr */
   png_read_end(png_ptr, info_ptr);

   /* clean up after the read, and free any memory allocated */
   png_read_destroy(png_ptr, info_ptr, (png_info *)0);

   /* free the structures */
   free(png_ptr);
   free(info_ptr);

   /* close the file */
   fclose(fp);

   /* that's it */
   return;
}

/* write a png file */
void write_png(char *file_name, ... other image information ...)
{
   FILE *fp;
   png_struct *png_ptr;
   png_info *info_ptr;

   /* open the file */
   fp = fopen(file_name, "wb");
   if (!fp)
      return;

   /* allocate the necessary structures */
   png_ptr = malloc(sizeof (png_struct));
   if (!png_ptr)
   {
      fclose(fp);
      return;
   }

   info_ptr = malloc(sizeof (png_info));
   if (!info_ptr)
   {
      fclose(fp);
      free(png_ptr);
      return;
   }

   /* set error handling */
   if (setjmp(png_ptr->jmpbuf))
   {
      png_write_destroy(png_ptr);
      fclose(fp);
      free(png_ptr);
      free(info_ptr);
      /* If we get here, we had a problem reading the file */
      return;
   }

   /* initialize the structures */
   png_info_init(info_ptr);
   png_write_init(png_ptr);

   /* set up the output control */
   png_init_io(png_ptr, fp);

   /* set the file information here */
   info_ptr->width = ;
   info_ptr->height = ;
   etc.

   /* set the palette if there is one */
   info_ptr->valid |= PNG_INFO_PLTE;
   info_ptr->palette = malloc(256 * sizeof (png_color));
   info_ptr->num_palette = 256;
   ... set palette colors ...

   /* optional significant bit chunk */
   info_ptr->valid |= PNG_INFO_sBIT;
   info_ptr->sig_bit = true_bit_depth;

   /* optional gamma chunk */
   info_ptr->valid |= PNG_INFO_gAMA;
   info_ptr->gamma = gamma;

   /* other optional chunks */

   /* write the file information */
   png_write_info(png_ptr, info_ptr);

   /* set up the transformations you want.  Note that these are
      all optional.  Only call them if you want them */

   /* invert monocrome pixels */
   png_set_invert(png_ptr);

   /* shift the pixels up to a legal bit depth and fill in
      as appropriate to correctly scale the image */
   png_set_shift(png_ptr, &(info_ptr->sig_bit));

   /* pack pixels into bytes */
   png_set_packing(png_ptr);

   /* flip bgr pixels to rgb */
   png_set_bgr(png_ptr);

   /* swap bytes of 16 bit files to most significant bit first */
   png_set_swap(png_ptr);

   /* get rid of filler bytes, pack rgb into 3 bytes */
   png_set_rgbx(png_ptr);

   /* the easiest way to write the image */
   void *row_pointers[height];
   png_write_image(png_ptr, row_pointers);

   /* the other way to write the image - deal with interlacing */

   /* turn on interlace handling */
   if (interlacing)
      number_passes = png_set_interlace_handling(png_ptr);
   else
      number_passes = 1;

   for (pass = 0; pass < number_passes; pass++)
   {
      /* Write a few rows at a time. */
      png_write_rows(png_ptr, row_pointers, number_of_rows);

      /* If you are only writing one row at a time, this works */
      for (y = 0; y < height; y++)
      {
         char *row_pointers = row[y];
         png_write_rows(png_ptr, &row_pointers, 1);
      }
   }

   /* write the rest of the file */
   png_write_end(png_ptr, info_ptr);

   /* clean up after the write, and free any memory allocated */
   png_write_destroy(png_ptr);

   /* if you malloced the palette, free it here */
   if (info_ptr->palette)
      free(info_ptr->palette);

   /* free the structures */
   free(png_ptr);
   free(info_ptr);

   /* close the file */
   fclose(fp);

   /* that's it */
   return;
}

