Index: app/core/gimpimage-convert.c
===================================================================
RCS file: /cvs/gnome/gimp/app/core/gimpimage-convert.c,v
retrieving revision 1.180
diff -u -p -u -p -r1.180 gimpimage-convert.c
--- app/core/gimpimage-convert.c	9 Dec 2006 21:28:23 -0000	1.180
+++ app/core/gimpimage-convert.c	29 Dec 2006 08:09:08 -0000
@@ -484,6 +484,7 @@ struct _QuantizeObj
   CFHistogram histogram;            /* holds the histogram               */
 
   gboolean want_alpha_dither;
+  gboolean preserve_mode;     /* AII XXX ignored -- should switch between 'keep-mode' and 'go-to-indexed-mode' */
   int      error_freedom;           /* 0=much bleed, 1=controlled bleed */
 
   GimpProgress *progress;
@@ -762,6 +763,7 @@ gimp_image_convert (GimpImage           
                     /* The following are only used for new_type == GIMP_INDEXED
                      */
                     gint                    num_cols,
+                    /* gint                    preserve_mode,*/ /* AII use this! */
                     GimpConvertDitherType   dither,
                     gboolean                alpha_dither,
                     gboolean                remove_dups,
@@ -774,11 +776,16 @@ gimp_image_convert (GimpImage           
   GList             *list;
   const gchar       *undo_desc = NULL;
   gint               nth_layer, n_layers;
+  gint               preserve_mode = TRUE; /* AII placeholder forceholder */
 
   g_return_if_fail (GIMP_IS_IMAGE (image));
   g_return_if_fail (new_type != gimp_image_base_type (image));
   g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
 
+  /* for now (and probably forever), converting to greyscale cannot preserve mode -- use desaturate instead. RGB is simply meaningless in the context of preserve_mode. */
+  if (new_type != GIMP_INDEXED)
+    preserve_mode = FALSE;
+
   if (palette_type == GIMP_CUSTOM_PALETTE)
     {
       g_return_if_fail (custom_palette == NULL ||
@@ -812,7 +819,11 @@ gimp_image_convert (GimpImage           
       break;
 
     case GIMP_INDEXED:
-      undo_desc = _("Convert Image to Indexed");
+      /* show preserve up in the undo */
+      if (preserve_mode)
+        undo_desc = _("Indexize");
+      else
+        undo_desc = _("Convert Image to Indexed");
       break;
     }
 
@@ -830,7 +841,9 @@ gimp_image_convert (GimpImage           
   /*  Set the new base type  */
   old_type = image->base_type;
 
-  g_object_set (image, "base-type", new_type, NULL);
+  /* AIIII heeeeeres the bug! */
+  if (!preserve_mode)
+    g_object_set (image, "base-type", new_type, NULL);
 
   /* initialize the colour conversion routines */
   cpercep_init ();
@@ -964,7 +977,11 @@ gimp_image_convert (GimpImage           
       GimpImageType  new_layer_type;
       TileManager   *new_tiles;
 
-      new_layer_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_type);
+      /* AIII HACK */
+      if (preserve_mode && new_type == GIMP_INDEXED)
+        new_layer_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (old_type);
+      else
+        new_layer_type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (new_type);
 
       if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
         new_layer_type = GIMP_IMAGE_TYPE_WITH_ALPHA (new_layer_type);
@@ -1011,6 +1028,9 @@ gimp_image_convert (GimpImage           
       break;
 
     case GIMP_INDEXED:
+      /* AIII only need the below machinations if the result is actually indexed. */
+      if (preserve_mode)
+        break;
       gimp_image_undo_push_image_colormap (image, NULL);
 
       image->cmap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
@@ -1086,7 +1106,9 @@ gimp_image_convert (GimpImage           
   gimp_image_undo_group_end (image);
 
   gimp_image_invalidate_layer_previews (image);
-  gimp_image_mode_changed (image);
+  if (!preserve_mode)
+    gimp_image_mode_changed (image);
+
   g_object_thaw_notify (G_OBJECT (image));
 
   gimp_unset_busy (image->gimp);
@@ -2769,14 +2791,20 @@ median_cut_pass2_no_dither_gray (Quantiz
   gint          row, col;
   gint          pixel;
   gint          has_alpha;
+  gint          dest_alpha_pix = ALPHA_G_PIX;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
   gulong       *index_used_count = quantobj->index_used_count;
+  Color        *cmap             = quantobj->cmap; /* AIII */
   gboolean      alpha_dither     = quantobj->want_alpha_dither;
   gint          offsetx, offsety;
+  gint          index;
   gpointer      pr;
 
   gimp_item_offsets (GIMP_ITEM (layer), &offsetx, &offsety);
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (! preserve_mode)
+      dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -2828,18 +2856,32 @@ median_cut_pass2_no_dither_gray (Quantiz
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
-                      index_used_count[dest[INDEXED_PIX] = *cachep - 1]++;
+                      dest[dest_alpha_pix] = 255;
+                      if (preserve_mode)
+                        {
+                          index = *cachep - 1;
+                          dest[GRAY_PIX] = cmap[index].red;
+                          index_used_count[index]++;
+                        }
+                      else
+                        index_used_count[dest[INDEXED_PIX] = *cachep - 1]++;
                     }
                 }
               else
                 {
                   /* Now emit the colormap index for this cell */
-                  index_used_count[dest[INDEXED_PIX] = *cachep - 1]++;
+                  if (preserve_mode)
+                    {
+                      index = *cachep - 1;
+                      dest[GRAY_PIX] = cmap[index].red;
+                      index_used_count[index]++;
+                    }
+                  else
+                    index_used_count[dest[INDEXED_PIX] = *cachep - 1]++;
                 }
 
               src += srcPR.bytes;
@@ -2865,7 +2907,10 @@ median_cut_pass2_fixed_dither_gray (Quan
   guchar       *dest;
   gint          row, col;
   gint          pixel;
+  gint          dest_alpha_pix = ALPHA_G_PIX;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
   gulong       *index_used_count = quantobj->index_used_count;
+  Color        *cmap             = quantobj->cmap; /* AIII */
   gboolean      has_alpha;
   gboolean      alpha_dither     = quantobj->want_alpha_dither;
   gint          offsetx, offsety;
@@ -2874,6 +2919,8 @@ median_cut_pass2_fixed_dither_gray (Quan
   gimp_item_offsets (GIMP_ITEM (layer), &offsetx, &offsety);
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (! preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -2974,18 +3021,30 @@ median_cut_pass2_fixed_dither_gray (Quan
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
-                      index_used_count[dest[INDEXED_PIX] = pixval1]++;
+                      dest[dest_alpha_pix] = 255;
+                      if (preserve_mode)
+                        {
+                          dest[GRAY_PIX] = cmap[pixval1].red;
+                          index_used_count[pixval1]++;
+                        }
+                      else
+                        index_used_count[dest[INDEXED_PIX] = pixval1]++;
                     }
                 }
               else
                 {
                   /* Now emit the colormap index for this cell, barfbarf */
-                  index_used_count[dest[INDEXED_PIX] = pixval1]++;
+                  if (preserve_mode)
+                    {
+                      dest[GRAY_PIX] = cmap[pixval1].red;
+                      index_used_count[pixval1]++;
+                    }
+                  else
+                    index_used_count[dest[INDEXED_PIX] = pixval1]++;
                 }
 
               src += srcPR.bytes;
@@ -3013,13 +3072,17 @@ median_cut_pass2_no_dither_rgb (Quantize
   gint          green_pix        = GREEN_PIX;
   gint          blue_pix         = BLUE_PIX;
   gint          alpha_pix        = ALPHA_PIX;
+  gint          dest_alpha_pix   = ALPHA_PIX;
   gboolean      alpha_dither     = quantobj->want_alpha_dither;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
   gint          offsetx, offsety;
   gulong       *index_used_count = quantobj->index_used_count;
+  Color        *cmap             = quantobj->cmap; /* AIII */
   glong         total_size       = 0;
   glong         layer_size;
   gint          nth_layer        = quantobj->nth_layer;
   gint          n_layers         = quantobj->n_layers;
+  gint          index;
 
   gimp_item_offsets (GIMP_ITEM (layer), &offsetx, &offsety);
 
@@ -3033,6 +3096,8 @@ median_cut_pass2_no_dither_rgb (Quantize
     }
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (! preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -3079,12 +3144,12 @@ median_cut_pass2_no_dither_rgb (Quantize
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                       goto next_pixel;
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
+                      dest[dest_alpha_pix] = 255;
                     }
                 }
 
@@ -3098,7 +3163,16 @@ median_cut_pass2_no_dither_rgb (Quantize
                 fill_inverse_cmap_rgb (quantobj, histogram, R, G, B);
 
               /* Now emit the colormap index for this cell, barfbarf */
-              index_used_count[dest[INDEXED_PIX] = *cachep - 1]++;
+              if (preserve_mode)
+                {
+                  index = *cachep - 1;
+                  dest[red_pix] = cmap[index].red;
+                  dest[green_pix] = cmap[index].green;
+                  dest[blue_pix] = cmap[index].blue;
+                  index_used_count[index]++;
+                }
+              else
+                index_used_count[dest[INDEXED_PIX] = *cachep - 1]++;
 
             next_pixel:
 
@@ -3136,9 +3210,12 @@ median_cut_pass2_fixed_dither_rgb (Quant
   gint          green_pix        = GREEN_PIX;
   gint          blue_pix         = BLUE_PIX;
   gint          alpha_pix        = ALPHA_PIX;
+  gint          dest_alpha_pix   = ALPHA_PIX;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
   gboolean      alpha_dither     = quantobj->want_alpha_dither;
   gint          offsetx, offsety;
   gulong       *index_used_count = quantobj->index_used_count;
+  Color        *cmap             = quantobj->cmap; /* AIII */
   glong         total_size       = 0;
   glong         layer_size;
   gint          nth_layer        = quantobj->nth_layer;
@@ -3156,6 +3233,8 @@ median_cut_pass2_fixed_dither_rgb (Quant
     }
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (! preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -3204,12 +3283,12 @@ median_cut_pass2_fixed_dither_rgb (Quant
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                       goto next_pixel;
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
+                      dest[dest_alpha_pix] = 255;
                     }
                 }
 
@@ -3230,7 +3309,7 @@ median_cut_pass2_fixed_dither_rgb (Quant
                  colours from the intended colour to determine their relative
                  probabilities of being chosen. */
               pixval1 = *cachep - 1;
-              color1 = &quantobj->cmap[pixval1];
+              color1 = &cmap[pixval1];
 
               if (quantobj->actual_number_of_colors > 2) {
                 const int re = src[red_pix] - (int)color1->red;
@@ -3275,7 +3354,7 @@ median_cut_pass2_fixed_dither_rgb (Quant
                 color1 = &quantobj->cmap[pixval1];
               }
 
-              color2 = &quantobj->cmap[pixval2];
+              color2 = &cmap[pixval2];
 
               /* now figure out the relative probabilites of choosing
                  either of our candidates. */
@@ -3307,7 +3386,15 @@ median_cut_pass2_fixed_dither_rgb (Quant
               }
 
               /* Now emit the colormap index for this cell, barfbarf */
-              index_used_count[dest[INDEXED_PIX] = pixval1]++;
+              if (preserve_mode)
+                {         
+                  dest[red_pix] = cmap[pixval1].red;
+                  dest[green_pix] = cmap[pixval1].green;
+                  dest[blue_pix] = cmap[pixval1].blue;
+                  index_used_count[pixval1]++;
+                }
+              else
+                index_used_count[dest[INDEXED_PIX] = pixval1]++;
 
             next_pixel:
 
@@ -3339,6 +3426,9 @@ median_cut_pass2_nodestruct_dither_rgb (
   gint          green_pix = GREEN_PIX;
   gint          blue_pix = BLUE_PIX;
   gint          alpha_pix = ALPHA_PIX;
+  gint          dest_alpha_pix = ALPHA_PIX;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
+  Color        *cmap          = quantobj->cmap; /* AIII */
   gint          i;
   gint          lastindex = 0;
   gint          lastred = -1;
@@ -3349,6 +3439,8 @@ median_cut_pass2_nodestruct_dither_rgb (
   gimp_item_offsets (GIMP_ITEM (layer), &offsetx, &offsety);
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (!preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -3360,6 +3452,9 @@ median_cut_pass2_nodestruct_dither_rgb (
                      GIMP_ITEM (layer)->height,
                      TRUE);
 
+  if (! preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
+
   for (pr = pixel_regions_register (2, &srcPR, &destPR);
        pr != NULL;
        pr = pixel_regions_process (pr))
@@ -3397,9 +3492,16 @@ median_cut_pass2_nodestruct_dither_rgb (
                       (lastblue == src[blue_pix]))
                     {
                       /*  same pixel colour as last time  */
-                      dest[INDEXED_PIX] = lastindex;
+                      if (preserve_mode)
+                        {
+                          dest[red_pix] = cmap[lastindex].red;
+                          dest[green_pix] = cmap[lastindex].green;
+                          dest[blue_pix] = cmap[lastindex].blue;
+                        }
+                      else
+                        dest[INDEXED_PIX] = lastindex;
                       if (has_alpha)
-                        dest[ALPHA_I_PIX] = 255;
+                        dest[dest_alpha_pix] = 255;
                     }
                   else
                     {
@@ -3423,14 +3525,21 @@ median_cut_pass2_nodestruct_dither_rgb (
                       g_error ("Non-existant colour was expected to "
                                "be in non-destructive colourmap.");
                     got_colour:
-                      dest[INDEXED_PIX] = lastindex;
+                      if (preserve_mode)
+                        {
+                          dest[red_pix] = cmap[lastindex].red;
+                          dest[green_pix] = cmap[lastindex].green;
+                          dest[blue_pix] = cmap[lastindex].blue;
+                        }
+                      else
+                        dest[INDEXED_PIX] = lastindex;
                       if (has_alpha)
-                        dest[ALPHA_I_PIX] = 255;
+                        dest[dest_alpha_pix] = 255;
                     }
                 }
               else
                 { /*  have alpha, and transparent  */
-                  dest[ALPHA_I_PIX] = 0;
+                  dest[dest_alpha_pix] = 0;
                 }
 
               src += srcPR.bytes;
@@ -3554,14 +3663,19 @@ median_cut_pass2_fs_dither_gray (Quantiz
   gint          step_dest, step_src;
   gint          odd_row;
   gboolean      has_alpha;
+  gint          dest_alpha_pix = ALPHA_G_PIX;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
   gint          offsetx, offsety;
   gboolean      alpha_dither = quantobj->want_alpha_dither;
   gint          width, height;
   gulong       *index_used_count = quantobj->index_used_count;
+  Color        *cmap             = quantobj->cmap; /* AIII */
 
   gimp_item_offsets (GIMP_ITEM (layer), &offsetx, &offsety);
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (! preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -3660,7 +3774,7 @@ median_cut_pass2_fs_dither_gray (Quantiz
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                       pr--;
                       nr--;
                       *(nr - 1) = 0;
@@ -3668,7 +3782,7 @@ median_cut_pass2_fs_dither_gray (Quantiz
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
+                      dest[dest_alpha_pix] = 255;
                     }
                 }
               else
@@ -3689,7 +3803,7 @@ median_cut_pass2_fs_dither_gray (Quantiz
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                       pr++;
                       nr++;
                       *(nr + 1) = 0;
@@ -3697,15 +3811,21 @@ median_cut_pass2_fs_dither_gray (Quantiz
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
+                      dest[dest_alpha_pix] = 255;
                     }
                 }
             }
 
           index = *cachep - 1;
-          index_used_count[dest[INDEXED_PIX] = index]++;
+          if (preserve_mode)
+            {
+              index_used_count[index]++;
+              dest[GRAY_PIX] = cmap[index].red;
+            }
+          else
+            index_used_count[dest[INDEXED_PIX] = index]++;
 
-          color = &quantobj->cmap[index];
+          color = &cmap[index];
           pixele = pixel - color->red;
 
           if (odd_row)
@@ -3811,9 +3931,12 @@ median_cut_pass2_fs_dither_rgb (Quantize
   gint          green_pix = GREEN_PIX;
   gint          blue_pix  = BLUE_PIX;
   gint          alpha_pix = ALPHA_PIX;
+  gint          dest_alpha_pix = ALPHA_PIX;
+  gint          preserve_mode = quantobj->preserve_mode; /* AIII readthis from quantobj */
   gint          offsetx, offsety;
   gboolean      alpha_dither     = quantobj->want_alpha_dither;
   gulong       *index_used_count = quantobj->index_used_count;
+  Color        *cmap             = quantobj->cmap; /* AIII */
   gint          global_rmax = 0, global_rmin = G_MAXINT;
   gint          global_gmax = 0, global_gmin = G_MAXINT;
   gint          global_bmax = 0, global_bmin = G_MAXINT;
@@ -3829,6 +3952,8 @@ median_cut_pass2_fs_dither_rgb (Quantize
     red_pix = green_pix = blue_pix = GRAY_PIX;
 
   has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
+  if (! preserve_mode)
+    dest_alpha_pix = ALPHA_I_PIX;
 
   pixel_region_init (&srcPR, GIMP_DRAWABLE (layer)->tiles,
                      0, 0,
@@ -3846,7 +3971,7 @@ median_cut_pass2_fs_dither_rgb (Quantize
   height     = GIMP_ITEM (layer)->height;
 
   error_limiter = init_error_limit (quantobj->error_freedom);
-  range_limiter = range_array + 256;
+  range_limiter = range_array + 256; /* AII this is unrelated to palette size.*/
 
   /* find the bounding box of the palette colours --
      we use this for hard-clamping our error-corrected
@@ -3947,7 +4072,7 @@ median_cut_pass2_fs_dither_rgb (Quantize
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                       rpr--; gpr--; bpr--;
                       rnr--; gnr--; bnr--;
                       *(rnr - 1) = *(gnr - 1) = *(bnr - 1) = 0;
@@ -3955,7 +4080,7 @@ median_cut_pass2_fs_dither_rgb (Quantize
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
+                      dest[dest_alpha_pix] = 255;
                     }
                 }
               else
@@ -3976,7 +4101,7 @@ median_cut_pass2_fs_dither_rgb (Quantize
 
                   if (transparent)
                     {
-                      dest[ALPHA_I_PIX] = 0;
+                      dest[dest_alpha_pix] = 0;
                       rpr++; gpr++; bpr++;
                       rnr++; gnr++; bnr++;
                       *(rnr + 1) = *(gnr + 1) = *(bnr + 1) = 0;
@@ -3984,7 +4109,7 @@ median_cut_pass2_fs_dither_rgb (Quantize
                     }
                   else
                     {
-                      dest[ALPHA_I_PIX] = 255;
+                      dest[dest_alpha_pix] = 255;
                     }
                 }
             }
@@ -4028,7 +4153,16 @@ median_cut_pass2_fs_dither_rgb (Quantize
 
           index = *cachep - 1;
           index_used_count[index]++;
-          dest[INDEXED_PIX] = index;
+          /* AIII here index[] should go through a LUT to map it to real color */
+          /* AIIII done. */
+          if (preserve_mode)
+            {
+              dest[red_pix] = cmap[index].red;
+              dest[green_pix] = cmap[index].green;
+              dest[blue_pix] = cmap[index].blue;
+            }
+          else
+            dest[INDEXED_PIX] = index;
 
           /*if (re > global_rmax)
             re = (re + 3*global_rmax) / 4;
@@ -4213,6 +4347,7 @@ initialize_median_cut (GimpImageBaseType
   quantobj->desired_number_of_colors = num_colors;
   quantobj->want_alpha_dither        = want_alpha_dither;
   quantobj->progress                 = progress;
+  quantobj->preserve_mode = TRUE; /* AIII HARDCODED */
 
   switch (type)
     {
