Re: [Gimp-developer] gimp & multipage tiff



On Fri, Dec 07, 2012 at 11:07:33AM +0100, scl wrote:
> Hi,
> 
> it seems we already have a patch:
> https://bugzilla.gnome.org/show_bug.cgi?id=335975
> It only needs to be tested and integrated.

  Wow! This is great! Thanks a lot.
  I've adopted this patch to gimp 2.6 from debian squeeze source package. May
be this is useful for anybody.
  Why this patch is not in the mainstream yet?

P.S. Forgot the patch
--- gimp-2.6.10.old/plug-ins/common/file-tiff-save.c	2010-07-03 02:51:56.000000000 +0400
+++ gimp-2.6.10/plug-ins/common/file-tiff-save.c.2	2012-12-07 16:12:21.000000000 +0400
@@ -75,12 +75,16 @@
 #define SAVE2_PROC     "file-tiff-save2"
 #define PLUG_IN_BINARY "file-tiff-save"
 
+#define LAYER_MODE_MERGE   0
+#define LAYER_MODE_COMBINE 1
+#define LAYER_MODE_PAGES   2
 
 typedef struct
 {
   gint      compression;
   gint      fillorder;
   gboolean  save_transp_pixels;
+  gshort    layer_mode;
 } TiffSaveVals;
 
 typedef struct
@@ -254,7 +258,8 @@
                                       (GIMP_EXPORT_CAN_HANDLE_RGB |
                                        GIMP_EXPORT_CAN_HANDLE_GRAY |
                                        GIMP_EXPORT_CAN_HANDLE_INDEXED |
-                                       GIMP_EXPORT_CAN_HANDLE_ALPHA ));
+                                       GIMP_EXPORT_CAN_HANDLE_ALPHA |
+                                       GIMP_EXPORT_CAN_HANDLE_LAYERS ));
           if (export == GIMP_EXPORT_CANCEL)
             {
               values[0].data.d_status = GIMP_PDB_CANCEL;
@@ -286,6 +291,7 @@
 
               tsvals.compression        = pvals->compression;
               tsvals.save_transp_pixels = pvals->save_transp_pixels;
+              tsvals.layer_mode = pvals->layer_mode;
             }
           gimp_parasite_free (parasite);
 
@@ -333,6 +339,7 @@
 
               tsvals.compression        = pvals->compression;
               tsvals.save_transp_pixels = pvals->save_transp_pixels;
+              tsvals.layer_mode = pvals->layer_mode;
             }
           gimp_parasite_free (parasite);
           break;
@@ -643,25 +650,28 @@
   gushort        extra_samples[1];
   gboolean       alpha;
   gshort         predictor;
-  gshort         photometric;
+  gshort         photometric = 0;
   gshort         samplesperpixel;
   gshort         bitspersample;
   gint           bytesperrow;
-  guchar        *t, *src, *data;
+  guchar        *t, *src, *data = NULL;
   guchar        *cmap;
-  gint           colors;
+  gint           num_colors;
   gint           success;
-  GimpDrawable  *drawable;
+  GimpDrawable  *drawable = NULL;
   GimpImageType  drawable_type;
   GimpPixelRgn   pixel_rgn;
   gint           tile_height;
   gint           y, yend;
-  gint           fd;
   gboolean       is_bw    = FALSE;
   gboolean       invert   = TRUE;
   const guchar   bw_map[] = { 0, 0, 0, 255, 255, 255 };
   const guchar   wb_map[] = { 255, 255, 255, 0, 0, 0 };
 
