Back to index

php5  5.3.10
webpng.c
Go to the documentation of this file.
00001 /* Bring in the gd library functions */
00002 #include "gd.h"
00003 
00004 /* Bring in standard I/O and string manipulation functions */
00005 #include <stdio.h>
00006 #include <stdlib.h>         /* for atoi() */
00007 #include <string.h>
00008 
00009 #ifdef _WIN32
00010 #include <process.h>
00011 int
00012 getpid ()
00013 {
00014   return _getpid ();
00015 }
00016 #else
00017 #include <unistd.h>         /* for getpid(), unlink() */
00018 #endif
00019 int
00020 main (int argc, char **argv)
00021 {
00022   FILE *in;
00023   FILE *out;
00024   char outFn[20];
00025   int useStdinStdout = 0;
00026 
00027   /* Declare our image pointer */
00028   gdImagePtr im = 0;
00029   int i;
00030   /* We'll clear 'no' once we know the user has made a
00031      reasonable request. */
00032   int no = 1;
00033   /* We'll set 'write' once we know the user's request
00034      requires that the image be written back to disk. */
00035   int write = 0;
00036   /* C programs always get at least one argument; we want at
00037      least one more (the image), more in practice. */
00038   if (argc < 2 || !strcmp (argv[1], "--help"))
00039     {
00040       no = 1;
00041       goto usage;
00042     }
00043 
00044   /* The last argument should be the image. Open the file. */
00045   if (strcmp ("-", argv[argc - 1]) == 0)
00046     {                       /* - is synonymous with STDIN */
00047       useStdinStdout = 1;
00048       in = stdin;
00049     }
00050   else
00051     {
00052       in = fopen (argv[argc - 1], "rb");
00053     }
00054   if (!in)
00055     {
00056       fprintf (stderr,
00057               "Error: can't open file %s.\n", argv[argc - 1]);
00058       exit (1);
00059     }
00060   /* Now load the image. */
00061   im = gdImageCreateFromPng (in);
00062   fclose (in);
00063   /* If the load failed, it must not be a PNG file. */
00064   if (!im)
00065     {
00066       fprintf (stderr,
00067               "Error: %s is not a valid PNG file.\n", argv[argc - 1]);
00068       exit (1);
00069     }
00070   /* Consider each argument in turn. */
00071   for (i = 1; (i < (argc - 1)); i++)
00072     {
00073       /* -i turns on and off interlacing. */
00074       if (!strcmp (argv[i], "--help"))
00075        {
00076          /* Every program should use this for help! :) */
00077          no = 1;
00078          goto usage;
00079        }
00080       else if (!strcmp (argv[i], "-i"))
00081        {
00082          if (i == (argc - 2))
00083            {
00084              fprintf (stderr,
00085                      "Error: -i specified without y or n.\n");
00086              no = 1;
00087              goto usage;
00088            }
00089          if (!strcmp (argv[i + 1], "y"))
00090            {
00091              /* Set interlace. */
00092              gdImageInterlace (im, 1);
00093            }
00094          else if (!strcmp (argv[i + 1], "n"))
00095            {
00096              /* Clear interlace. */
00097              gdImageInterlace (im, 0);
00098            }
00099          else
00100            {
00101              fprintf (stderr,
00102                      "Error: -i specified without y or n.\n");
00103              no = 1;
00104              goto usage;
00105            }
00106          i++;
00107          no = 0;
00108          write = 1;
00109        }
00110       else if (!strcmp (argv[i], "-t"))
00111        {
00112          /* Set transparent index (or none). */
00113          int index;
00114          if (i == (argc - 2))
00115            {
00116              fprintf (stderr,
00117                      "Error: -t specified without a color table index.\n");
00118              no = 1;
00119              goto usage;
00120            }
00121          if (!strcmp (argv[i + 1], "none"))
00122            {
00123              /* -1 means not transparent. */
00124              gdImageColorTransparent (im, -1);
00125            }
00126          else
00127            {
00128              /* OK, get an integer and set the index. */
00129              index = atoi (argv[i + 1]);
00130              gdImageColorTransparent (im, index);
00131            }
00132          i++;
00133          write = 1;
00134          no = 0;
00135        }
00136       else if (!strcmp (argv[i], "-l"))
00137        {
00138          /* List the colors in the color table. */
00139          int j;
00140          if (!im->trueColor)
00141            {
00142              /* Tabs used below. */
00143              printf ("Index Red    Green  Blue Alpha\n");
00144              for (j = 0; (j < gdImageColorsTotal (im)); j++)
00145               {
00146                 /* Use access macros to learn colors. */
00147                 printf ("%d %d     %d     %d     %d\n",
00148                        j,
00149                        gdImageRed (im, j),
00150                        gdImageGreen (im, j),
00151                        gdImageBlue (im, j),
00152                        gdImageAlpha (im, j));
00153               }
00154            }
00155          else
00156            {
00157              printf ("Truecolor image, no palette entries to list.\n");
00158            }
00159          no = 0;
00160        }
00161       else if (!strcmp (argv[i], "-d"))
00162        {
00163          /* Output dimensions, etc. */
00164          int t;
00165          printf ("Width: %d Height: %d Colors: %d\n",
00166                 gdImageSX (im), gdImageSY (im),
00167                 gdImageColorsTotal (im));
00168          t = gdImageGetTransparent (im);
00169          if (t != (-1))
00170            {
00171                             printf ("First 100%% transparent index: %d\n", t);
00172            }
00173          else
00174            {
00175              /* -1 means the image is not transparent. */
00176                             printf ("First 100%% transparent index: none\n");
00177            }
00178          if (gdImageGetInterlaced (im))
00179            {
00180              printf ("Interlaced: yes\n");
00181            }
00182          else
00183            {
00184              printf ("Interlaced: no\n");
00185            }
00186          no = 0;
00187        }
00188               else if (!strcmp(argv[i], "-a"))
00189               {
00190                      int maxx, maxy, x, y, alpha, pix, nalpha = 0;
00191 
00192                      maxx = gdImageSX(im);
00193                      maxy = gdImageSY(im);
00194 
00195                      printf("alpha channel information:\n");
00196 
00197                      if (im->trueColor)   {
00198                             for (y = 0; y < maxy; y++)  {
00199                                    for (x = 0; x < maxx; x++)  {
00200                                           pix = gdImageGetPixel(im, x, y);
00201                                           alpha = gdTrueColorGetAlpha(pix);
00202 
00203                                           if (alpha > gdAlphaOpaque)  {
00204                                                  /* Use access macros to learn colors. */
00205                                                  printf ("%d   %d     %d     %d\n",
00206                                                                gdTrueColorGetRed(pix),
00207                                                                gdTrueColorGetGreen(pix),
00208                                                                gdTrueColorGetBlue(pix),
00209                                                                alpha);
00210                                                  nalpha++;
00211                                           }
00212 
00213                                    }
00214                             }
00215                      }
00216                      else
00217                             printf("NOT a true color image\n");
00218                      no = 0;
00219                      printf("%d alpha channels\n", nalpha);
00220 
00221               }
00222       else
00223        {
00224          fprintf (stderr, "Unknown argument: %s\n", argv[i]);
00225          break;
00226        }
00227     }
00228 usage:
00229   if (no)
00230     {
00231       /* If the command failed, output an explanation. */
00232       fprintf (stderr,
00233          "Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n"
00234 
00235               "  -i [y|n]   Turns on/off interlace\n"
00236               "  -l         Prints the table of color indexes\n"
00237               "  -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n"
00238               "  -d         Reports the dimensions and other characteristics of the image.\n"
00239                             "  -a         Prints all alpha channels that are not 100%% opaque.\n"
00240               "\n"
00241               "If you specify '-' as the input file, stdin/stdout will be used input/output.\n"
00242        );
00243     }
00244   if (write)
00245     {
00246       if (useStdinStdout)
00247        {
00248          out = stdout;
00249        }
00250       else
00251        {
00252          /* Open a temporary file. */
00253 
00254          /* "temp.tmp" is not good temporary filename. */
00255          snprintf (outFn, sizeof(outFn), "webpng.tmp%d", getpid ());
00256          out = fopen (outFn, "wb");
00257 
00258          if (!out)
00259            {
00260              fprintf (stderr,
00261                      "Unable to write to %s -- exiting\n", outFn);
00262              exit (1);
00263            }
00264        }
00265 
00266       /* Write the new PNG. */
00267       gdImagePng (im, out);
00268 
00269       if (!useStdinStdout)
00270        {
00271          fclose (out);
00272          /* Erase the old PNG. */
00273          unlink (argv[argc - 1]);
00274          /* Rename the new to the old. */
00275          if (rename (outFn, argv[argc - 1]) != 0)
00276            {
00277              perror ("rename");
00278              exit (1);
00279            }
00280        }
00281     }
00282   /* Delete the image from memory. */
00283   if (im)
00284     {
00285       gdImageDestroy (im);
00286     }
00287   /* All's well that ends well. */
00288   return 0;
00289 }