root/ext/gd/libgd/webpng.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getpid
  2. main

/* Bring in the gd library functions */
#include "gd.h"

/* Bring in standard I/O and string manipulation functions */
#include <stdio.h>
#include <stdlib.h>             /* for atoi() */
#include <string.h>

#ifdef _WIN32
#include <process.h>
int
getpid ()
{
  return _getpid ();
}
#else
#include <unistd.h>             /* for getpid(), unlink() */
#endif
int
main (int argc, char **argv)
{
  FILE *in;
  FILE *out;
  char outFn[20];
  int useStdinStdout = 0;

  /* Declare our image pointer */
  gdImagePtr im = 0;
  int i;
  /* We'll clear 'no' once we know the user has made a
     reasonable request. */
  int no = 1;
  /* We'll set 'write' once we know the user's request
     requires that the image be written back to disk. */
  int write = 0;
  /* C programs always get at least one argument; we want at
     least one more (the image), more in practice. */
  if (argc < 2 || !strcmp (argv[1], "--help"))
    {
      no = 1;
      goto usage;
    }

  /* The last argument should be the image. Open the file. */
  if (strcmp ("-", argv[argc - 1]) == 0)
    {                           /* - is synonymous with STDIN */
      useStdinStdout = 1;
      in = stdin;
    }
  else
    {
      in = fopen (argv[argc - 1], "rb");
    }
  if (!in)
    {
      fprintf (stderr,
               "Error: can't open file %s.\n", argv[argc - 1]);
      exit (1);
    }
  /* Now load the image. */
  im = gdImageCreateFromPng (in);
  fclose (in);
  /* If the load failed, it must not be a PNG file. */
  if (!im)
    {
      fprintf (stderr,
               "Error: %s is not a valid PNG file.\n", argv[argc - 1]);
      exit (1);
    }
  /* Consider each argument in turn. */
  for (i = 1; (i < (argc - 1)); i++)
    {
      /* -i turns on and off interlacing. */
      if (!strcmp (argv[i], "--help"))
        {
          /* Every program should use this for help! :) */
          no = 1;
          goto usage;
        }
      else if (!strcmp (argv[i], "-i"))
        {
          if (i == (argc - 2))
            {
              fprintf (stderr,
                       "Error: -i specified without y or n.\n");
              no = 1;
              goto usage;
            }
          if (!strcmp (argv[i + 1], "y"))
            {
              /* Set interlace. */
              gdImageInterlace (im, 1);
            }
          else if (!strcmp (argv[i + 1], "n"))
            {
              /* Clear interlace. */
              gdImageInterlace (im, 0);
            }
          else
            {
              fprintf (stderr,
                       "Error: -i specified without y or n.\n");
              no = 1;
              goto usage;
            }
          i++;
          no = 0;
          write = 1;
        }
      else if (!strcmp (argv[i], "-t"))
        {
          /* Set transparent index (or none). */
          int index;
          if (i == (argc - 2))
            {
              fprintf (stderr,
                       "Error: -t specified without a color table index.\n");
              no = 1;
              goto usage;
            }
          if (!strcmp (argv[i + 1], "none"))
            {
              /* -1 means not transparent. */
              gdImageColorTransparent (im, -1);
            }
          else
            {
              /* OK, get an integer and set the index. */
              index = atoi (argv[i + 1]);
              gdImageColorTransparent (im, index);
            }
          i++;
          write = 1;
          no = 0;
        }
      else if (!strcmp (argv[i], "-l"))
        {
          /* List the colors in the color table. */
          int j;
          if (!im->trueColor)
            {
              /* Tabs used below. */
              printf ("Index    Red     Green   Blue Alpha\n");
              for (j = 0; (j < gdImageColorsTotal (im)); j++)
                {
                  /* Use access macros to learn colors. */
                  printf ("%d   %d      %d      %d      %d\n",
                          j,
                          gdImageRed (im, j),
                          gdImageGreen (im, j),
                          gdImageBlue (im, j),
                          gdImageAlpha (im, j));
                }
            }
          else
            {
              printf ("Truecolor image, no palette entries to list.\n");
            }
          no = 0;
        }
      else if (!strcmp (argv[i], "-d"))
        {
          /* Output dimensions, etc. */
          int t;
          printf ("Width: %d Height: %d Colors: %d\n",
                  gdImageSX (im), gdImageSY (im),
                  gdImageColorsTotal (im));
          t = gdImageGetTransparent (im);
          if (t != (-1))
            {
                                printf ("First 100%% transparent index: %d\n", t);
            }
          else
            {
              /* -1 means the image is not transparent. */
                                printf ("First 100%% transparent index: none\n");
            }
          if (gdImageGetInterlaced (im))
            {
              printf ("Interlaced: yes\n");
            }
          else
            {
              printf ("Interlaced: no\n");
            }
          no = 0;
        }
                else if (!strcmp(argv[i], "-a"))
                {
                        int maxx, maxy, x, y, alpha, pix, nalpha = 0;

                        maxx = gdImageSX(im);
                        maxy = gdImageSY(im);

                        printf("alpha channel information:\n");

                        if (im->trueColor)      {
                                for (y = 0; y < maxy; y++)      {
                                        for (x = 0; x < maxx; x++)      {
                                                pix = gdImageGetPixel(im, x, y);
                                                alpha = gdTrueColorGetAlpha(pix);

                                                if (alpha > gdAlphaOpaque)      {
                                                        /* Use access macros to learn colors. */
                                                        printf ("%d     %d      %d      %d\n",
                                                                        gdTrueColorGetRed(pix),
                                                                        gdTrueColorGetGreen(pix),
                                                                        gdTrueColorGetBlue(pix),
                                                                        alpha);
                                                        nalpha++;
                                                }

                                        }
                                }
                        }
                        else
                                printf("NOT a true color image\n");
                        no = 0;
                        printf("%d alpha channels\n", nalpha);

                }
      else
        {
          fprintf (stderr, "Unknown argument: %s\n", argv[i]);
          break;
        }
    }
usage:
  if (no)
    {
      /* If the command failed, output an explanation. */
      fprintf (stderr,
          "Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n"

               "  -i [y|n]   Turns on/off interlace\n"
               "  -l         Prints the table of color indexes\n"
               "  -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n"
               "  -d         Reports the dimensions and other characteristics of the image.\n"
                                "  -a         Prints all alpha channels that are not 100%% opaque.\n"
               "\n"
               "If you specify '-' as the input file, stdin/stdout will be used input/output.\n"
        );
    }
  if (write)
    {
      if (useStdinStdout)
        {
          out = stdout;
        }
      else
        {
          /* Open a temporary file. */

          /* "temp.tmp" is not good temporary filename. */
          snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ());
          out = fopen (outFn, "wb");

          if (!out)
            {
              fprintf (stderr,
                       "Unable to write to %s -- exiting\n", outFn);
              exit (1);
            }
        }

      /* Write the new PNG. */
      gdImagePng (im, out);

      if (!useStdinStdout)
        {
          fclose (out);
          /* Erase the old PNG. */
          unlink (argv[argc - 1]);
          /* Rename the new to the old. */
          if (rename (outFn, argv[argc - 1]) != 0)
            {
              perror ("rename");
              exit (1);
            }
        }
    }
  /* Delete the image from memory. */
  if (im)
    {
      gdImageDestroy (im);
    }
  /* All's well that ends well. */
  return 0;
}

/* [<][>][^][v][top][bottom][index][help] */