+  gint32	*layers;
+  gint		nlayers;
+  gint		layerIndex;
+
   compression = tsvals.compression;
 
   /* Disabled because this isn't in older releases of libtiff, and it
@@ -675,17 +685,7 @@
   tile_height = gimp_tile_height ();
   rowsperstrip = tile_height;
 
-  fd = g_open (filename, O_CREAT | O_TRUNC | O_WRONLY | _O_BINARY, 0644);
-
-  if (fd == -1)
-    {
-      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                   _("Could not open '%s' for writing: %s"),
-                   gimp_filename_to_utf8 (filename), g_strerror (errno));
-      return FALSE;
-    }
-
-  tif = TIFFFdOpen (fd, filename, "w");
+  tif = TIFFOpen(filename, "w");
 
   TIFFSetWarningHandler (tiff_warning);
   TIFFSetErrorHandler (tiff_error);
@@ -693,187 +693,6 @@
   gimp_progress_init_printf (_("Saving '%s'"),
                              gimp_filename_to_utf8 (filename));
 
-  drawable = gimp_drawable_get (layer);
-  drawable_type = gimp_drawable_type (layer);
-  gimp_pixel_rgn_init (&pixel_rgn, drawable,
-                       0, 0, drawable->width, drawable->height, FALSE, FALSE);
-
-  cols = drawable->width;
-  rows = drawable->height;
-
-  gimp_tile_cache_ntiles (1 + drawable->width / gimp_tile_width ());
-
-  switch (drawable_type)
-    {
-    case GIMP_RGB_IMAGE:
-      predictor       = 2;
-      samplesperpixel = 3;
-      bitspersample   = 8;
-      photometric     = PHOTOMETRIC_RGB;
-      bytesperrow     = cols * 3;
-      alpha           = FALSE;
-      break;
-
-    case GIMP_GRAY_IMAGE:
-      samplesperpixel = 1;
-      bitspersample   = 8;
-      photometric     = PHOTOMETRIC_MINISBLACK;
-      bytesperrow     = cols;
-      alpha           = FALSE;
-      break;
-
-    case GIMP_RGBA_IMAGE:
-      predictor       = 2;
-      samplesperpixel = 4;
-      bitspersample   = 8;
-      photometric     = PHOTOMETRIC_RGB;
-      bytesperrow     = cols * 4;
-      alpha           = TRUE;
-      break;
-
-    case GIMP_GRAYA_IMAGE:
-      samplesperpixel = 2;
-      bitspersample   = 8;
-      photometric     = PHOTOMETRIC_MINISBLACK;
-      bytesperrow     = cols * 2;
-      alpha           = TRUE;
-      break;
-
-    case GIMP_INDEXED_IMAGE:
-      cmap = gimp_image_get_colormap (image, &colors);
-
-      if (colors == 2)
-        {
-          is_bw = (memcmp (cmap, bw_map, 6) == 0);
-          photometric = PHOTOMETRIC_MINISWHITE;
-
-          if (!is_bw)
-            {
-              is_bw = (memcmp (cmap, wb_map, 6) == 0);
-
-              if (is_bw)
-                invert = FALSE;
-            }
-       }
-
-      if (is_bw)
-        {
-          bitspersample = 1;
-        }
-      else
-        {
-          bitspersample = 8;
-          photometric   = PHOTOMETRIC_PALETTE;
-
-          for (i = 0; i < colors; i++)
-            {
-              red[i] = cmap[i * 3 + 0] * 65535 / 255;
-              grn[i] = cmap[i * 3 + 1] * 65535 / 255;
-              blu[i] = cmap[i * 3 + 2] * 65535 / 255;
-            }
-       }
-
-      samplesperpixel = 1;
-      bytesperrow     = cols;
-      alpha           = FALSE;
-
-      g_free (cmap);
-      break;
-
-    case GIMP_INDEXEDA_IMAGE:
-      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
-                   "%s",
-                   "TIFF save cannot handle indexed images with alpha channel.");
-    default:
-      return FALSE;
-    }
-
-  if (compression == COMPRESSION_CCITTFAX3 ||
-      compression == COMPRESSION_CCITTFAX4)
-    {
-      if (bitspersample != 1 || samplesperpixel != 1)
-        {
-          g_message ("Only monochrome pictures can be compressed with \"CCITT Group 4\" or \"CCITT Group 3\".");
-          return FALSE;
-        }
-    }
-
-  /* Set TIFF parameters. */
-  TIFFSetField (tif, TIFFTAG_SUBFILETYPE, 0);
-  TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, cols);
-  TIFFSetField (tif, TIFFTAG_IMAGELENGTH, rows);
-  TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
-  TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
-  TIFFSetField (tif, TIFFTAG_COMPRESSION, compression);
-
-  if ((compression == COMPRESSION_LZW || compression == COMPRESSION_DEFLATE)
-      && (predictor != 0))
-    {
-      TIFFSetField (tif, TIFFTAG_PREDICTOR, predictor);
-    }
-
-  if (alpha)
-    {
-      if (tsvals.save_transp_pixels)
-        extra_samples [0] = EXTRASAMPLE_UNASSALPHA;
-      else
-        extra_samples [0] = EXTRASAMPLE_ASSOCALPHA;
-
-      TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
-    }
-
-  TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, photometric);
-  TIFFSetField (tif, TIFFTAG_DOCUMENTNAME, filename);
-  TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
-  TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
-  /* TIFFSetField( tif, TIFFTAG_STRIPBYTECOUNTS, rows / rowsperstrip ); */
-  TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-
-  /* resolution fields */
-  {
-    gdouble  xresolution;
-    gdouble  yresolution;
-    gushort  save_unit = RESUNIT_INCH;
-    GimpUnit unit;
-    gfloat   factor;
-
-    gimp_image_get_resolution (orig_image, &xresolution, &yresolution);
-    unit = gimp_image_get_unit (orig_image);
-    factor = gimp_unit_get_factor (unit);
-
-    /*  if we have a metric unit, save the resolution as centimeters
-     */
-    if ((ABS (factor - 0.0254) < 1e-5) ||  /* m  */
-        (ABS (factor - 0.254) < 1e-5) ||   /* dm */
-        (ABS (factor - 2.54) < 1e-5) ||    /* cm */
-        (ABS (factor - 25.4) < 1e-5))      /* mm */
-      {
-        save_unit = RESUNIT_CENTIMETER;
-        xresolution /= 2.54;
-        yresolution /= 2.54;
-      }
-
-    if (xresolution > 1e-5 && yresolution > 1e-5)
-      {
-        TIFFSetField (tif, TIFFTAG_XRESOLUTION, xresolution);
-        TIFFSetField (tif, TIFFTAG_YRESOLUTION, yresolution);
-        TIFFSetField (tif, TIFFTAG_RESOLUTIONUNIT, save_unit);
-      }
-
-/* TODO: enable in 2.6
-
-    gint     offset_x, offset_y;
-
-    gimp_drawable_offsets (layer, &offset_x, &offset_y);
-
-    if (offset_x || offset_y)
-      {
-        TIFFSetField (tif, TIFFTAG_XPOSITION, offset_x / xresolution);
-        TIFFSetField (tif, TIFFTAG_YPOSITION, offset_y / yresolution);
-      }
-*/
-  }
-
   /* The TIFF spec explicitely says ASCII for the image description. */
   if (image_comment)
     {
@@ -932,114 +751,332 @@
   /* save path data */
   save_paths (tif, orig_image);
 
-  if (!is_bw && drawable_type == GIMP_INDEXED_IMAGE)
-    TIFFSetField (tif, TIFFTAG_COLORMAP, red, grn, blu);
-
-  /* array to rearrange data */
-  src = g_new (guchar, bytesperrow * tile_height);
-  data = g_new (guchar, bytesperrow);
-
-  /* Now write the TIFF data. */
-  for (y = 0; y < rows; y = yend)
+  if (tsvals.layer_mode == LAYER_MODE_PAGES)
     {
-      yend = y + tile_height;
-      yend = MIN (yend, rows);
-
-      gimp_pixel_rgn_get_rect (&pixel_rgn, src, 0, y, cols, yend - y);
-
-      for (row = y; row < yend; row++)
+      layers = gimp_image_get_layers (image, &nlayers);
+    }
+  else 
+    {
+      nlayers = 1;
+      layers = NULL;
+      if (image == orig_image)
+        image = gimp_image_duplicate(image);
+        
+      if (tsvals.layer_mode == LAYER_MODE_MERGE)
         {
-          t = src + bytesperrow * (row - y);
-
-          switch (drawable_type)
-            {
-            case GIMP_INDEXED_IMAGE:
-              if (is_bw)
-                {
-                  byte2bit (t, bytesperrow, data, invert);
-                  success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
-                }
-              else
-                {
-                  success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
-                }
-              break;
-
-            case GIMP_GRAY_IMAGE:
-              success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
-              break;
+          layer = gimp_image_merge_visible_layers (image, GIMP_CLIP_TO_IMAGE);
+        }
+      else
+        {
+          layer = gimp_image_flatten (image);
+        }
+    }
 
-            case GIMP_GRAYA_IMAGE:
-              for (col = 0; col < cols*samplesperpixel; col+=samplesperpixel)
-                {
-                  if (tsvals.save_transp_pixels)
-                    {
-                      data[col + 0] = t[col + 0];
-                    }
-                  else
-                    {
-                      /* pre-multiply gray by alpha */
-                      data[col + 0] = (t[col + 0] * t[col + 1]) / 255;
-                    }
+  for (layerIndex = nlayers-1; layerIndex >= 0; layerIndex--){
+    if(nlayers > 1)
+      {
+        drawable = gimp_drawable_get (layers[layerIndex]);
+        drawable_type = gimp_drawable_type (layers[layerIndex]);
+      }
+    else
+      {
+        drawable = gimp_drawable_get (layer);
+        drawable_type = gimp_drawable_type (layer);
+      }
+  
+    gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
 
-                  data[col + 1] = t[col + 1];  /* alpha channel */
-                }
+    cols = drawable->width;
+    rows = drawable->height;
 
-              success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
-              break;
+    gimp_tile_cache_ntiles (1 + drawable->width / gimp_tile_width ());
 
-            case GIMP_RGB_IMAGE:
-              success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
-              break;
+    switch (drawable_type)
+      {
+      case GIMP_RGB_IMAGE:
+        predictor       = 2;
+        samplesperpixel = 3;
+        bitspersample   = 8;
+        photometric     = PHOTOMETRIC_RGB;
+        bytesperrow     = cols * 3;
+        alpha           = FALSE;
+        break;
+  
+      case GIMP_GRAY_IMAGE:
+        samplesperpixel = 1;
+        bitspersample   = 8;
+        photometric     = PHOTOMETRIC_MINISBLACK;
+        bytesperrow     = cols;
+        alpha           = FALSE;
+        break;
+  
+      case GIMP_RGBA_IMAGE:
+        predictor       = 2;
+        samplesperpixel = 4;
+        bitspersample   = 8;
+        photometric     = PHOTOMETRIC_RGB;
+        bytesperrow     = cols * 4;
+        alpha           = TRUE;
+        break;
+  
+      case GIMP_GRAYA_IMAGE:
+        samplesperpixel = 2;
+        bitspersample   = 8;
+        photometric     = PHOTOMETRIC_MINISBLACK;
+        bytesperrow     = cols * 2;
+        alpha           = TRUE;
+        break;
+  
+      case GIMP_INDEXED_IMAGE:
+        cmap = gimp_image_get_colormap (image, &num_colors);
+  
+        if (num_colors == 2 || num_colors == 1)
+          {
+            is_bw = (memcmp (cmap, bw_map, 3 * num_colors) == 0);
+            photometric = PHOTOMETRIC_MINISWHITE;
+  
+            if (!is_bw)
+              {
+                is_bw = (memcmp (cmap, wb_map, 3 * num_colors) == 0);
+  
+                if (is_bw)
+                  invert = FALSE;
+              }
+         }
+  
+        if (is_bw)
+          {
+            bitspersample = 1;
+          }
+        else
+          {
+            bitspersample = 8;
+            photometric   = PHOTOMETRIC_PALETTE;
+  
+            for (i = 0; i < num_colors; i++)
+              {
+                red[i] = cmap[i * 3 + 0] * 65535 / 255;
+                grn[i] = cmap[i * 3 + 1] * 65535 / 255;
+                blu[i] = cmap[i * 3 + 2] * 65535 / 255;
+              }
+         }
+  
+        samplesperpixel = 1;
+        bytesperrow     = cols;
+        alpha           = FALSE;
+  
+        g_free (cmap);
+        break;
+  
+      case GIMP_INDEXEDA_IMAGE:
+        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                     "%s",
+                     "TIFF save cannot handle indexed images with alpha channel.");
+      default:
+        return FALSE;
+      }
+  
+    if (compression == COMPRESSION_CCITTFAX3 ||
+        compression == COMPRESSION_CCITTFAX4)
+      {
+        if (bitspersample != 1 || samplesperpixel != 1)
+          {
+            g_message ("Only monochrome pictures can be compressed with \"CCITT Group 4\" or \"CCITT Group 3\".");
+            return FALSE;
+          }
+      }
 
-            case GIMP_RGBA_IMAGE:
-              for (col = 0; col < cols*samplesperpixel; col+=samplesperpixel)
-                {
-                  if (tsvals.save_transp_pixels)
-                    {
-                      data[col+0] = t[col + 0];
-                      data[col+1] = t[col + 1];
-                      data[col+2] = t[col + 2];
-                    }
-                  else
-                    {
-                      /* pre-multiply rgb by alpha */
-                      data[col+0] = t[col + 0] * t[col + 3] / 255;
-                      data[col+1] = t[col + 1] * t[col + 3] / 255;
-                      data[col+2] = t[col + 2] * t[col + 3] / 255;
-                    }
+    
+    /* Set TIFF parameters. */
+    TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, cols);
+    TIFFSetField (tif, TIFFTAG_IMAGELENGTH, rows);
+    TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
+    TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+    TIFFSetField (tif, TIFFTAG_COMPRESSION, compression);
 
-                  data[col+3] = t[col + 3];  /* alpha channel */
-                }
+    if ((compression == COMPRESSION_LZW || compression == COMPRESSION_DEFLATE)
+        && (predictor != 0))
+      {
+        TIFFSetField (tif, TIFFTAG_PREDICTOR, predictor);
+      }
+  
+    if (alpha)
+      {
+        if (tsvals.save_transp_pixels)
+          extra_samples [0] = EXTRASAMPLE_UNASSALPHA;
+        else
+          extra_samples [0] = EXTRASAMPLE_ASSOCALPHA;
+  
+        TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
+      }
+  
+    TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, photometric);
+    TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+    TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+    /* TIFFSetField( tif, TIFFTAG_STRIPBYTECOUNTS, rows / rowsperstrip ); */
+    TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+
+    if (!is_bw && drawable_type == GIMP_INDEXED_IMAGE)
+      TIFFSetField (tif, TIFFTAG_COLORMAP, red, grn, blu);
+  
 
