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 / xwd.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-13  |  57.9 KB  |  2,101 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  * XWD reading and writing code Copyright (C) 1996 Peter Kirchgessner
  4.  * (email: peter@kirchgessner.net, WWW: http://www.kirchgessner.net)
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19.  *
  20.  */
  21.  
  22. /*
  23.  * XWD-input/output was written by Peter Kirchgessner (pkirchg@aol.com).
  24.  * Examples from mainly used UNIX-systems have been used for testing.
  25.  * If a file does not work, please return a small (!!) compressed example.
  26.  * Currently the following formats are supported:
  27.  *    pixmap_format | pixmap_depth | bits_per_pixel
  28.  *    ---------------------------------------------
  29.  *          0       |        1     |       1
  30.  *          1       |    1,...,24  |       1
  31.  *          2       |        1     |       1
  32.  *          2       |    1,...,8   |       8
  33.  *          2       |    1,...,16  |      16
  34.  *          2       |    1,...,24  |      24
  35.  *          2       |    1,...,24  |      32
  36.  */
  37. /* Event history:
  38.  * PK = Peter Kirchgessner, ME = Mattias Engdegσrd
  39.  * V 1.00, PK, xx-Aug-96: First try
  40.  * V 1.01, PK, 03-Sep-96: Check for bitmap_bit_order
  41.  * V 1.90, PK, 17-Mar-97: Upgrade to work with GIMP V0.99
  42.  *                        Use visual class 3 to write indexed image
  43.  *                        Set gimp b/w-colormap if no xwdcolormap present
  44.  * V 1.91, PK, 05-Apr-97: Return all arguments, even in case of an error
  45.  * V 1.92, PK, 12-Oct-97: No progress bars for non-interactive mode
  46.  * V 1.93, PK, 11-Apr-98: Fix problem with overwriting memory
  47.  * V 1.94, ME, 27-Feb-00: Remove superfluous little-endian support (format is
  48.                           specified as big-endian). Trim magic header
  49.  */
  50. static char ident[] = "@(#) GIMP XWD file-plugin v1.94  27-Feb-2000";
  51.  
  52. #include "config.h"
  53.  
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include <string.h>
  57. #ifdef HAVE_UNISTD_H
  58. #include <unistd.h>
  59. #endif
  60.  
  61. #include <gtk/gtk.h>
  62.  
  63. #include <libgimp/gimp.h>
  64. #include <libgimp/gimpui.h>
  65.  
  66. #include "libgimp/stdplugins-intl.h"
  67.  
  68.  
  69. typedef gulong  L_CARD32;
  70. typedef gushort L_CARD16;
  71. typedef guchar  L_CARD8;
  72.  
  73. typedef struct
  74. {
  75.   L_CARD32 l_header_size;    /* Header size */
  76.  
  77.   L_CARD32 l_file_version;   /* File version (7) */
  78.   L_CARD32 l_pixmap_format;  /* Image type */
  79.   L_CARD32 l_pixmap_depth;   /* Number of planes */
  80.   L_CARD32 l_pixmap_width;   /* Image width */
  81.   L_CARD32 l_pixmap_height;  /* Image height */
  82.   L_CARD32 l_xoffset;        /* x-offset (0 ?) */
  83.   L_CARD32 l_byte_order;     /* Byte ordering */
  84.  
  85.   L_CARD32 l_bitmap_unit;
  86.   L_CARD32 l_bitmap_bit_order; /* Bit order */
  87.   L_CARD32 l_bitmap_pad;
  88.   L_CARD32 l_bits_per_pixel; /* Number of bits per pixel */
  89.  
  90.   L_CARD32 l_bytes_per_line; /* Number of bytes per scanline */
  91.   L_CARD32 l_visual_class;   /* Visual class */
  92.   L_CARD32 l_red_mask;       /* Red mask */
  93.   L_CARD32 l_green_mask;     /* Green mask */
  94.   L_CARD32 l_blue_mask;      /* Blue mask */
  95.   L_CARD32 l_bits_per_rgb;   /* Number of bits per RGB-part */
  96.   L_CARD32 l_colormap_entries; /* Number of colours in colour table (?) */
  97.   L_CARD32 l_ncolors;        /* Number of xwdcolor structures */
  98.   L_CARD32 l_window_width;   /* Window width */
  99.   L_CARD32 l_window_height;  /* Window height */
  100.   L_CARD32 l_window_x;       /* Window position x */
  101.   L_CARD32 l_window_y;       /* Window position y */
  102.   L_CARD32 l_window_bdrwidth;/* Window border width */
  103. } L_XWDFILEHEADER;
  104.  
  105. typedef struct
  106. {
  107.   L_CARD32 l_pixel;          /* Colour index */
  108.   L_CARD16 l_red, l_green, l_blue;  /* RGB-values */
  109.   L_CARD8  l_flags, l_pad;
  110. } L_XWDCOLOR;
  111.  
  112.  
  113. /* Some structures for mapping up to 32bit-pixel */
  114. /* values which are kept in the XWD-Colormap */
  115.  
  116. #define MAPPERBITS 12
  117. #define MAPPERMASK ((1 << MAPPERBITS)-1)
  118.  
  119. typedef struct
  120. {
  121.   L_CARD32 pixel_val;
  122.   guchar   red;
  123.   guchar   green;
  124.   guchar   blue;
  125. } PMAP;
  126.  
  127. typedef struct
  128. {
  129.   gint   npixel; /* Number of pixel values in map */
  130.   guchar pixel_in_map[1 << MAPPERBITS];
  131.   PMAP   pmap[256];
  132. } PIXEL_MAP;
  133.  
  134. #define XWDHDR_PAD   0  /* Total number of padding bytes for XWD header */
  135. #define XWDCOL_PAD   0  /* Total number of padding bytes for each XWD color */
  136.  
  137. /* Declare some local functions.
  138.  */
  139. static void   query               (void);
  140. static void   run                 (gchar   *name,
  141.                    gint     nparams,
  142.                    GimpParam  *param,
  143.                    gint    *nreturn_vals,
  144.                    GimpParam **return_vals);
  145.  
  146. static gint32 load_image          (gchar  *filename);
  147. static gint   save_image          (gchar  *filename,
  148.                    gint32  image_ID,
  149.                    gint32  drawable_ID);
  150. static gint32 create_new_image    (char *filename, guint width, guint height,
  151.                    GimpImageBaseType type, gint32 *layer_ID, 
  152.                    GimpDrawable **drawable, GimpPixelRgn *pixel_rgn);
  153.  
  154. static int    set_pixelmap        (int, L_XWDCOLOR *,PIXEL_MAP *);
  155. static int    get_pixelmap        (L_CARD32, PIXEL_MAP *,unsigned char *,
  156.                    unsigned char *, unsigned char *);
  157. static void   set_bw_color_table  (gint32);
  158. static void   set_color_table     (gint32, L_XWDFILEHEADER *, L_XWDCOLOR *);
  159.  
  160. static gint32 load_xwd_f2_d1_b1   (char *, FILE *, L_XWDFILEHEADER *,
  161.                    L_XWDCOLOR *);
  162. static gint32 load_xwd_f2_d8_b8   (char *, FILE *, L_XWDFILEHEADER *,
  163.                    L_XWDCOLOR *);
  164. static gint32 load_xwd_f2_d16_b16 (char *, FILE *, L_XWDFILEHEADER *,
  165.                                    L_XWDCOLOR *);
  166. static gint32 load_xwd_f2_d24_b32 (char *, FILE *, L_XWDFILEHEADER *,
  167.                                    L_XWDCOLOR *);
  168. static gint32 load_xwd_f1_d24_b1  (char *, FILE *, L_XWDFILEHEADER *,
  169.                                    L_XWDCOLOR *);
  170.  
  171. static L_CARD32 read_card32  (FILE *, int *);
  172. static L_CARD16 read_card16  (FILE *, int *);
  173. static L_CARD8  read_card8   (FILE *, int *);
  174.  
  175. static void write_card32     (FILE *, L_CARD32);
  176. static void write_card16     (FILE *, L_CARD32);
  177. static void write_card8      (FILE *, L_CARD32);
  178.  
  179. static void read_xwd_header  (FILE *, L_XWDFILEHEADER *);
  180. static void write_xwd_header (FILE *, L_XWDFILEHEADER *);
  181. static void read_xwd_cols    (FILE *, L_XWDFILEHEADER *, L_XWDCOLOR *);
  182. static void write_xwd_cols   (FILE *, L_XWDFILEHEADER *, L_XWDCOLOR *);
  183.  
  184. static gint save_index       (FILE *, gint32, gint32, int);
  185. static gint save_rgb         (FILE *, gint32, gint32);
  186.  
  187.  
  188. GimpPlugInInfo PLUG_IN_INFO =
  189. {
  190.   NULL,  /* init_proc  */
  191.   NULL,  /* quit_proc  */
  192.   query, /* query_proc */
  193.   run,   /* run_proc   */
  194. };
  195.  
  196.  
  197. /* The run mode */
  198. static GimpRunModeType l_run_mode;
  199.  
  200.  
  201. MAIN ()
  202.  
  203.  
  204. static void
  205. query (void)
  206.  
  207. {
  208.   static GimpParamDef load_args[] =
  209.   {
  210.     { GIMP_PDB_INT32,  "run_mode",     "Interactive, non-interactive" },
  211.     { GIMP_PDB_STRING, "filename",     "The name of the file to load" },
  212.     { GIMP_PDB_STRING, "raw_filename", "The name of the file to load" }
  213.   };
  214.   static gint nload_args = sizeof (load_args) / sizeof (load_args[0]);
  215.  
  216.   static GimpParamDef load_return_vals[] =
  217.   {
  218.     { GIMP_PDB_IMAGE,  "image",        "Output image" }
  219.   };
  220.   static gint nload_return_vals = (sizeof (load_return_vals) /
  221.                    sizeof (load_return_vals[0]));
  222.  
  223.   static GimpParamDef save_args[] =
  224.   {
  225.     { GIMP_PDB_INT32,    "run_mode",     "Interactive, non-interactive" },
  226.     { GIMP_PDB_IMAGE,    "image",        "Input image" },
  227.     { GIMP_PDB_DRAWABLE, "drawable",     "Drawable to save" },
  228.     { GIMP_PDB_STRING,   "filename",     "The name of the file to save the image in" },
  229.     { GIMP_PDB_STRING,   "raw_filename", "The name of the file to save the image in" }
  230.   };
  231.   static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
  232.  
  233.   gimp_install_procedure ("file_xwd_load",
  234.                           "load file of the XWD file format",
  235.                           "load file of the XWD file format",
  236.                           "Peter Kirchgessner",
  237.                           "Peter Kirchgessner",
  238.                           "1996",
  239.                           "<Load>/XWD",
  240.                           NULL,
  241.                           GIMP_PLUGIN,
  242.                           nload_args, nload_return_vals,
  243.                           load_args, load_return_vals);
  244.  
  245.   gimp_install_procedure ("file_xwd_save",
  246.                           "saves files in the XWD file format",
  247.                           "XWD saving handles all image types except \
  248. those with alpha channels.",
  249.                           "Peter Kirchgessner",
  250.                           "Peter Kirchgessner",
  251.                           "1996",
  252.                           "<Save>/XWD",
  253.                           "RGB, GRAY, INDEXED",
  254.                           GIMP_PLUGIN,
  255.                           nsave_args, 0,
  256.                           save_args, NULL);
  257.  
  258.   gimp_register_magic_load_handler ("file_xwd_load",
  259.                     "xwd",
  260.                     "",
  261.                                     "4,long,0x00000007");
  262.   gimp_register_save_handler ("file_xwd_save",
  263.                   "xwd",
  264.                   "");
  265. }
  266.  
  267.  
  268. static void
  269. run (gchar   *name,
  270.      gint     nparams,
  271.      GimpParam  *param,
  272.      gint    *nreturn_vals,
  273.      GimpParam **return_vals)
  274. {
  275.   static GimpParam values[2];
  276.   GimpRunModeType  run_mode;
  277.   GimpPDBStatusType   status = GIMP_PDB_SUCCESS;
  278.   gint32        image_ID;
  279.   gint32        drawable_ID;
  280.   GimpExportReturnType export = GIMP_EXPORT_CANCEL;
  281.  
  282.   l_run_mode = run_mode = param[0].data.d_int32;
  283.  
  284.   *nreturn_vals = 1;
  285.   *return_vals  = values;
  286.   values[0].type          = GIMP_PDB_STATUS;
  287.   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  288.  
  289.   if (strcmp (name, "file_xwd_load") == 0)
  290.     {
  291.       INIT_I18N();
  292.  
  293.       image_ID = load_image (param[1].data.d_string);
  294.  
  295.       if (image_ID != -1)
  296.     {
  297.       *nreturn_vals = 2;
  298.       values[1].type         = GIMP_PDB_IMAGE;
  299.       values[1].data.d_image = image_ID;
  300.     }
  301.       else
  302.     {
  303.       status = GIMP_PDB_EXECUTION_ERROR;
  304.     }
  305.     }
  306.   else if (strcmp (name, "file_xwd_save") == 0)
  307.     {
  308.       INIT_I18N();
  309.  
  310.       image_ID = param[1].data.d_int32;
  311.       drawable_ID = param[2].data.d_int32;
  312.  
  313.       /*  eventually export the image */ 
  314.       switch (run_mode)
  315.     {
  316.     case GIMP_RUN_INTERACTIVE:
  317.     case GIMP_RUN_WITH_LAST_VALS:
  318.       gimp_ui_init ("xwd", FALSE);
  319.       export = gimp_export_image (&image_ID, &drawable_ID, "XWD", 
  320.                       (GIMP_EXPORT_CAN_HANDLE_RGB |
  321.                        GIMP_EXPORT_CAN_HANDLE_GRAY |
  322.                        GIMP_EXPORT_CAN_HANDLE_INDEXED));
  323.       if (export == GIMP_EXPORT_CANCEL)
  324.         {
  325.           values[0].data.d_status = GIMP_PDB_CANCEL;
  326.           return;
  327.       }
  328.       break;
  329.     default:
  330.       break;
  331.     }
  332.  
  333.       switch (run_mode)
  334.         {
  335.         case GIMP_RUN_INTERACTIVE:
  336.         case GIMP_RUN_WITH_LAST_VALS:
  337.           /* No additional data to retrieve */
  338.           break;
  339.  
  340.         case GIMP_RUN_NONINTERACTIVE:
  341.           /*  Make sure all the arguments are there!  */
  342.           if (nparams != 5)
  343.             status = GIMP_PDB_CALLING_ERROR;
  344.           break;
  345.  
  346.         default:
  347.           break;
  348.         }
  349.  
  350.       if (status == GIMP_PDB_SUCCESS)
  351.     {
  352.       if (! save_image (param[3].data.d_string, image_ID, drawable_ID))
  353.         {
  354.           status = GIMP_PDB_EXECUTION_ERROR;
  355.         }
  356.     }
  357.       if (export == GIMP_EXPORT_EXPORT)
  358.     gimp_image_delete (image_ID);
  359.     }
  360.   else
  361.     {
  362.       status = GIMP_PDB_CANCEL;
  363.     }
  364.  
  365.   values[0].data.d_status = status;
  366. }
  367.  
  368. static gint32
  369. load_image (gchar *filename)
  370. {
  371.   FILE *ifp;
  372.   int depth, bpp;
  373.   gchar *temp;
  374.   gint32 image_ID;
  375.   L_XWDFILEHEADER xwdhdr;
  376.   L_XWDCOLOR *xwdcolmap = NULL;
  377.  
  378.   ifp = fopen (filename, "rb");
  379.   if (!ifp)
  380.     {
  381.       g_message (_("can't open file for reading"));
  382.       return (-1);
  383.     }
  384.  
  385.   read_xwd_header (ifp, &xwdhdr);
  386.   if (xwdhdr.l_file_version != 7)
  387.     {
  388.       g_message(_("can't open file as XWD file"));
  389.       fclose (ifp);
  390.       return (-1);
  391.     }
  392.  
  393.   /* Position to start of XWDColor structures */
  394.   fseek (ifp, (long)xwdhdr.l_header_size, SEEK_SET);
  395.  
  396.   if (xwdhdr.l_colormap_entries > 0)
  397.     {
  398.       xwdcolmap = (L_XWDCOLOR *)g_malloc (sizeof (L_XWDCOLOR)
  399.                                         * xwdhdr.l_colormap_entries);
  400.       if (xwdcolmap == NULL)
  401.     {
  402.       g_message (_("can't get memory for colormap"));
  403.       fclose (ifp);
  404.       return (-1);
  405.     }
  406.  
  407.     read_xwd_cols (ifp, &xwdhdr, xwdcolmap);
  408. #ifdef XWD_COL_DEBUG
  409.     {
  410.       int j;
  411.       printf ("File %s\n",filename);
  412.       for (j=0; j < xwdhdr.l_colormap_entries; j++)
  413.     printf ("Entry 0x%08lx: 0x%04lx,  0x%04lx, 0x%04lx, %d\n",
  414.         (long)xwdcolmap[j].l_pixel,(long)xwdcolmap[j].l_red,
  415.         (long)xwdcolmap[j].l_green,(long)xwdcolmap[j].l_blue,
  416.         (int)xwdcolmap[j].l_flags);
  417.     }
  418. #endif
  419.     if (xwdhdr.l_file_version != 7)
  420.       {
  421.     g_message (_("can't read color entries"));
  422.     g_free (xwdcolmap);
  423.     fclose (ifp);
  424.     return (-1);
  425.       }
  426.     }
  427.  
  428.   if (l_run_mode != GIMP_RUN_NONINTERACTIVE)
  429.     {
  430.       temp = g_strdup_printf (_("Loading %s:"), filename);
  431.       gimp_progress_init (temp);
  432.       g_free (temp);
  433.     }
  434.  
  435.   depth = xwdhdr.l_pixmap_depth;
  436.   bpp = xwdhdr.l_bits_per_pixel;
  437.  
  438.   image_ID = -1;
  439.   switch (xwdhdr.l_pixmap_format)
  440.   {
  441.     case 0:    /* Single plane bitmap */
  442.       if ((depth == 1) && (bpp == 1))
  443.       { /* Can be performed by format 2 loader */
  444.         image_ID = load_xwd_f2_d1_b1 (filename, ifp, &xwdhdr, xwdcolmap);
  445.       }
  446.       break;
  447.  
  448.     case 1:    /* Single plane pixmap */
  449.       if ((depth <= 24) && (bpp == 1))
  450.       {
  451.         image_ID = load_xwd_f1_d24_b1 (filename, ifp, &xwdhdr, xwdcolmap);
  452.       }
  453.       break;
  454.  
  455.    case 2:    /* Multiplane pixmaps */
  456.      if ((depth == 1) && (bpp == 1))
  457.      {
  458.        image_ID = load_xwd_f2_d1_b1 (filename, ifp, &xwdhdr, xwdcolmap);
  459.      }
  460.      else if ((depth <= 8) && (bpp == 8))
  461.      {
  462.        image_ID = load_xwd_f2_d8_b8 (filename, ifp, &xwdhdr, xwdcolmap);
  463.      }
  464.      else if ((depth <= 16) && (bpp == 16))
  465.      {
  466.        image_ID = load_xwd_f2_d16_b16 (filename, ifp, &xwdhdr, xwdcolmap);
  467.      }
  468.      else if ((depth <= 24) && ((bpp == 24) || (bpp == 32)))
  469.      {
  470.        image_ID = load_xwd_f2_d24_b32 (filename, ifp, &xwdhdr, xwdcolmap);
  471.      }
  472.      break;
  473.   }
  474.  
  475.   fclose (ifp);
  476.  
  477.   if (xwdcolmap != NULL) g_free ((char *)xwdcolmap);
  478.  
  479.   if (image_ID == -1)
  480.   {
  481.     temp = g_strdup_printf (_("load_image (xwd): XWD-file %s has format %d, depth %d\n\
  482. and bits per pixel %d.\nCurrently this is not supported.\n"),
  483.                 filename, (int)xwdhdr.l_pixmap_format, depth, bpp);
  484.     g_message (temp);
  485.     g_free (temp);
  486.     return (-1);
  487.   }
  488.  
  489.   return (image_ID);
  490. }
  491.  
  492. static gint
  493. save_image (char   *filename,
  494.             gint32  image_ID,
  495.             gint32  drawable_ID)
  496.  
  497. {
  498.   FILE* ofp;
  499.   GimpImageType drawable_type;
  500.   gint retval;
  501.   char *temp;
  502.  
  503.   drawable_type = gimp_drawable_type (drawable_ID);
  504.  
  505.   /*  Make sure we're not saving an image with an alpha channel  */
  506.   if (gimp_drawable_has_alpha (drawable_ID))
  507.     {
  508.       g_message (_("XWD save cannot handle images with alpha channels"));
  509.       return FALSE;
  510.     }
  511.  
  512.   switch (drawable_type)
  513.     {
  514.     case GIMP_INDEXED_IMAGE:
  515.     case GIMP_GRAY_IMAGE:
  516.     case GIMP_RGB_IMAGE:
  517.       break;
  518.     default:
  519.       g_message (_("cannot operate on unknown image types"));
  520.       return (FALSE);
  521.       break;
  522.     }
  523.  
  524.   /* Open the output file. */
  525.   ofp = fopen (filename, "wb");
  526.   if (!ofp)
  527.     {
  528.       g_message (_("can't open file for writing"));
  529.       return (FALSE);
  530.     }
  531.  
  532.   if (l_run_mode != GIMP_RUN_NONINTERACTIVE)
  533.     {
  534.       temp = g_strdup_printf (_("Saving %s:"), filename);
  535.       gimp_progress_init (temp);
  536.       g_free (temp);
  537.     }
  538.  
  539.   if (drawable_type == GIMP_INDEXED_IMAGE)
  540.     retval = save_index (ofp, image_ID, drawable_ID, 0);
  541.   else if (drawable_type == GIMP_GRAY_IMAGE)
  542.     retval = save_index (ofp, image_ID, drawable_ID, 1);
  543.   else if (drawable_type == GIMP_RGB_IMAGE)
  544.     retval = save_rgb (ofp, image_ID, drawable_ID);
  545.   else
  546.     retval = FALSE;
  547.  
  548.   fclose (ofp);
  549.  
  550.   return (retval);
  551. }
  552.  
  553.  
  554. static L_CARD32 
  555. read_card32 (FILE *ifp,
  556.          int  *err)
  557.  
  558. {
  559.   L_CARD32 c;
  560.  
  561.   c = (((L_CARD32)(getc (ifp))) << 24);
  562.   c |= (((L_CARD32)(getc (ifp))) << 16);
  563.   c |= (((L_CARD32)(getc (ifp))) << 8);
  564.   c |= ((L_CARD32)(*err = getc (ifp)));
  565.   
  566.   *err = (*err < 0);
  567.   return (c);
  568. }
  569.  
  570.  
  571. static L_CARD16 
  572. read_card16 (FILE *ifp,
  573.          int  *err)
  574.  
  575. {
  576.   L_CARD16 c;
  577.   
  578.   c = (((L_CARD16)(getc (ifp))) << 8);
  579.   c |= ((L_CARD16)(*err = getc (ifp)));
  580.   
  581.   *err = (*err < 0);
  582.   return (c);
  583. }
  584.  
  585.  
  586. static L_CARD8 
  587. read_card8 (FILE *ifp,
  588.         int  *err)
  589. {
  590.   L_CARD8 c;
  591.   
  592.   c = ((L_CARD8)(*err = getc (ifp)));
  593.   
  594.   *err = (*err < 0);
  595.   return (c);
  596. }
  597.  
  598. static void 
  599. write_card32 (FILE     *ofp,
  600.           L_CARD32  c)
  601. {
  602.   putc ((int)((c >> 24) & 0xff), ofp);
  603.   putc ((int)((c >> 16) & 0xff), ofp);
  604.   putc ((int)((c >> 8) & 0xff), ofp);
  605.   putc ((int)((c) & 0xff), ofp);
  606. }
  607.  
  608.  
  609. static void 
  610. write_card16 (FILE     *ofp,
  611.           L_CARD32  c)
  612. {
  613.   putc ((int)((c >> 8) & 0xff), ofp);
  614.   putc ((int)((c) & 0xff), ofp);
  615. }
  616.  
  617.  
  618. static void 
  619. write_card8 (FILE     *ofp,
  620.          L_CARD32  c)
  621. {
  622.   putc ((int)((c) & 0xff), ofp);
  623. }
  624.  
  625.  
  626. static void
  627. read_xwd_header (FILE            *ifp,
  628.                  L_XWDFILEHEADER *xwdhdr)
  629. {
  630.   int j, err;
  631.   L_CARD32 *cp;
  632.   
  633.   cp = (L_CARD32 *)xwdhdr;
  634.   
  635.   /* Read in all 32-bit values of the header and check for byte order */
  636.   for (j = 0; j < sizeof (L_XWDFILEHEADER)/sizeof(xwdhdr->l_file_version); j++)
  637.     {
  638.       *(cp++) = read_card32 (ifp, &err);
  639.       if (err) break;
  640.     }
  641.   
  642.   if (err) xwdhdr->l_file_version = 0;  /* Not a valid XWD-file */
  643. }
  644.  
  645.  
  646. /* Write out an XWD-fileheader. The header size is calculated here */
  647. static void
  648. write_xwd_header (FILE            *ofp,
  649.                   L_XWDFILEHEADER *xwdhdr)
  650.  
  651. {
  652.   int j, hdrpad, hdr_entries;
  653.   L_CARD32 *cp;
  654.   
  655.   hdrpad = XWDHDR_PAD;
  656.   hdr_entries = sizeof (L_XWDFILEHEADER)/sizeof(xwdhdr->l_file_version);
  657.   xwdhdr->l_header_size = hdr_entries * 4 + hdrpad;
  658.   
  659.   cp = (L_CARD32 *)xwdhdr;
  660.  
  661.   /* Write out all 32-bit values of the header and check for byte order */
  662.   for (j = 0; j < sizeof (L_XWDFILEHEADER)/sizeof(xwdhdr->l_file_version); j++)
  663.     {
  664.       write_card32 (ofp, *(cp++));
  665.     }
  666.   
  667.   /* Add padding bytes after XWD header */
  668.   for (j = 0; j < hdrpad; j++)
  669.     write_card8 (ofp, (L_CARD32)0);
  670. }
  671.  
  672.  
  673. static void
  674. read_xwd_cols (FILE            *ifp,
  675.                L_XWDFILEHEADER *xwdhdr,
  676.                L_XWDCOLOR      *colormap)
  677. {
  678.   int j, err = 0;
  679.   int flag_is_bad, index_is_bad;
  680.   int indexed = (xwdhdr->l_pixmap_depth <= 8);
  681.   long colmappos = ftell (ifp);
  682.   
  683.   /* Read in XWD-Color structures (the usual case) */
  684.   flag_is_bad = index_is_bad = 0;
  685.   for (j = 0; j < xwdhdr->l_ncolors; j++)
  686.     {
  687.       colormap[j].l_pixel = read_card32 (ifp, &err);
  688.  
  689.       colormap[j].l_red   = read_card16 (ifp, &err);
  690.       colormap[j].l_green = read_card16 (ifp, &err);
  691.       colormap[j].l_blue  = read_card16 (ifp, &err);
  692.       
  693.       colormap[j].l_flags = read_card8 (ifp, &err);
  694.       colormap[j].l_pad   = read_card8 (ifp, &err);
  695.       
  696.       if (indexed && (colormap[j].l_pixel > 255))
  697.     index_is_bad++;
  698.       
  699.       if (err) break;
  700.     }
  701.   
  702.   if (err)        /* Not a valid XWD-file ? */
  703.     xwdhdr->l_file_version = 0;
  704.   if (err || ((flag_is_bad == 0) && (index_is_bad == 0)))
  705.     return;
  706.   
  707.   /* Read in XWD-Color structures (with 4 bytes inserted infront of RGB) */
  708.   fseek (ifp, colmappos, SEEK_SET);
  709.   flag_is_bad = index_is_bad = 0;
  710.   for (j = 0; j < xwdhdr->l_ncolors; j++)
  711.     {
  712.       colormap[j].l_pixel = read_card32 (ifp, &err);
  713.       
  714.       read_card32 (ifp, &err);  /* Empty bytes on Alpha OSF */
  715.       
  716.       colormap[j].l_red   = read_card16 (ifp, &err);
  717.       colormap[j].l_green = read_card16 (ifp, &err);
  718.       colormap[j].l_blue  = read_card16 (ifp, &err);
  719.       
  720.       colormap[j].l_flags = read_card8 (ifp, &err);
  721.       colormap[j].l_pad   = read_card8 (ifp, &err);
  722.       
  723.       if (indexed && (colormap[j].l_pixel > 255))
  724.     index_is_bad++;
  725.       
  726.       if (err) break;
  727.     }
  728.   
  729.   if (err)        /* Not a valid XWD-file ? */
  730.     xwdhdr->l_file_version = 0;
  731.   if (err || ((flag_is_bad == 0) && (index_is_bad == 0)))
  732.     return;
  733.   
  734.   /* Read in XWD-Color structures (with 2 bytes inserted infront of RGB) */
  735.   fseek (ifp, colmappos, SEEK_SET);
  736.   flag_is_bad = index_is_bad = 0;
  737.   for (j = 0; j < xwdhdr->l_ncolors; j++)
  738.     {
  739.       colormap[j].l_pixel = read_card32 (ifp, &err);
  740.       
  741.       read_card16 (ifp, &err);  /* Empty bytes (from where ?) */
  742.       
  743.       colormap[j].l_red   = read_card16 (ifp, &err);
  744.       colormap[j].l_green = read_card16 (ifp, &err);
  745.       colormap[j].l_blue  = read_card16 (ifp, &err);
  746.       
  747.       colormap[j].l_flags = read_card8 (ifp, &err);
  748.       colormap[j].l_pad   = read_card8 (ifp, &err);
  749.       
  750.       /* if ((colormap[j].l_flags == 0) || (colormap[j].l_flags > 7))
  751.      flag_is_bad++; */
  752.       
  753.       if (indexed && (colormap[j].l_pixel > 255))
  754.     index_is_bad++;
  755.       
  756.       if (err) break;
  757.     }
  758.   
  759.   if (err)        /* Not a valid XWD-file ? */
  760.     xwdhdr->l_file_version = 0;
  761.   if (err || ((flag_is_bad == 0) && (index_is_bad == 0)))
  762.     return;
  763.   
  764.   /* Read in XWD-Color structures (every value is 8 bytes from a CRAY) */
  765.   fseek (ifp, colmappos, SEEK_SET);
  766.   flag_is_bad = index_is_bad = 0;
  767.   for (j = 0; j < xwdhdr->l_ncolors; j++)
  768.     {
  769.       read_card32 (ifp, &err);
  770.       colormap[j].l_pixel = read_card32 (ifp, &err);
  771.       
  772.       read_card32 (ifp, &err);
  773.       colormap[j].l_red   = read_card32 (ifp, &err);
  774.       read_card32 (ifp, &err);
  775.       colormap[j].l_green = read_card32 (ifp, &err);
  776.       read_card32 (ifp, &err);
  777.       colormap[j].l_blue  = read_card32 (ifp, &err);
  778.       
  779.       /* The flag byte is kept in the first byte */
  780.       colormap[j].l_flags = read_card8 (ifp, &err);
  781.       colormap[j].l_pad   = read_card8 (ifp, &err);
  782.       read_card16 (ifp, &err);
  783.       read_card32 (ifp, &err);
  784.       
  785.        if (indexed && (colormap[j].l_pixel > 255))
  786.     index_is_bad++;
  787.       
  788.        if (err) break;
  789.     }
  790.   
  791.   if (flag_is_bad || index_is_bad)
  792.     {
  793.       printf ("xwd: Warning. Error in XWD-color-structure (");
  794.       
  795.       if (flag_is_bad) printf ("flag");
  796.       if (index_is_bad) printf ("index");
  797.       
  798.       printf (")\n");
  799.     }
  800.   if (err) xwdhdr->l_file_version = 0;  /* Not a valid XWD-file */
  801. }
  802.  
  803.  
  804. static void
  805. write_xwd_cols (FILE            *ofp,
  806.                 L_XWDFILEHEADER *xwdhdr,
  807.                 L_XWDCOLOR      *colormap)
  808.  
  809. {
  810.   int j;
  811.   
  812.   for (j = 0; j < xwdhdr->l_colormap_entries; j++)
  813.     {
  814. #ifdef CRAY
  815.       write_card32 (ofp, (L_CARD32)0);
  816.       write_card32 (ofp, colormap[j].l_pixel);
  817.       write_card32 (ofp, (L_CARD32)0);
  818.       write_card32 (ofp, (L_CARD32)colormap[j].l_red);
  819.       write_card32 (ofp, (L_CARD32)0);
  820.       write_card32 (ofp, (L_CARD32)colormap[j].l_green);
  821.       write_card32 (ofp, (L_CARD32)0);
  822.       write_card32 (ofp, (L_CARD32)colormap[j].l_blue);
  823.       write_card8 (ofp, (L_CARD32)colormap[j].l_flags);
  824.       write_card8 (ofp, (L_CARD32)colormap[j].l_pad);
  825.       write_card16 (ofp, (L_CARD32)0);
  826.       write_card32 (ofp, (L_CARD32)0);
  827. #else
  828. #ifdef __alpha
  829.       write_card32 (ofp, colormap[j].l_pixel);
  830.       write_card32 (ofp, (L_CARD32)0);
  831.       write_card16 (ofp, (L_CARD32)colormap[j].l_red);
  832.       write_card16 (ofp, (L_CARD32)colormap[j].l_green);
  833.       write_card16 (ofp, (L_CARD32)colormap[j].l_blue);
  834.       write_card8 (ofp, (L_CARD32)colormap[j].l_flags);
  835.       write_card8 (ofp, (L_CARD32)colormap[j].l_pad);
  836. #else
  837.       write_card32 (ofp, colormap[j].l_pixel);
  838.       write_card16 (ofp, (L_CARD32)colormap[j].l_red);
  839.       write_card16 (ofp, (L_CARD32)colormap[j].l_green);
  840.       write_card16 (ofp, (L_CARD32)colormap[j].l_blue);
  841.       write_card8 (ofp, (L_CARD32)colormap[j].l_flags);
  842.       write_card8 (ofp, (L_CARD32)colormap[j].l_pad);
  843. #endif
  844. #endif
  845.     }
  846. }
  847.  
  848.  
  849. /* Create a map for mapping up to 32 bit pixelvalues to RGB. */
  850. /* Returns number of colors kept in the map (up to 256) */
  851.  
  852. static int set_pixelmap (int         ncols,
  853.                          L_XWDCOLOR *xwdcol,
  854.                          PIXEL_MAP  *pixelmap)
  855.  
  856. {
  857.   int i, j, k, maxcols;
  858.   L_CARD32 pixel_val;
  859.   
  860.   memset ((char *)pixelmap,0,sizeof (PIXEL_MAP));
  861.   
  862.   maxcols = 0;
  863.   
  864.   for (j = 0; j < ncols; j++) /* For each entry of the XWD colormap */
  865.     {
  866.       pixel_val = xwdcol[j].l_pixel;
  867.       for (k = 0; k < maxcols; k++)  /* Where to insert in list ? */
  868.     {
  869.       if (pixel_val <= pixelmap->pmap[k].pixel_val)
  870.         break;
  871.     }
  872.       if ((k < maxcols) && (pixel_val == pixelmap->pmap[k].pixel_val))
  873.     break;   /* It was already in list */
  874.       
  875.       if (k >= 256) break;
  876.       
  877.       if (k < maxcols)   /* Must move entries to the back ? */
  878.     {
  879.       for (i = maxcols-1; i >= k; i--)
  880.         memcpy ((char *)&(pixelmap->pmap[i+1]),(char *)&(pixelmap->pmap[i]),
  881.             sizeof (PMAP));
  882.     }
  883.       pixelmap->pmap[k].pixel_val = pixel_val;
  884.       pixelmap->pmap[k].red = xwdcol[j].l_red >> 8;
  885.       pixelmap->pmap[k].green = xwdcol[j].l_green >> 8;
  886.       pixelmap->pmap[k].blue = xwdcol[j].l_blue >> 8;
  887.       pixelmap->pixel_in_map[pixel_val & MAPPERMASK] = 1;
  888.       maxcols++;
  889.     }
  890.   pixelmap->npixel = maxcols;
  891. #ifdef XWD_COL_DEBUG
  892.   printf ("Colours in pixelmap: %d\n",pixelmap->npixel);
  893.   for (j=0; j<pixelmap->npixel; j++)
  894.     printf ("Pixelvalue 0x%08lx, 0x%02x 0x%02x 0x%02x\n",
  895.         pixelmap->pmap[j].pixel_val,
  896.         pixelmap->pmap[j].red,pixelmap->pmap[j].green,
  897.         pixelmap->pmap[j].blue);
  898.   for (j=0; j<=MAPPERMASK; j++)
  899.     printf ("0x%08lx: %d\n",(long)j,pixelmap->pixel_in_map[j]);
  900. #endif
  901.   return (pixelmap->npixel);
  902. }
  903.  
  904.  
  905. /* Search a pixel value in the pixel map. Returns 0 if the */
  906. /* pixelval was not found in map. Returns 1 if found. */
  907.  
  908. static int 
  909. get_pixelmap (L_CARD32       pixelval,
  910.           PIXEL_MAP     *pixelmap,
  911.           unsigned char *red,
  912.           unsigned char *green,
  913.           unsigned char *blue)
  914.      
  915. {
  916.   register PMAP *low, *high, *middle;
  917.   
  918.   if (pixelmap->npixel == 0) return (0);
  919.   if (!(pixelmap->pixel_in_map[pixelval & MAPPERMASK])) return (0);
  920.   
  921.   low =  &(pixelmap->pmap[0]);
  922.   high = &(pixelmap->pmap[pixelmap->npixel-1]);
  923.   
  924.   /* Do a binary search on the array */
  925.   while (low < high)
  926.     {
  927.       middle = low + ((high - low)/2);
  928.       if (pixelval <= middle->pixel_val)
  929.     high = middle;
  930.       else
  931.     low = middle+1;
  932.     }
  933.   
  934.   if (pixelval == low->pixel_val)
  935.     {
  936.       *red = low->red; *green = low->green; *blue = low->blue;
  937.       return (1);
  938.     }
  939.   return (0);
  940. }
  941.  
  942.  
  943. static void 
  944. set_bw_color_table (gint32 image_ID)
  945. {
  946.   static unsigned char BWColorMap[2*3] = { 255, 255, 255, 0, 0, 0 };
  947.  
  948. #ifdef XWD_COL_DEBUG
  949.   printf ("Set GIMP b/w-colortable:\n");
  950. #endif
  951.   
  952.   gimp_image_set_cmap (image_ID, BWColorMap, 2);
  953. }
  954.  
  955.  
  956. static void 
  957. set_color_table (gint32           image_ID,
  958.          L_XWDFILEHEADER *xwdhdr,
  959.          L_XWDCOLOR      *xwdcolmap)
  960.      
  961. {
  962.   int ncols, i, j;
  963.   unsigned char ColorMap[256*3];
  964.   
  965.   ncols = xwdhdr->l_colormap_entries;
  966.   if (xwdhdr->l_ncolors < ncols) 
  967.     ncols = xwdhdr->l_ncolors;
  968.   if (ncols <= 0) 
  969.     return;
  970.   if (ncols > 256) 
  971.     ncols = 256;
  972.   
  973.   memset ((char *)ColorMap,0,sizeof (ColorMap));
  974.   
  975.   for (j = 0; j < ncols; j++)
  976.     {
  977.       i = xwdcolmap[j].l_pixel;
  978.       if ((i >= 0) && (i < 256))
  979.     {
  980.       ColorMap[i*3] = (xwdcolmap[j].l_red) >> 8;
  981.       ColorMap[i*3+1] = (xwdcolmap[j].l_green) >> 8;
  982.       ColorMap[i*3+2] = (xwdcolmap[j].l_blue) >> 8;
  983.     }
  984.     }
  985.   
  986. #ifdef XWD_COL_DEBUG
  987.   printf ("Set GIMP colortable:\n");
  988.   for (j = 0; j < ncols; j++)
  989.     printf ("%3d: 0x%02x 0x%02x 0x%02x\n", j,
  990.         ColorMap[j*3], ColorMap[j*3+1], ColorMap[j*3+2]);
  991. #endif
  992.   gimp_image_set_cmap (image_ID, ColorMap, ncols);
  993. }
  994.  
  995.  
  996. /* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
  997. static gint32
  998. create_new_image (char                *filename, 
  999.                   guint                width,
  1000.                   guint                height,
  1001.                   GimpImageBaseType    type,
  1002.                   gint32              *layer_ID,
  1003.                   GimpDrawable       **drawable,
  1004.                   GimpPixelRgn        *pixel_rgn)
  1005. {
  1006.   gint32        image_ID;
  1007.   GimpImageType gdtype;
  1008.   
  1009.   switch (type)
  1010.     {
  1011.     case GIMP_GRAY: 
  1012.       gdtype = GIMP_GRAY_IMAGE;
  1013.       break;
  1014.     case GIMP_INDEXED: 
  1015.       gdtype = GIMP_INDEXED_IMAGE;
  1016.       break;
  1017.     case GIMP_RGB:
  1018.       gdtype = GIMP_RGB_IMAGE;
  1019.       break;
  1020.     default:
  1021.       g_warning ("Unknown image type");
  1022.       return -1;
  1023.     }
  1024.   
  1025.   image_ID = gimp_image_new (width, height, type);
  1026.   gimp_image_set_filename (image_ID, filename);
  1027.   
  1028.   *layer_ID = gimp_layer_new (image_ID, "Background", width, height,
  1029.                   gdtype, 100, GIMP_NORMAL_MODE);
  1030.   gimp_image_add_layer (image_ID, *layer_ID, 0);
  1031.   
  1032.   *drawable = gimp_drawable_get (*layer_ID);
  1033.   gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
  1034.                (*drawable)->height, TRUE, FALSE);
  1035.   return (image_ID);
  1036. }
  1037.  
  1038.  
  1039. /* Load XWD with pixmap_format 2, pixmap_depth 1, bits_per_pixel 1 */
  1040.  
  1041. static gint32
  1042. load_xwd_f2_d1_b1 (char            *filename,
  1043.                    FILE            *ifp,
  1044.                    L_XWDFILEHEADER *xwdhdr,
  1045.                    L_XWDCOLOR      *xwdcolmap)
  1046. {
  1047.   register int pix8;
  1048.   register unsigned char *dest, *src;
  1049.   unsigned char c1, c2, c3, c4;
  1050.   int width, height, linepad, scan_lines, tile_height;
  1051.   int i, j, ncols;
  1052.   char *temp = ident;  /* Just to satisfy lint/gcc */
  1053.   unsigned char bit2byte[256*8];
  1054.   unsigned char *data, *scanline;
  1055.   int err = 0;
  1056.   gint32 layer_ID, image_ID;
  1057.   GimpPixelRgn pixel_rgn;
  1058.   GimpDrawable *drawable;
  1059.   
  1060. #ifdef XWD_DEBUG
  1061.   printf ("load_xwd_f2_d1_b1 (%s)\n", filename);
  1062. #endif
  1063.   
  1064.   width = xwdhdr->l_pixmap_width;
  1065.   height = xwdhdr->l_pixmap_height;
  1066.   
  1067.   image_ID = create_new_image (filename, width, height, GIMP_INDEXED,
  1068.                    &layer_ID, &drawable, &pixel_rgn);
  1069.   
  1070.   tile_height = gimp_tile_height ();
  1071.   data = g_malloc (tile_height * width);
  1072.   
  1073.   scanline = (unsigned char *)g_malloc (xwdhdr->l_bytes_per_line+8);
  1074.   if (scanline == NULL) return (-1);
  1075.   
  1076.   ncols = xwdhdr->l_colormap_entries;
  1077.   if (xwdhdr->l_ncolors < ncols) ncols = xwdhdr->l_ncolors;
  1078.   
  1079.   if (ncols < 2)
  1080.     set_bw_color_table (image_ID);
  1081.   else
  1082.     set_color_table (image_ID, xwdhdr, xwdcolmap);
  1083.   
  1084.   temp = (char *)bit2byte;
  1085.   
  1086.   /* Get an array for mapping 8 bits in a byte to 8 bytes */
  1087.   if (!xwdhdr->l_bitmap_bit_order)
  1088.     {
  1089.       for (j = 0; j < 256; j++)
  1090.     for (i = 0; i < 8; i++)
  1091.       *(temp++) = ((j & (1 << i)) != 0);
  1092.     }
  1093.   else
  1094.     {
  1095.       for (j = 0; j < 256; j++)
  1096.     for (i = 7; i >= 0; i--)
  1097.       *(temp++) = ((j & (1 << i)) != 0);
  1098.     }
  1099.   
  1100.   linepad = xwdhdr->l_bytes_per_line - (xwdhdr->l_pixmap_width+7)/8;
  1101.   if (linepad < 0) linepad = 0;
  1102.   
  1103.   dest = data;
  1104.   scan_lines = 0;
  1105.   
  1106.   for (i = 0; i < height; i++)
  1107.     {
  1108.       if (fread (scanline, xwdhdr->l_bytes_per_line, 1, ifp) != 1)
  1109.     {
  1110.       err = 1;
  1111.       break;
  1112.     }
  1113.       
  1114.       /* Need to check byte order ? */
  1115.       if (xwdhdr->l_bitmap_bit_order != xwdhdr->l_byte_order)
  1116.     {
  1117.       src = scanline;
  1118.       switch (xwdhdr->l_bitmap_unit)
  1119.         {
  1120.         case 16:
  1121.           j = xwdhdr->l_bytes_per_line;
  1122.           while (j > 0)
  1123.         {
  1124.           c1 = src[0]; c2 = src[1];
  1125.           *(src++) = c2; *(src++) = c1;
  1126.           j -= 2;
  1127.         }
  1128.           break;
  1129.           
  1130.         case 32:
  1131.           j = xwdhdr->l_bytes_per_line;
  1132.           while (j > 0)
  1133.         {
  1134.           c1 = src[0]; c2 = src[1]; c3 = src[2]; c4 = src[3];
  1135.           *(src++) = c4; *(src++) = c3; *(src++) = c2; *(src++) = c1;
  1136.           j -= 4;
  1137.         }
  1138.           break;
  1139.         }
  1140.     }
  1141.       src = scanline;
  1142.       j = width;
  1143.       while (j >= 8)
  1144.     {
  1145.       pix8 = *(src++);
  1146.       memcpy (dest, bit2byte + pix8*8, 8);
  1147.       dest += 8;
  1148.       j -= 8;
  1149.     }
  1150.       if (j > 0)
  1151.     {
  1152.       pix8 = *(src++);
  1153.       memcpy (dest, bit2byte + pix8*8, j);
  1154.       dest += j;
  1155.     }
  1156.       
  1157.       scan_lines++;
  1158.       
  1159.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  1160.     gimp_progress_update ((double)(i+1) / (double)height);
  1161.       
  1162.       if ((scan_lines == tile_height) || ((i+1) == height))
  1163.     {
  1164.       gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, i-scan_lines+1,
  1165.                    width, scan_lines);
  1166.       scan_lines = 0;
  1167.       dest = data;
  1168.     }
  1169.       if (err) break;
  1170.     }
  1171.   g_free (data);
  1172.   g_free (scanline);
  1173.   
  1174.   if (err)
  1175.     g_message (_("EOF encountered on "));
  1176.   
  1177.   gimp_drawable_flush (drawable);
  1178.   
  1179.   return (err ? -1 : image_ID);
  1180. }
  1181.  
  1182.  
  1183. /* Load XWD with pixmap_format 2, pixmap_depth 8, bits_per_pixel 8 */
  1184.  
  1185. static gint32
  1186. load_xwd_f2_d8_b8 (char            *filename,
  1187.                    FILE            *ifp,
  1188.                    L_XWDFILEHEADER *xwdhdr,
  1189.                    L_XWDCOLOR      *xwdcolmap)
  1190. {
  1191.   int width, height, linepad, tile_height, scan_lines;
  1192.   int i, j, ncols;
  1193.   int greyscale;
  1194.   unsigned char *dest, *data;
  1195.   int err = 0;
  1196.   gint32 layer_ID, image_ID;
  1197.   GimpPixelRgn pixel_rgn;
  1198.   GimpDrawable *drawable;
  1199.   
  1200. #ifdef XWD_DEBUG
  1201.   printf ("load_xwd_f2_d8_b8 (%s)\n", filename);
  1202. #endif
  1203.   
  1204.   width = xwdhdr->l_pixmap_width;
  1205.   height = xwdhdr->l_pixmap_height;
  1206.   
  1207.   /* This could also be a greyscale image. Check it */
  1208.   greyscale = 0;
  1209.   if ((xwdhdr->l_ncolors == 256) && (xwdhdr->l_colormap_entries == 256))
  1210.     {
  1211.       for (j = 0; j < 256; j++)
  1212.     {
  1213.       if (   (xwdcolmap[j].l_pixel != j)
  1214.          || ((xwdcolmap[j].l_red >> 8) != j)
  1215.          || ((xwdcolmap[j].l_green >> 8) != j)
  1216.          || ((xwdcolmap[j].l_blue >> 8) != j))
  1217.         break;
  1218.     }
  1219.       greyscale = (j == 256);
  1220.     }
  1221.   
  1222.   image_ID = create_new_image (filename, width, height,
  1223.                    greyscale ? GIMP_GRAY : GIMP_INDEXED,
  1224.                    &layer_ID, &drawable, &pixel_rgn);
  1225.   
  1226.   tile_height = gimp_tile_height ();
  1227.   data = g_malloc (tile_height * width);
  1228.   
  1229.   if (!greyscale)
  1230.     {
  1231.       ncols = xwdhdr->l_colormap_entries;
  1232.       if (xwdhdr->l_ncolors < ncols) ncols = xwdhdr->l_ncolors;
  1233.       if (ncols < 2)
  1234.     set_bw_color_table (image_ID);
  1235.       else
  1236.     set_color_table (image_ID, xwdhdr, xwdcolmap);
  1237.     }
  1238.   
  1239.   linepad = xwdhdr->l_bytes_per_line - xwdhdr->l_pixmap_width;
  1240.   if (linepad < 0) linepad = 0;
  1241.   
  1242.   dest = data;
  1243.   scan_lines = 0;
  1244.   
  1245.   for (i = 0; i < height; i++)
  1246.     {
  1247.       if (fread (dest, 1, width, ifp) != width)
  1248.     {
  1249.       err = 1;
  1250.       break;
  1251.     }
  1252.       dest += width;
  1253.       
  1254.       for (j = 0; j < linepad; j++)
  1255.     getc (ifp);
  1256.       
  1257.       scan_lines++;
  1258.       
  1259.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  1260.     gimp_progress_update ((double)(i+1) / (double)height);
  1261.       
  1262.       if ((scan_lines == tile_height) || ((i+1) == height))
  1263.     {
  1264.       gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, i-scan_lines+1,
  1265.                    width, scan_lines);
  1266.       scan_lines = 0;
  1267.       dest = data;
  1268.     }
  1269.     }
  1270.   g_free (data);
  1271.   
  1272.   if (err)
  1273.     g_message (_("EOF encountered on reading"));
  1274.   
  1275.   gimp_drawable_flush (drawable);
  1276.   
  1277.   return (err ? -1 : image_ID);
  1278. }
  1279.  
  1280.  
  1281. /* Load XWD with pixmap_format 2, pixmap_depth up to 16, bits_per_pixel 16 */
  1282.  
  1283. static gint32
  1284. load_xwd_f2_d16_b16 (char            *filename,
  1285.                      FILE             *ifp,
  1286.                      L_XWDFILEHEADER *xwdhdr,
  1287.                      L_XWDCOLOR      *xwdcolmap)
  1288. {
  1289.   register unsigned char *dest, lsbyte_first;
  1290.   int width, height, linepad, i, j, c0, c1, ncols;
  1291.   int red, green, blue, redval, greenval, blueval;
  1292.   int maxred, maxgreen, maxblue;
  1293.   int tile_height, scan_lines;
  1294.   unsigned long redmask, greenmask, bluemask;
  1295.   unsigned int redshift, greenshift, blueshift;
  1296.   unsigned long maxval;
  1297.   unsigned char *ColorMap, *cm, *data;
  1298.   int err = 0;
  1299.   gint32 layer_ID, image_ID;
  1300.   GimpPixelRgn pixel_rgn;
  1301.   GimpDrawable *drawable;
  1302.   
  1303. #ifdef XWD_DEBUG
  1304.   printf ("load_xwd_f2_d16_b16 (%s)\n", filename);
  1305. #endif
  1306.   
  1307.   width = xwdhdr->l_pixmap_width;
  1308.   height = xwdhdr->l_pixmap_height;
  1309.   
  1310.   image_ID = create_new_image (filename, width, height, GIMP_RGB,
  1311.                    &layer_ID, &drawable, &pixel_rgn);
  1312.   
  1313.   tile_height = gimp_tile_height ();
  1314.   data = g_malloc (tile_height * width * 3);
  1315.   
  1316.   /* Get memory for mapping 16 bit XWD-pixel to GIMP-RGB */
  1317.   maxval = 0x10000 * 3;
  1318.   ColorMap = (unsigned char *)g_malloc (maxval);
  1319.   if (ColorMap == NULL)
  1320.     {
  1321.       g_message (_("No memory for mapping colors"));
  1322.       return (-1);
  1323.     }
  1324.   memset (ColorMap,0,maxval);
  1325.   
  1326.   redmask   = xwdhdr->l_red_mask;
  1327.   greenmask = xwdhdr->l_green_mask;
  1328.   bluemask  = xwdhdr->l_blue_mask;
  1329.   
  1330.   /* How to shift RGB to be right aligned ? */
  1331.   /* (We rely on the the mask bits are grouped and not mixed) */
  1332.   redshift = greenshift = blueshift = 0;
  1333.   
  1334.   while (((1 << redshift) & redmask) == 0) redshift++;
  1335.   while (((1 << greenshift) & greenmask) == 0) greenshift++;
  1336.   while (((1 << blueshift) & bluemask) == 0) blueshift++;
  1337.   
  1338.   /* The bits_per_rgb may not be correct. Use redmask instead */
  1339.   maxred = 0; while (redmask >> (redshift + maxred)) maxred++;
  1340.   maxred = (1 << maxred) - 1;
  1341.   
  1342.   maxgreen = 0; while (greenmask >> (greenshift + maxgreen)) maxgreen++;
  1343.   maxgreen = (1 << maxgreen) - 1;
  1344.   
  1345.   maxblue = 0; while (bluemask >> (blueshift + maxblue)) maxblue++;
  1346.   maxblue = (1 << maxblue) - 1;
  1347.   
  1348.   /* Built up the array to map XWD-pixel value to GIMP-RGB */
  1349.   for (red = 0; red <= maxred; red++)
  1350.     {
  1351.       redval = (red * 255) / maxred;
  1352.       for (green = 0; green <= maxgreen; green++)
  1353.     {
  1354.       greenval = (green * 255) / maxgreen;
  1355.       for (blue = 0; blue <= maxblue; blue++)
  1356.         {
  1357.           blueval = (blue * 255) / maxblue;
  1358.           cm = ColorMap + ((red << redshift) + (green << greenshift)
  1359.                    + (blue << blueshift)) * 3;
  1360.           *(cm++) = redval;
  1361.           *(cm++) = greenval;
  1362.           *cm = blueval;
  1363.         }
  1364.     }
  1365.     }
  1366.   
  1367.   /* Now look what was written to the XWD-Colormap */
  1368.   
  1369.   ncols = xwdhdr->l_colormap_entries;
  1370.   if (xwdhdr->l_ncolors < ncols) ncols = xwdhdr->l_ncolors;
  1371.   
  1372.   for (j = 0; j < ncols; j++)
  1373.     {
  1374.       cm = ColorMap + xwdcolmap[j].l_pixel * 3;
  1375.       *(cm++) = (xwdcolmap[j].l_red >> 8);
  1376.       *(cm++) = (xwdcolmap[j].l_green >> 8);
  1377.       *cm = (xwdcolmap[j].l_blue >> 8);
  1378.     }
  1379.   
  1380.   /* What do we have to consume after a line has finished ? */
  1381.   linepad =   xwdhdr->l_bytes_per_line
  1382.     - (xwdhdr->l_pixmap_width*xwdhdr->l_bits_per_pixel)/8;
  1383.   if (linepad < 0) linepad = 0;
  1384.   
  1385.   lsbyte_first = (xwdhdr->l_byte_order == 0);
  1386.   
  1387.   dest = data;
  1388.   scan_lines = 0;
  1389.   
  1390.   for (i = 0; i < height; i++)
  1391.     {
  1392.       for (j = 0; j < width; j++)
  1393.     {
  1394.       c0 = getc (ifp);
  1395.       c1 = getc (ifp);
  1396.       if (c1 < 0)
  1397.         {
  1398.           err = 1;
  1399.           break;
  1400.         }
  1401.       
  1402.       if (lsbyte_first)
  1403.         c0 = c0 | (c1 << 8);
  1404.       else
  1405.         c0 = (c0 << 8) | c1;
  1406.       
  1407.       cm = ColorMap + c0 * 3;
  1408.       *(dest++) = *(cm++);
  1409.       *(dest++) = *(cm++);
  1410.       *(dest++) = *cm;
  1411.     }
  1412.       
  1413.       if (err) break;
  1414.       
  1415.       for (j = 0; j < linepad; j++)
  1416.     getc (ifp);
  1417.       
  1418.       scan_lines++;
  1419.       
  1420.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  1421.     gimp_progress_update ((double)(i+1) / (double)height);
  1422.       
  1423.       if ((scan_lines == tile_height) || ((i+1) == height))
  1424.     {
  1425.       gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, i-scan_lines+1,
  1426.                    width, scan_lines);
  1427.       scan_lines = 0;
  1428.       dest = data;
  1429.     }
  1430.     }
  1431.   g_free (data);
  1432.   g_free (ColorMap);
  1433.   
  1434.   if (err)
  1435.     g_message (_("EOF encountered on reading"));
  1436.   
  1437.   gimp_drawable_flush (drawable);
  1438.   
  1439.   return (err ? -1 : image_ID);
  1440. }
  1441.  
  1442.  
  1443. /* Load XWD with pixmap_format 2, pixmap_depth up to 24, bits_per_pixel 24/32 */
  1444.  
  1445. static gint32
  1446. load_xwd_f2_d24_b32 (char            *filename,
  1447.                      FILE            *ifp,
  1448.                      L_XWDFILEHEADER *xwdhdr,
  1449.                      L_XWDCOLOR      *xwdcolmap)
  1450. {
  1451.   register unsigned char *dest, lsbyte_first;
  1452.   int width, height, linepad, i, j, c0, c1, c2, c3;
  1453.   int tile_height, scan_lines;
  1454.   L_CARD32 pixelval;
  1455.   int red, green, blue, ncols;
  1456.   int maxred, maxgreen, maxblue;
  1457.   unsigned long redmask, greenmask, bluemask;
  1458.   unsigned int redshift, greenshift, blueshift;
  1459.   unsigned char redmap[256],greenmap[256],bluemap[256];
  1460.   unsigned char *data;
  1461.   PIXEL_MAP pixel_map;
  1462.   int err = 0;
  1463.   gint32 layer_ID, image_ID;
  1464.   GimpPixelRgn pixel_rgn;
  1465.   GimpDrawable *drawable;
  1466.   
  1467. #ifdef XWD_DEBUG
  1468.   printf ("load_xwd_f2_d24_b32 (%s)\n", filename);
  1469. #endif
  1470.   
  1471.   width = xwdhdr->l_pixmap_width;
  1472.   height = xwdhdr->l_pixmap_height;
  1473.   
  1474.   image_ID = create_new_image (filename, width, height, GIMP_RGB,
  1475.                    &layer_ID, &drawable, &pixel_rgn);
  1476.   
  1477.   tile_height = gimp_tile_height ();
  1478.   data = g_malloc (tile_height * width * 3);
  1479.   
  1480.   redmask   = xwdhdr->l_red_mask;
  1481.   greenmask = xwdhdr->l_green_mask;
  1482.   bluemask  = xwdhdr->l_blue_mask;
  1483.   
  1484.   if (redmask == 0) redmask = 0xff0000;
  1485.   if (greenmask == 0) greenmask = 0x00ff00;
  1486.   if (bluemask == 0) bluemask = 0x0000ff;
  1487.   
  1488.   /* How to shift RGB to be right aligned ? */
  1489.   /* (We rely on the the mask bits are grouped and not mixed) */
  1490.   redshift = greenshift = blueshift = 0;
  1491.   
  1492.   while (((1 << redshift) & redmask) == 0) redshift++;
  1493.   while (((1 << greenshift) & greenmask) == 0) greenshift++;
  1494.   while (((1 << blueshift) & bluemask) == 0) blueshift++;
  1495.   
  1496.   /* The bits_per_rgb may not be correct. Use redmask instead */
  1497.   
  1498.   maxred = 0; while (redmask >> (redshift + maxred)) maxred++;
  1499.   maxred = (1 << maxred) - 1;
  1500.   
  1501.   maxgreen = 0; while (greenmask >> (greenshift + maxgreen)) maxgreen++;
  1502.   maxgreen = (1 << maxgreen) - 1;
  1503.   
  1504.   maxblue = 0; while (bluemask >> (blueshift + maxblue)) maxblue++;
  1505.   maxblue = (1 << maxblue) - 1;
  1506.   
  1507.   /* Set map-arrays for red, green, blue */
  1508.   for (red = 0; red <= maxred; red++)
  1509.     redmap[red] = (red * 255) / maxred;
  1510.   for (green = 0; green <= maxgreen; green++)
  1511.     greenmap[green] = (green * 255) / maxgreen;
  1512.   for (blue = 0; blue <= maxblue; blue++)
  1513.     bluemap[blue] = (blue * 255) / maxblue;
  1514.   
  1515.   ncols = xwdhdr->l_colormap_entries;
  1516.   if (xwdhdr->l_ncolors < ncols) ncols = xwdhdr->l_ncolors;
  1517.   
  1518.   ncols = set_pixelmap (ncols, xwdcolmap, &pixel_map);
  1519.   
  1520.   /* What do we have to consume after a line has finished ? */
  1521.   linepad =   xwdhdr->l_bytes_per_line
  1522.     - (xwdhdr->l_pixmap_width*xwdhdr->l_bits_per_pixel)/8;
  1523.   if (linepad < 0) linepad = 0;
  1524.   
  1525.   lsbyte_first = (xwdhdr->l_byte_order == 0);
  1526.   
  1527.   dest = data;
  1528.   scan_lines = 0;
  1529.   
  1530.   if (xwdhdr->l_bits_per_pixel == 32)
  1531.     {
  1532.       for (i = 0; i < height; i++)
  1533.     {
  1534.       for (j = 0; j < width; j++)
  1535.         {
  1536.           c0 = getc (ifp);
  1537.           c1 = getc (ifp);
  1538.           c2 = getc (ifp);
  1539.           c3 = getc (ifp);
  1540.           if (c3 < 0)
  1541.         {
  1542.           err = 1;
  1543.           break;
  1544.         }
  1545.           if (lsbyte_first)
  1546.         pixelval = c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
  1547.           else
  1548.         pixelval = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
  1549.           
  1550.           if (get_pixelmap (pixelval, &pixel_map, dest, dest+1, dest+2))
  1551.         {
  1552.           dest += 3;
  1553.         }
  1554.           else
  1555.         {
  1556.           *(dest++) = redmap[(pixelval & redmask) >> redshift];
  1557.           *(dest++) = greenmap[(pixelval & greenmask) >> greenshift];
  1558.           *(dest++) = bluemap[(pixelval & bluemask) >> blueshift];
  1559.         }
  1560.         }
  1561.       scan_lines++;
  1562.       
  1563.       if (err) break;
  1564.       
  1565.       for (j = 0; j < linepad; j++)
  1566.         getc (ifp);
  1567.       
  1568.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  1569.         gimp_progress_update ((double)(i+1) / (double)height);
  1570.       
  1571.       if ((scan_lines == tile_height) || ((i+1) == height))
  1572.         {
  1573.           gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, i-scan_lines+1,
  1574.                        width, scan_lines);
  1575.           scan_lines = 0;
  1576.           dest = data;
  1577.         }
  1578.     }
  1579.     }
  1580.   else    /* 24 bits per pixel */
  1581.     {
  1582.       for (i = 0; i < height; i++)
  1583.     {
  1584.       for (j = 0; j < width; j++)
  1585.         {
  1586.           c0 = getc (ifp);
  1587.           c1 = getc (ifp);
  1588.           c2 = getc (ifp);
  1589.           if (c2 < 0)
  1590.         {
  1591.           err = 1;
  1592.           break;
  1593.         }
  1594.           if (lsbyte_first)
  1595.         pixelval = c0 | (c1 << 8) | (c2 << 16);
  1596.           else
  1597.         pixelval = (c0 << 16) | (c1 << 8) | c2;
  1598.           
  1599.           if (get_pixelmap (pixelval, &pixel_map, dest, dest+1, dest+2))
  1600.         {
  1601.           dest += 3;
  1602.         }
  1603.           else
  1604.         {
  1605.           *(dest++) = redmap[(pixelval & redmask) >> redshift];
  1606.           *(dest++) = greenmap[(pixelval & greenmask) >> greenshift];
  1607.           *(dest++) = bluemap[(pixelval & bluemask) >> blueshift];
  1608.         }
  1609.         }
  1610.       scan_lines++;
  1611.       
  1612.       if (err) break;
  1613.       
  1614.       for (j = 0; j < linepad; j++)
  1615.         getc (ifp);
  1616.       
  1617.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  1618.         gimp_progress_update ((double)(i+1) / (double)height);
  1619.       
  1620.       if ((scan_lines == tile_height) || ((i+1) == height))
  1621.         {
  1622.           gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, i-scan_lines+1,
  1623.                        width, scan_lines);
  1624.           scan_lines = 0;
  1625.           dest = data;
  1626.         }
  1627.     }
  1628.     }
  1629.   g_free (data);
  1630.   
  1631.   if (err)
  1632.     g_message (_("EOF encountered on reading"));
  1633.   
  1634.   gimp_drawable_flush (drawable);
  1635.   
  1636.   return (err ? -1 : image_ID);
  1637. }
  1638.  
  1639.  
  1640. /* Load XWD with pixmap_format 1, pixmap_depth up to 24, bits_per_pixel 1 */
  1641.  
  1642. static gint32
  1643. load_xwd_f1_d24_b1 (char            *filename,
  1644.                     FILE            *ifp,
  1645.                     L_XWDFILEHEADER *xwdhdr,
  1646.                     L_XWDCOLOR      *xwdcolmap)
  1647. {
  1648.   register unsigned char *dest, outmask, inmask, do_reverse;
  1649.   int width, height, linepad, i, j, plane, fromright;
  1650.   int tile_height, tile_start, tile_end;
  1651.   int indexed, bytes_per_pixel;
  1652.   int maxred, maxgreen, maxblue;
  1653.   int red, green, blue, ncols, standard_rgb;
  1654.   long data_offset, plane_offset, tile_offset;
  1655.   unsigned long redmask, greenmask, bluemask;
  1656.   unsigned int redshift, greenshift, blueshift;
  1657.   unsigned long g;
  1658.   unsigned char redmap[256], greenmap[256], bluemap[256];
  1659.   unsigned char bit_reverse[256];
  1660.   unsigned char *xwddata, *xwdin, *data;
  1661.   L_CARD32 pixelval;
  1662.   PIXEL_MAP pixel_map;
  1663.   int err = 0;
  1664.   gint32 layer_ID, image_ID;
  1665.   GimpPixelRgn pixel_rgn;
  1666.   GimpDrawable *drawable;
  1667.   
  1668. #ifdef XWD_DEBUG
  1669.   printf ("load_xwd_f1_d24_b1 (%s)\n", filename);
  1670. #endif
  1671.   
  1672.   xwddata = g_malloc (xwdhdr->l_bytes_per_line);
  1673.   if (xwddata == NULL) return (-1);
  1674.   
  1675.   width = xwdhdr->l_pixmap_width;
  1676.   height = xwdhdr->l_pixmap_height;
  1677.   indexed = (xwdhdr->l_pixmap_depth <= 8);
  1678.   bytes_per_pixel = (indexed ? 1 : 3);
  1679.   
  1680.   image_ID = create_new_image (filename, width, height, indexed ? GIMP_INDEXED : GIMP_RGB,
  1681.                    &layer_ID, &drawable, &pixel_rgn);
  1682.   
  1683.   tile_height = gimp_tile_height ();
  1684.   data = g_malloc (tile_height * width * bytes_per_pixel);
  1685.   
  1686.   linepad =   xwdhdr->l_bytes_per_line
  1687.     - (xwdhdr->l_pixmap_width+7)/8;
  1688.   if (linepad < 0) linepad = 0;
  1689.   
  1690.   for (j = 0; j < 256; j++)   /* Create an array for reversing bits */
  1691.     {
  1692.       inmask = 0;
  1693.       for (i = 0; i < 8; i++)
  1694.     {
  1695.       inmask <<= 1;
  1696.       if (j & (1 << i)) inmask |= 1;
  1697.     }
  1698.       bit_reverse[j] = inmask;
  1699.     }
  1700.   
  1701.   redmask   = xwdhdr->l_red_mask;
  1702.   greenmask = xwdhdr->l_green_mask;
  1703.   bluemask  = xwdhdr->l_blue_mask;
  1704.   
  1705.   if (redmask == 0) redmask = 0xff0000;
  1706.   if (greenmask == 0) greenmask = 0x00ff00;
  1707.   if (bluemask == 0) bluemask = 0x0000ff;
  1708.   
  1709.   standard_rgb =    (redmask == 0xff0000) && (greenmask == 0x00ff00)
  1710.     && (bluemask == 0x0000ff);
  1711.   redshift = greenshift = blueshift = 0;
  1712.   
  1713.  if (!standard_rgb)   /* Do we need to re-map the pixel-values ? */
  1714.    {
  1715.      /* How to shift RGB to be right aligned ? */
  1716.      /* (We rely on the the mask bits are grouped and not mixed) */
  1717.      
  1718.      while (((1 << redshift) & redmask) == 0) redshift++;
  1719.      while (((1 << greenshift) & greenmask) == 0) greenshift++;
  1720.      while (((1 << blueshift) & bluemask) == 0) blueshift++;
  1721.      
  1722.      /* The bits_per_rgb may not be correct. Use redmask instead */
  1723.      
  1724.      maxred = 0; while (redmask >> (redshift + maxred)) maxred++;
  1725.      maxred = (1 << maxred) - 1;
  1726.      
  1727.      maxgreen = 0; while (greenmask >> (greenshift + maxgreen)) maxgreen++;
  1728.      maxgreen = (1 << maxgreen) - 1;
  1729.      
  1730.      maxblue = 0; while (bluemask >> (blueshift + maxblue)) maxblue++;
  1731.      maxblue = (1 << maxblue) - 1;
  1732.      
  1733.      /* Set map-arrays for red, green, blue */
  1734.      for (red = 0; red <= maxred; red++)
  1735.        redmap[red] = (red * 255) / maxred;
  1736.      for (green = 0; green <= maxgreen; green++)
  1737.        greenmap[green] = (green * 255) / maxgreen;
  1738.      for (blue = 0; blue <= maxblue; blue++)
  1739.        bluemap[blue] = (blue * 255) / maxblue;
  1740.    }
  1741.  
  1742.  ncols = xwdhdr->l_colormap_entries;
  1743.  if (xwdhdr->l_ncolors < ncols) ncols = xwdhdr->l_ncolors;
  1744.  if (indexed)
  1745.    {
  1746.      if (ncols < 2)
  1747.        set_bw_color_table (image_ID);
  1748.      else
  1749.        set_color_table (image_ID, xwdhdr, xwdcolmap);
  1750.    }
  1751.  else
  1752.    {
  1753.      ncols = set_pixelmap (ncols, xwdcolmap, &pixel_map);
  1754.    }
  1755.  
  1756.  do_reverse = !xwdhdr->l_bitmap_bit_order;
  1757.  
  1758.  /* This is where the image data starts within the file */
  1759.  data_offset = ftell (ifp);
  1760.  
  1761.  for (tile_start = 0; tile_start < height; tile_start += tile_height)
  1762.    {
  1763.      memset (data, 0, width*tile_height*bytes_per_pixel);
  1764.      
  1765.      tile_end = tile_start + tile_height - 1;
  1766.      if (tile_end >= height) tile_end = height - 1;
  1767.      
  1768.      for (plane = 0; plane < xwdhdr->l_pixmap_depth; plane++)
  1769.        {
  1770.      dest = data;    /* Position to start of tile within the plane */
  1771.      plane_offset = data_offset + plane*height*xwdhdr->l_bytes_per_line;
  1772.      tile_offset = plane_offset + tile_start*xwdhdr->l_bytes_per_line;
  1773.      fseek (ifp, tile_offset, SEEK_SET);
  1774.      
  1775.      /* Place the last plane at the least significant bit */
  1776.      
  1777.      if (indexed)   /* Only 1 byte per pixel */
  1778.        {
  1779.          fromright = xwdhdr->l_pixmap_depth-1-plane;
  1780.          outmask = (1 << fromright);
  1781.        }
  1782.      else           /* 3 bytes per pixel */
  1783.        {
  1784.          fromright = xwdhdr->l_pixmap_depth-1-plane;
  1785.          dest += 2 - fromright/8;
  1786.          outmask = (1 << (fromright % 8));
  1787.        }
  1788.      
  1789.      for (i = tile_start; i <= tile_end; i++)
  1790.        {
  1791.          if (fread (xwddata,xwdhdr->l_bytes_per_line,1,ifp) != 1)
  1792.            {
  1793.          err = 1;
  1794.          break;
  1795.            }
  1796.          xwdin = xwddata;
  1797.          
  1798.          /* Handle bitmap unit */
  1799.          if (xwdhdr->l_bitmap_unit == 16)
  1800.            {
  1801.          if (xwdhdr->l_bitmap_bit_order != xwdhdr->l_byte_order)
  1802.            {
  1803.              j = xwdhdr->l_bytes_per_line/2;
  1804.              while (j--)
  1805.                {
  1806.              inmask = xwdin[0]; xwdin[0] = xwdin[1]; xwdin[1] = inmask;
  1807.              xwdin += 2;
  1808.                }
  1809.              xwdin = xwddata;
  1810.            }
  1811.            }
  1812.          else if (xwdhdr->l_bitmap_unit == 32)
  1813.            {
  1814.          if (xwdhdr->l_bitmap_bit_order != xwdhdr->l_byte_order)
  1815.            {
  1816.              j = xwdhdr->l_bytes_per_line/4;
  1817.              while (j--)
  1818.                {
  1819.              inmask = xwdin[0]; xwdin[0] = xwdin[3]; xwdin[3] = inmask;
  1820.              inmask = xwdin[1]; xwdin[1] = xwdin[2]; xwdin[2] = inmask;
  1821.              xwdin += 4;
  1822.                }
  1823.              xwdin = xwddata;
  1824.            }
  1825.            }
  1826.          
  1827.          g = inmask = 0;
  1828.          for (j = 0; j < width; j++)
  1829.            {
  1830.          if (!inmask)
  1831.            {
  1832.              g = *(xwdin++);
  1833.              if (do_reverse) 
  1834.                g = bit_reverse[g];
  1835.              inmask = 0x80;
  1836.            }
  1837.          
  1838.          if (g & inmask) 
  1839.            *dest |= outmask;
  1840.          dest += bytes_per_pixel;
  1841.          
  1842.          inmask >>= 1;
  1843.            }
  1844.        }
  1845.      
  1846.        }
  1847.      
  1848.      /* For indexed images, the mapping to colors is done by the color table. */
  1849.      /* Otherwise we must do the mapping by ourself. */
  1850.      if (!indexed)
  1851.        {
  1852.      dest = data;
  1853.      for (i = tile_start; i <= tile_end; i++)
  1854.        {
  1855.          for (j = 0; j < width; j++)
  1856.            {
  1857.          pixelval = (*dest << 16) | (*(dest+1) << 8) | *(dest+2);
  1858.          if (   get_pixelmap (pixelval, &pixel_map, dest, dest+1, dest+2)
  1859.             || standard_rgb)
  1860.            {
  1861.              dest += 3;
  1862.            }
  1863.          else   /* We have to map RGB to 0,...,255 */
  1864.            {
  1865.              *(dest++) = redmap[(pixelval & redmask) >> redshift];
  1866.              *(dest++) = greenmap[(pixelval & greenmask) >> greenshift];
  1867.              *(dest++) = bluemap[(pixelval & bluemask) >> blueshift];
  1868.            }
  1869.            }
  1870.        }
  1871.        }
  1872.      
  1873.      if (l_run_mode != GIMP_RUN_NONINTERACTIVE)
  1874.        gimp_progress_update ((double)(tile_end) / (double)(height));
  1875.      
  1876.      gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, tile_start,
  1877.                   width, tile_end-tile_start+1);
  1878.    }
  1879.  g_free (data);
  1880.  g_free (xwddata);
  1881.  
  1882.  if (err)
  1883.    g_message (_("EOF encountered on reading"));
  1884.  
  1885.  gimp_drawable_flush (drawable);
  1886.  
  1887.  return (err ? -1 : image_ID);
  1888. }
  1889.  
  1890.  
  1891. static gint
  1892. save_index (FILE    *ofp,
  1893.         gint32   image_ID,
  1894.         gint32   drawable_ID,
  1895.         int      grey)
  1896.   int height, width, linepad, tile_height, i, j;
  1897.   int ncolors, vclass;
  1898.   long tmp = 0;
  1899.   unsigned char *data, *src, *cmap;
  1900.   L_XWDFILEHEADER xwdhdr;
  1901.   L_XWDCOLOR xwdcolmap[256];
  1902.   GimpPixelRgn pixel_rgn;
  1903.   GimpDrawable *drawable;
  1904.   GimpImageType drawable_type;
  1905.   
  1906. #ifdef XWD_DEBUG
  1907.   printf ("save_index ()\n");
  1908. #endif
  1909.   
  1910.   drawable = gimp_drawable_get (drawable_ID);
  1911.   drawable_type = gimp_drawable_type (drawable_ID);
  1912.   width = drawable->width;
  1913.   height = drawable->height;
  1914.   tile_height = gimp_tile_height ();
  1915.   gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, FALSE, FALSE);
  1916.   
  1917.   /* allocate a buffer for retrieving information from the pixel region  */
  1918.   src = data = (unsigned char *)g_malloc (tile_height * width * drawable->bpp);
  1919.  
  1920.   linepad = width % 4;
  1921.   if (linepad) linepad = 4 - linepad;
  1922.  
  1923.   /* Fill XWD-color map */
  1924.   if (grey)
  1925.     {
  1926.       vclass = 0;
  1927.       ncolors = 256;
  1928.       
  1929.       for (j = 0; j < ncolors; j++)
  1930.     {
  1931.       xwdcolmap[j].l_pixel = j;
  1932.       xwdcolmap[j].l_red   = (j << 8) | j;
  1933.       xwdcolmap[j].l_green = (j << 8) | j;
  1934.       xwdcolmap[j].l_blue  = (j << 8) | j;
  1935.       xwdcolmap[j].l_flags = 7;
  1936.       xwdcolmap[j].l_pad = 0;
  1937.     }
  1938.     }
  1939.   else
  1940.     {
  1941.       vclass = 3;
  1942.       cmap = gimp_image_get_cmap (image_ID, &ncolors);
  1943.       
  1944.       for (j = 0; j < ncolors; j++)
  1945.     {
  1946.       xwdcolmap[j].l_pixel = j;
  1947.       xwdcolmap[j].l_red   = ((*cmap) << 8) | *cmap; cmap++;
  1948.       xwdcolmap[j].l_green = ((*cmap) << 8) | *cmap; cmap++;
  1949.       xwdcolmap[j].l_blue  = ((*cmap) << 8) | *cmap; cmap++;
  1950.       xwdcolmap[j].l_flags = 7;
  1951.       xwdcolmap[j].l_pad = 0;
  1952.     }
  1953.     }
  1954.   
  1955.   /* Fill in the XWD header (header_size is evaluated by write_xwd_hdr ()) */
  1956.   xwdhdr.l_header_size = 0;
  1957.   xwdhdr.l_file_version = 7;
  1958.   xwdhdr.l_pixmap_format = 2;
  1959.   xwdhdr.l_pixmap_depth = 8;
  1960.   xwdhdr.l_pixmap_width = width;
  1961.   xwdhdr.l_pixmap_height = height;
  1962.   xwdhdr.l_xoffset = 0;
  1963.   xwdhdr.l_byte_order = 1;
  1964.   xwdhdr.l_bitmap_unit = 32;
  1965.   xwdhdr.l_bitmap_bit_order = 1;
  1966.   xwdhdr.l_bitmap_pad = 32;
  1967.   xwdhdr.l_bits_per_pixel = 8;
  1968.   xwdhdr.l_bytes_per_line = width + linepad;
  1969.   xwdhdr.l_visual_class = vclass;
  1970.   xwdhdr.l_red_mask = 0x000000;
  1971.   xwdhdr.l_green_mask = 0x000000;
  1972.   xwdhdr.l_blue_mask = 0x000000;
  1973.   xwdhdr.l_bits_per_rgb = 8;
  1974.   xwdhdr.l_colormap_entries = ncolors;
  1975.   xwdhdr.l_ncolors = ncolors;
  1976.   xwdhdr.l_window_width = width;
  1977.   xwdhdr.l_window_height = height;
  1978.   xwdhdr.l_window_x = 64;
  1979.   xwdhdr.l_window_y = 64;
  1980.   xwdhdr.l_window_bdrwidth = 0;
  1981.  
  1982.   write_xwd_header (ofp, &xwdhdr);
  1983.   write_xwd_cols (ofp, &xwdhdr, xwdcolmap);
  1984.  
  1985.   for (i = 0; i < height; i++)
  1986.     {
  1987.       if ((i % tile_height) == 0)   /* Get more data */
  1988.     {int scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i);
  1989.     
  1990.     gimp_pixel_rgn_get_rect (&pixel_rgn, data, 0, i, width, scan_lines);
  1991.     src = data;
  1992.     }
  1993.       fwrite (src, width, 1, ofp);
  1994.       if (linepad) fwrite ((char *)&tmp, linepad, 1, ofp);
  1995.       src += width;
  1996.       
  1997.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  1998.     gimp_progress_update ((double) i / (double) height);
  1999.     }
  2000.   g_free (data);
  2001.   
  2002.   gimp_drawable_detach (drawable);
  2003.   
  2004.   if (ferror (ofp))
  2005.     {
  2006.       g_message (_("Error during writing indexed/grey image"));
  2007.       return (FALSE);
  2008.     }
  2009.   return (TRUE);
  2010. }
  2011.  
  2012.  
  2013. static gint
  2014. save_rgb (FILE   *ofp,
  2015.           gint32  image_ID,
  2016.           gint32  drawable_ID)   
  2017.   int height, width, linepad, tile_height, i;
  2018.   long tmp = 0;
  2019.   unsigned char *data, *src;
  2020.   L_XWDFILEHEADER xwdhdr;
  2021.   GimpPixelRgn pixel_rgn;
  2022.   GimpDrawable *drawable;
  2023.   GimpImageType drawable_type;
  2024.  
  2025. #ifdef XWD_DEBUG
  2026.   printf ("save_rgb ()\n");
  2027. #endif
  2028.  
  2029.   drawable = gimp_drawable_get (drawable_ID);
  2030.   drawable_type = gimp_drawable_type (drawable_ID);
  2031.   width = drawable->width;
  2032.   height = drawable->height;
  2033.   tile_height = gimp_tile_height ();
  2034.   gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, FALSE, FALSE);
  2035.  
  2036.   /* allocate a buffer for retrieving information from the pixel region  */
  2037.   src = data = (unsigned char *)g_malloc (tile_height * width * drawable->bpp);
  2038.   
  2039.   linepad = (width * 3) % 4;
  2040.   if (linepad) linepad = 4 - linepad;
  2041.  
  2042.   /* Fill in the XWD header (header_size is evaluated by write_xwd_hdr ()) */
  2043.   xwdhdr.l_header_size = 0;
  2044.   xwdhdr.l_file_version = 7;
  2045.   xwdhdr.l_pixmap_format = 2;
  2046.   xwdhdr.l_pixmap_depth = 24;
  2047.   xwdhdr.l_pixmap_width = width;
  2048.   xwdhdr.l_pixmap_height = height;
  2049.   xwdhdr.l_xoffset = 0;
  2050.   xwdhdr.l_byte_order = 1;
  2051.  
  2052.   xwdhdr.l_bitmap_unit = 32;
  2053.   xwdhdr.l_bitmap_bit_order = 1;
  2054.   xwdhdr.l_bitmap_pad = 32;
  2055.   xwdhdr.l_bits_per_pixel = 24;
  2056.  
  2057.   xwdhdr.l_bytes_per_line = width * 3 + linepad;
  2058.   xwdhdr.l_visual_class = 5;
  2059.   xwdhdr.l_red_mask = 0xff0000;
  2060.   xwdhdr.l_green_mask = 0x00ff00;
  2061.   xwdhdr.l_blue_mask = 0x0000ff;
  2062.   xwdhdr.l_bits_per_rgb = 8;
  2063.   xwdhdr.l_colormap_entries = 0;
  2064.   xwdhdr.l_ncolors = 0;
  2065.   xwdhdr.l_window_width = width;
  2066.   xwdhdr.l_window_height = height;
  2067.   xwdhdr.l_window_x = 64;
  2068.   xwdhdr.l_window_y = 64;
  2069.   xwdhdr.l_window_bdrwidth = 0;
  2070.  
  2071.   write_xwd_header (ofp, &xwdhdr);
  2072.  
  2073.   for (i = 0; i < height; i++)
  2074.     {
  2075.       if ((i % tile_height) == 0)   /* Get more data */
  2076.     {int scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i);
  2077.     
  2078.     gimp_pixel_rgn_get_rect (&pixel_rgn, data, 0, i, width, scan_lines);
  2079.     src = data;
  2080.     }
  2081.       fwrite (src, width*3, 1, ofp);
  2082.       if (linepad) fwrite ((char *)&tmp, linepad, 1, ofp);
  2083.       src += width*3;
  2084.       
  2085.       if ((l_run_mode != GIMP_RUN_NONINTERACTIVE) && ((i % 20) == 0))
  2086.     gimp_progress_update ((double) i / (double) height);
  2087.     }
  2088.   g_free (data);
  2089.   
  2090.   gimp_drawable_detach (drawable);
  2091.  
  2092.   if (ferror (ofp))
  2093.     {
  2094.       g_message (_("Error during writing rgb image"));
  2095.       return (FALSE);
  2096.     }
  2097.   return (TRUE);
  2098. }
  2099.