home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / common / header.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-24  |  8.3 KB  |  280 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <stdio.h>
  24.  
  25. #include <gtk/gtk.h>
  26.  
  27. #include <libgimp/gimp.h>
  28. #include <libgimp/gimpui.h>
  29.  
  30. #include "libgimp/stdplugins-intl.h"
  31.  
  32.  
  33. /* Declare some local functions.
  34.  */
  35. static void   query      (void);
  36. static void   run        (gchar   *name,
  37.                           gint     nparams,
  38.                           GimpParam  *param,
  39.                           gint    *nreturn_vals,
  40.                           GimpParam **return_vals);
  41. static gint   save_image (gchar   *filename,
  42.               gint32   image_ID,
  43.               gint32   drawable_ID);
  44.  
  45.  
  46. GimpPlugInInfo PLUG_IN_INFO =
  47. {
  48.   NULL,  /* init_proc  */
  49.   NULL,  /* quit_proc  */
  50.   query, /* query_proc */
  51.   run,   /* run_proc   */
  52. };
  53.  
  54.  
  55. MAIN ()
  56.  
  57. static void
  58. query (void)
  59. {
  60.   static GimpParamDef save_args[] =
  61.   {
  62.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  63.     { GIMP_PDB_IMAGE, "image", "Input image" },
  64.     { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
  65.     { GIMP_PDB_STRING, "filename", "The name of the file to save the image in" },
  66.     { GIMP_PDB_STRING, "raw_filename", "The name of the file to save the image in" }
  67.   };
  68.   static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
  69.  
  70.   gimp_install_procedure ("file_header_save",
  71.                           "saves files as C unsigned character array",
  72.                           "FIXME: write help",
  73.                           "Spencer Kimball & Peter Mattis",
  74.                           "Spencer Kimball & Peter Mattis",
  75.                           "1997",
  76.                           "<Save>/Header",
  77.               "INDEXED, RGB",
  78.                           GIMP_PLUGIN,
  79.                           nsave_args, 0,
  80.                           save_args, NULL);
  81.  
  82.   gimp_register_save_handler ("file_header_save",
  83.                   "h",
  84.                   "");
  85. }
  86.  
  87. static void
  88. run (gchar   *name,
  89.      gint     nparams,
  90.      GimpParam  *param,
  91.      gint    *nreturn_vals,
  92.      GimpParam **return_vals)
  93. {
  94.   static GimpParam values[2];
  95.   GimpRunModeType  run_mode;
  96.   GimpPDBStatusType   status = GIMP_PDB_SUCCESS;
  97.   gint32        image_ID;
  98.   gint32        drawable_ID;
  99.   GimpExportReturnType export = GIMP_EXPORT_CANCEL;
  100.  
  101.   run_mode = param[0].data.d_int32;
  102.  
  103.   *nreturn_vals = 1;
  104.   *return_vals  = values;
  105.   values[0].type          = GIMP_PDB_STATUS;
  106.   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  107.  
  108.   if (strcmp (name, "file_header_save") == 0)
  109.     {
  110.       image_ID    = param[1].data.d_int32;
  111.       drawable_ID = param[2].data.d_int32;
  112.  
  113.       /*  eventually export the image */ 
  114.       switch (run_mode)
  115.     {
  116.     case GIMP_RUN_INTERACTIVE:
  117.     case GIMP_RUN_WITH_LAST_VALS:
  118.       INIT_I18N_UI();
  119.       gimp_ui_init ("header", FALSE);
  120.       export = gimp_export_image (&image_ID, &drawable_ID, "Header", 
  121.                       (GIMP_EXPORT_CAN_HANDLE_RGB |
  122.                        GIMP_EXPORT_CAN_HANDLE_INDEXED));
  123.       if (export == GIMP_EXPORT_CANCEL)
  124.         {
  125.           values[0].data.d_status = GIMP_PDB_CANCEL;
  126.           return;
  127.         }
  128.       break;
  129.     default:
  130.       break;
  131.     }
  132.  
  133.       if (! save_image (param[3].data.d_string, image_ID, drawable_ID))
  134.     {
  135.       status = GIMP_PDB_EXECUTION_ERROR;
  136.     }
  137.  
  138.       if (export == GIMP_EXPORT_EXPORT)
  139.     gimp_image_delete (image_ID);
  140.     }
  141.   else
  142.     {
  143.       status = GIMP_PDB_CALLING_ERROR;
  144.     }
  145.  
  146.   values[0].data.d_status = status;
  147. }
  148.  
  149. static int
  150. save_image (gchar  *filename,
  151.         gint32  image_ID,
  152.         gint32  drawable_ID)
  153. {
  154.   GimpPixelRgn pixel_rgn;
  155.   GimpDrawable *drawable;
  156.   GimpImageType drawable_type;
  157.   FILE *fp;
  158.   gint x, y, b, c;
  159.   gchar *backslash = "\\\\";
  160.   gchar *quote = "\\\"";
  161.   gchar *newline = "\"\n\t\"";
  162.   gchar buf[4];
  163.   guchar *d = NULL;
  164.   guchar *data;
  165.   guchar *cmap;
  166.   gint colors;
  167.  
  168.   if ((fp = fopen (filename, "w")) == NULL)
  169.     return FALSE;
  170.  
  171.   drawable = gimp_drawable_get (drawable_ID);
  172.   drawable_type = gimp_drawable_type (drawable_ID);
  173.   gimp_pixel_rgn_init (&pixel_rgn, drawable,
  174.                0, 0, drawable->width, drawable->height, FALSE, FALSE);
  175.  
  176.   fprintf (fp, "/*  GIMP header image file format (%s): %s  */\n\n",
  177.        GIMP_RGB_IMAGE == drawable_type ? "RGB" : "INDEXED", filename);
  178.   fprintf (fp, "static unsigned int width = %d;\n", drawable->width);
  179.   fprintf (fp, "static unsigned int height = %d;\n\n", drawable->height);
  180.   fprintf (fp, "/*  Call this macro repeatedly.  After each use, the pixel data can be extracted  */\n\n");
  181.   switch (drawable_type)
  182.     {
  183.     case GIMP_RGB_IMAGE:
  184.       fprintf (fp, "#define HEADER_PIXEL(data,pixel) {\\\n  pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \\\n  pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \\\n  pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \\\n  data += 4;\n}\n");
  185.       fprintf (fp, "static char *header_data =\n\t\"");
  186.  
  187.       data = g_new (guchar, drawable->width * drawable->bpp);
  188.  
  189.       c = 0;
  190.       for (y = 0; y < drawable->height; y++)
  191.     {
  192.       gimp_pixel_rgn_get_row (&pixel_rgn, data, 0, y, drawable->width);
  193.       for (x = 0; x < drawable->width; x++)
  194.         {
  195.           d = data + x * drawable->bpp;
  196.           
  197.           buf[0] = ((d[0] >> 2) & 0x3F) + 33;
  198.           buf[1] = ((((d[0] & 0x3) << 4) | (d[1] >> 4)) & 0x3F) + 33;
  199.           buf[2] = ((((d[1] & 0xF) << 2) | (d[2] >> 6)) & 0x3F) + 33;
  200.           buf[3] = (d[2] & 0x3F) + 33;
  201.           
  202.           for (b = 0; b < 4; b++)
  203.         if (buf[b] == '"')
  204.           fwrite (quote, 1, 2, fp);
  205.         else if (buf[b] == '\\')
  206.           fwrite (backslash, 1, 2, fp);
  207.         else
  208.           fwrite (buf + b, 1, 1, fp);
  209.           
  210.           c++;
  211.           if (c >= 16)
  212.         {
  213.           fwrite (newline, 1, 4, fp);
  214.           c = 0;
  215.         }
  216.         }
  217.     }
  218.       fprintf (fp, "\";\n");
  219.       break;
  220.  
  221.     case GIMP_INDEXED_IMAGE:
  222.       fprintf (fp, "#define HEADER_PIXEL(data,pixel) {\\\n  pixel[0] = header_data_cmap[(unsigned char)data[0]][0]; \\\n  pixel[1] = header_data_cmap[(unsigned char)data[0]][1]; \\\n  pixel[2] = header_data_cmap[(unsigned char)data[0]][2]; \\\n  data ++; }\n\n");
  223.       /* save colormap */
  224.       cmap = gimp_image_get_cmap (image_ID, &colors);
  225.  
  226.       fprintf (fp, "static char header_data_cmap[256][3] = {");
  227.       fprintf(fp, "\n\t{%3d,%3d,%3d}", (int)cmap[0], (int)cmap[1], (int)cmap[2]);
  228.       for (c = 1; c < colors; c++)
  229.         fprintf(fp, ",\n\t{%3d,%3d,%3d}", (int)cmap[3*c], (int)cmap[3*c+1], (int)cmap[3*c+2]);
  230.       /* fill the rest */
  231.       for ( ; c < 256; c++)
  232.         fprintf(fp, ",\n\t{255,255,255}");
  233.       /* close bracket */
  234.       fprintf(fp, "\n\t};\n");
  235.       g_free(cmap);
  236.  
  237.       /* save image */
  238.       fprintf (fp, "static char header_data[] = {\n\t");
  239.  
  240.       data = g_new (guchar, drawable->width * drawable->bpp);
  241.  
  242.       c = 0;
  243.       for (y = 0; y < drawable->height; y++)
  244.         {
  245.           gimp_pixel_rgn_get_row (&pixel_rgn, data, 0, y, drawable->width);
  246.           for (x = 0; x < drawable->width-1; x++)
  247.         {
  248.           d = data + x * drawable->bpp;
  249.  
  250.               fprintf(fp, "%d,", (int)d[0]);
  251.  
  252.           c++;
  253.           if (c >= 16)
  254.             {
  255.               fprintf (fp, "\n\t");
  256.               c = 0;
  257.             }
  258.         }
  259.  
  260.           if (y != drawable->height - 1)
  261.             fprintf(fp, "%d,\n\t", (int)d[1]);
  262.           else
  263.             fprintf(fp, "%d\n\t", (int)d[1]);
  264.           c = 0; /* reset line counter */
  265.         }
  266.       fprintf (fp, "};\n");
  267.       break;
  268.     default:
  269.       g_warning ("unhandled drawable type (%d)", drawable_type);
  270.       return FALSE;
  271.     } /* switch (drawable_type) */
  272.  
  273.   fclose (fp);
  274.  
  275.   g_free (data);
  276.   gimp_drawable_detach (drawable);
  277.  
  278.   return TRUE;
  279. }
  280.