-              success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
-              break;
+    /* resolution fields */
+    {
+      gdouble  xresolution;
+      gdouble  yresolution;
+      gushort  save_unit = RESUNIT_INCH;
+      GimpUnit unit;
+      gfloat   factor;
+  
+      gimp_image_get_resolution (orig_image, &xresolution, &yresolution);
+      unit = gimp_image_get_unit (orig_image);
+      factor = gimp_unit_get_factor (unit);
+  
+      /*  if we have a metric unit, save the resolution as centimeters
+       */
+      if ((ABS (factor - 0.0254) < 1e-5) ||  /* m  */
+          (ABS (factor - 0.254) < 1e-5) ||   /* dm */
+          (ABS (factor - 2.54) < 1e-5) ||    /* cm */
+          (ABS (factor - 25.4) < 1e-5))      /* mm */
+        {
+          save_unit = RESUNIT_CENTIMETER;
+          xresolution /= 2.54;
+          yresolution /= 2.54;
+        }
+  
+      if (xresolution > 1e-5 && yresolution > 1e-5)
+        {
+          TIFFSetField (tif, TIFFTAG_XRESOLUTION, xresolution);
+          TIFFSetField (tif, TIFFTAG_YRESOLUTION, yresolution);
+          TIFFSetField (tif, TIFFTAG_RESOLUTIONUNIT, save_unit);
+        }
+  
+  /* TODO: enable in 2.6
+  
+      gint     offset_x, offset_y;
+  
+      gimp_drawable_offsets (layer, &offset_x, &offset_y);
+  
+      if (offset_x || offset_y)
+        {
+          TIFFSetField (tif, TIFFTAG_XPOSITION, offset_x / xresolution);
+          TIFFSetField (tif, TIFFTAG_YPOSITION, offset_y / yresolution);
+        }
+  */
+    }
+  
+    /* array to rearrange data */
+    src = g_new (guchar, bytesperrow * tile_height);
+    data = g_new (guchar, bytesperrow);
+  
+    /* Now write the TIFF data. */    
+    gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
 
-            default:
-              success = FALSE;
-              break;
-            }
+    TIFFSetField (tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
+    TIFFSetField (tif, TIFFTAG_PAGENUMBER, nlayers-layerIndex-1, nlayers);
 
-          if (!success)
-            {
-              g_message ("Failed a scanline write on row %d", row);
-              return FALSE;
-            }
-        }
+    for (y = 0; y < rows; y = yend)
+      {
+        yend = y + tile_height;
+        yend = MIN (yend, rows);
+  
+        gimp_pixel_rgn_get_rect (&pixel_rgn, src, 0, y, cols, yend - y);
+  
+        for (row = y; row < yend; row++)
+          {
+            t = src + bytesperrow * (row - y);
+  
+            switch (drawable_type)
+              {
+              case GIMP_INDEXED_IMAGE:
+                if (is_bw)
+                  {
+                    byte2bit (t, bytesperrow, data, invert);
+                    success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
+                  }
+                else
+                  {
+                    success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
+                  }
+                break;
+  
+              case GIMP_GRAY_IMAGE:
+                success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
+                break;
+  
+              case GIMP_GRAYA_IMAGE:
+                for (col = 0; col < cols*samplesperpixel; col+=samplesperpixel)
+                  {
+                    if (tsvals.save_transp_pixels)
+                      {
+                        data[col + 0] = t[col + 0];
+                      }
+                    else
+                      {
+                        /* pre-multiply gray by alpha */
+                        data[col + 0] = (t[col + 0] * t[col + 1]) / 255;
+                      }
+  
+                    data[col + 1] = t[col + 1];  /* alpha channel */
+                  }
+  
+                success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
+                break;
+  
+              case GIMP_RGB_IMAGE:
+                success = (TIFFWriteScanline (tif, t, row, 0) >= 0);
+                break;
+  
+              case GIMP_RGBA_IMAGE:
+                for (col = 0; col < cols*samplesperpixel; col+=samplesperpixel)
+                  {
+                    if (tsvals.save_transp_pixels)
+                      {
+                        data[col+0] = t[col + 0];
+                        data[col+1] = t[col + 1];
+                        data[col+2] = t[col + 2];
+                      }
+                    else
+                      {
+                        /* pre-multiply rgb by alpha */
+                        data[col+0] = t[col + 0] * t[col + 3] / 255;
+                        data[col+1] = t[col + 1] * t[col + 3] / 255;
+                        data[col+2] = t[col + 2] * t[col + 3] / 255;
+                      }
+  
+                    data[col+3] = t[col + 3];  /* alpha channel */
+                  }
+                success = (TIFFWriteScanline (tif, data, row, 0) >= 0);
+                break;
+  
+              default:
+                success = FALSE;
+                break;
+              }
+  
+            if (!success)
+              {
+                g_message ("Failed a scanline write on row %d", row);
+                g_free (layers);
+                return FALSE;
+              }
+          }
 
-      if ((row % 32) == 0)
-        gimp_progress_update ((gdouble) row / (gdouble) rows);
-    }
+        if ((row % 32) == 0)
+          gimp_progress_update ((gdouble) row / (gdouble) rows);
+      }
 
-  TIFFFlushData (tif);
+    TIFFWriteDirectory (tif);
+  }
+  
   TIFFClose (tif);
-  close (fd);
 
   gimp_progress_update (1.0);
 
   gimp_drawable_detach (drawable);
   g_free (data);
-
+  g_free (layers);
+  
   return TRUE;
 }
 
@@ -1057,6 +1094,7 @@
   GtkWidget *g3;
   GtkWidget *g4;
   gboolean   run;
+  GtkWidget *layer_frame;
 
   dialog = gimp_dialog_new (_("Save as TIFF"), PLUG_IN_BINARY,
                             NULL, 0,
@@ -1123,6 +1161,20 @@
                     G_CALLBACK (gimp_toggle_button_update),
                     &tsvals.save_transp_pixels);
 
+  /* Save layers as pages */
+  layer_frame = gimp_int_radio_group_new (TRUE, _("Layer Mode"),
+                                    G_CALLBACK (gimp_radio_button_update),
+                                    &tsvals.layer_mode, tsvals.layer_mode,
+                                    
+                                    _("_Flatten Image"),        LAYER_MODE_COMBINE, NULL,
+                                    _("_Merge Visible Layers"), LAYER_MODE_MERGE,   NULL,
+                                    _("Save as _Pages"),        LAYER_MODE_PAGES,   NULL,
+                                    
+                                    NULL);
+  gtk_box_pack_start (GTK_BOX (vbox), layer_frame, FALSE, FALSE, 0);
+  gtk_widget_show (layer_frame);
+
+
   /* comment entry */
   hbox = gtk_hbox_new (FALSE, 6);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]