[gimp/gimp-2-10] plug-ins: fix #4492 Add export options



commit 3a22719e6849bc13fee89c179ebebc5fec322feb
Author: Nikc <nikcdc gmail com>
Date:   Fri May 20 05:24:40 2022 +0000

    plug-ins: fix #4492 Add export options
    
    Adds a new option to flip the image on export. This allows for
    direct imports into certain DirectX engines without altering the
    project file. It also adds a new option to save all visible layers on
    export, again to avoid altering the user's project file.

 plug-ins/file-dds/dds.c       | 53 ++++++++++++++++++++++++++++++++++++++++---
 plug-ins/file-dds/dds.h       |  1 +
 plug-ins/file-dds/ddsplugin.h | 33 +++++++++++++++------------
 plug-ins/file-dds/ddswrite.c  | 46 +++++++++++++++++++++++++++++++++----
 4 files changed, 110 insertions(+), 23 deletions(-)
---
diff --git a/plug-ins/file-dds/dds.c b/plug-ins/file-dds/dds.c
index 8e79073737..9e2c830b48 100644
--- a/plug-ins/file-dds/dds.c
+++ b/plug-ins/file-dds/dds.c
@@ -101,7 +101,7 @@ static GimpParamDef save_args[] =
   { GIMP_PDB_STRING, "raw_filename", "The name entered"},
   { GIMP_PDB_INT32, "compression_format", "Compression format (0 = None, 1 = BC1/DXT1, 2 = BC2/DXT3, 3 = 
BC3/DXT5, 4 = BC3n/DXT5nm, 5 = BC4/ATI1N, 6 = BC5/ATI2N, 7 = RXGB (DXT5), 8 = Alpha Exponent (DXT5), 9 = 
YCoCg (DXT5), 10 = YCoCg scaled (DXT5))"},
   { GIMP_PDB_INT32, "mipmaps", "How to handle mipmaps (0 = No mipmaps, 1 = Generate mipmaps, 2 = Use 
existing mipmaps (layers)"},
-  { GIMP_PDB_INT32, "savetype", "How to save the image (0 = selected layer, 1 = cube map, 2 = volume map, 3 
= texture array"},
+  { GIMP_PDB_INT32, "savetype", "How to save the image (0 = selected layer, 1 = cube map, 2 = volume map, 3 
= texture array, 4 = all visible layers"},
   { GIMP_PDB_INT32, "format", "Custom pixel format (0 = default, 1 = R5G6B5, 2 = RGBA4, 3 = RGB5A1, 4 = 
RGB10A2)"},
   { GIMP_PDB_INT32, "transparent_index", "Index of transparent color or -1 to disable (for indexed images 
only)."},
   { GIMP_PDB_INT32, "mipmap_filter", "Filtering to use when generating mipmaps (0 = default, 1 = nearest, 2 
= box, 3 = triangle, 4 = quadratic, 5 = bspline, 6 = mitchell, 7 = lanczos, 8 = kaiser)"},
@@ -114,6 +114,29 @@ static GimpParamDef save_args[] =
   { GIMP_PDB_FLOAT, "alpha_test_threshold", "Alpha test threshold value for which alpha test converage 
should be preserved"}
 };
 
+static GimpParamDef save_args2[] =
+{
+  { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive"},
+  { GIMP_PDB_IMAGE, "image", "Input image"},
+  { GIMP_PDB_DRAWABLE, "drawable", "Drawable to save"},
+  { GIMP_PDB_STRING, "filename", "The name of the file to save the image as"},
+  { GIMP_PDB_STRING, "raw_filename", "The name entered"},
+  { GIMP_PDB_INT32, "compression_format", "Compression format (0 = None, 1 = BC1/DXT1, 2 = BC2/DXT3, 3 = 
BC3/DXT5, 4 = BC3n/DXT5nm, 5 = BC4/ATI1N, 6 = BC5/ATI2N, 7 = RXGB (DXT5), 8 = Alpha Exponent (DXT5), 9 = 
YCoCg (DXT5), 10 = YCoCg scaled (DXT5))"},
+  { GIMP_PDB_INT32, "mipmaps", "How to handle mipmaps (0 = No mipmaps, 1 = Generate mipmaps, 2 = Use 
existing mipmaps (layers)"},
+  { GIMP_PDB_INT32, "savetype", "How to save the image (0 = selected layer, 1 = cube map, 2 = volume map, 3 
= texture array, 4 = all visible layers"},
+  { GIMP_PDB_INT32, "format", "Custom pixel format (0 = default, 1 = R5G6B5, 2 = RGBA4, 3 = RGB5A1, 4 = 
RGB10A2)"},
+  { GIMP_PDB_INT32, "transparent_index", "Index of transparent color or -1 to disable (for indexed images 
only)."},
+  { GIMP_PDB_INT32, "mipmap_filter", "Filtering to use when generating mipmaps (0 = default, 1 = nearest, 2 
= box, 3 = triangle, 4 = quadratic, 5 = bspline, 6 = mitchell, 7 = lanczos, 8 = kaiser)"},
+  { GIMP_PDB_INT32, "mipmap_wrap", "Wrap mode to use when generating mipmaps (0 = default, 1 = mirror, 2 = 
repeat, 3 = clamp)"},
+  { GIMP_PDB_INT32, "gamma_correct", "Use gamma correct mipmap filtering"},
+  { GIMP_PDB_INT32, "srgb", "Use sRGB colorspace for gamma correction"},
+  { GIMP_PDB_FLOAT, "gamma", "Gamma value to use for gamma correction (i.e. 2.2)"},
+  { GIMP_PDB_INT32, "perceptual_metric", "Use a perceptual error metric during compression"},
+  { GIMP_PDB_INT32, "preserve_alpha_coverage", "Preserve alpha test converage for alpha channel maps"},
+  { GIMP_PDB_FLOAT, "alpha_test_threshold", "Alpha test threshold value for which alpha test converage 
should be preserved"},
+  { GIMP_PDB_INT32, "flip_image", "Flip image vertically on export"}
+};
+
 #if 0
 static GimpParamDef decode_args[] =
 {
@@ -166,6 +189,24 @@ query (void)
                               "dds",
                               "");
 
+  gimp_install_procedure (SAVE_PROC2,
+                          "Saves files in DDS image format "
+                          "with additional export options",
+                          "Saves files in DDS image format "
+                          "with additional export options",
+                          "Shawn Kirst",
+                          "Shawn Kirst",
+                          "2008",
+                          N_("DDS image"),
+                          "INDEXED, GRAY, RGB",
+                          GIMP_PLUGIN,
+                          G_N_ELEMENTS (save_args2), 0,
+                          save_args2, 0);
+
+  gimp_register_file_handler_mime (SAVE_PROC2, "image/dds");
+  gimp_register_save_handler (SAVE_PROC2,
+                              "dds",
+                              "");
 #if 0
   gimp_install_procedure (DECODE_YCOCG_PROC,
                           "Converts YCoCg encoded pixels to RGB",
@@ -270,7 +311,8 @@ run (const gchar      *name,
             }
         }
     }
-  else if (! strcmp (name, SAVE_PROC))
+  else if (! strcmp (name, SAVE_PROC) ||
+           ! strcmp (name, SAVE_PROC2))
     {
       imageID    = param[1].data.d_int32;
       drawableID = param[2].data.d_int32;
@@ -322,6 +364,10 @@ run (const gchar      *name,
               dds_write_vals.perceptual_metric       = param[15].data.d_int32;
               dds_write_vals.preserve_alpha_coverage = param[16].data.d_int32;
               dds_write_vals.alpha_test_threshold    = param[17].data.d_float;
+              if (nparams > 18)
+                dds_write_vals.flip_image            = param[18].data.d_int32;
+              else
+                dds_write_vals.flip_image            = FALSE;
 
               if ((dds_write_vals.compression <  DDS_COMPRESS_NONE) ||
                  (dds_write_vals.compression >= DDS_COMPRESS_MAX))
@@ -379,7 +425,8 @@ run (const gchar      *name,
       if (status == GIMP_PDB_SUCCESS)
         {
           status = write_dds (param[3].data.d_string, imageID, drawableID,
-                              run_mode == GIMP_RUN_INTERACTIVE);
+                              run_mode == GIMP_RUN_INTERACTIVE,
+                              export == GIMP_EXPORT_EXPORT);
           if (status == GIMP_PDB_SUCCESS)
             gimp_set_data (SAVE_PROC, &dds_write_vals, sizeof (dds_write_vals));
         }
diff --git a/plug-ins/file-dds/dds.h b/plug-ins/file-dds/dds.h
index 8442c53bec..971b00aeb5 100644
--- a/plug-ins/file-dds/dds.h
+++ b/plug-ins/file-dds/dds.h
@@ -49,6 +49,7 @@ typedef enum
   DDS_SAVE_CUBEMAP,
   DDS_SAVE_VOLUMEMAP,
   DDS_SAVE_ARRAY,
+  DDS_SAVE_VISIBLE_LAYERS,
   DDS_SAVE_MAX
 } DDS_SAVE_TYPE;
 
diff --git a/plug-ins/file-dds/ddsplugin.h b/plug-ins/file-dds/ddsplugin.h
index 1351886a51..96257c9ea4 100644
--- a/plug-ins/file-dds/ddsplugin.h
+++ b/plug-ins/file-dds/ddsplugin.h
@@ -32,20 +32,21 @@
 
 typedef struct
 {
-  int compression;
-  int mipmaps;
-  int savetype;
-  int format;
-  int transindex;
-  int mipmap_filter;
-  int mipmap_wrap;
-  int gamma_correct;
-  int srgb;
-  float gamma;
-  int perceptual_metric;
-  int show_adv_opt;
-  int preserve_alpha_coverage;
-  float alpha_test_threshold;
+  int      compression;
+  int      mipmaps;
+  int      savetype;
+  int      format;
+  int      transindex;
+  int      mipmap_filter;
+  int      mipmap_wrap;
+  int      gamma_correct;
+  int      srgb;
+  float    gamma;
+  int      perceptual_metric;
+  int      show_adv_opt;
+  int      preserve_alpha_coverage;
+  float    alpha_test_threshold;
+  gboolean flip_image;
 } DDSWriteVals;
 
 typedef struct
@@ -63,11 +64,13 @@ extern GimpPDBStatusType read_dds  (gchar    *filename,
 extern GimpPDBStatusType write_dds (gchar    *filename,
                                     gint32    image_id,
                                     gint32    drawable_id,
-                                    gboolean  interactive_dds);
+                                    gboolean  interactive_dds,
+                                    gboolean  is_duplicate_image);
 
 
 #define LOAD_PROC                "file-dds-load"
 #define SAVE_PROC                "file-dds-save"
+#define SAVE_PROC2               "file-dds-save2"
 
 #define DECODE_YCOCG_PROC        "color-decode-ycocg"
 #define DECODE_YCOCG_SCALED_PROC "color-decode-ycocg-scaled"
diff --git a/plug-ins/file-dds/ddswrite.c b/plug-ins/file-dds/ddswrite.c
index a3215ed3b0..5fb658a788 100644
--- a/plug-ins/file-dds/ddswrite.c
+++ b/plug-ins/file-dds/ddswrite.c
@@ -181,10 +181,11 @@ static string_value_t mipmap_wrap_strings[] =
 
 static string_value_t save_type_strings[] =
 {
-  { DDS_SAVE_SELECTED_LAYER, "Image / Selected layer" },
+  { DDS_SAVE_SELECTED_LAYER, "Selected layer" },
   { DDS_SAVE_CUBEMAP,        "As cube map" },
   { DDS_SAVE_VOLUMEMAP,      "As volume map" },
   { DDS_SAVE_ARRAY,          "As texture array" },
+  { DDS_SAVE_VISIBLE_LAYERS, "All visible layers" },
   { -1, 0}
 };
 
@@ -553,7 +554,8 @@ GimpPDBStatusType
 write_dds (gchar    *filename,
            gint32    image_id,
            gint32    drawable_id,
-           gboolean  interactive_dds)
+           gboolean  interactive_dds,
+           gboolean  is_duplicate_image)
 {
   FILE  *fp;
   gchar *tmp;
@@ -617,7 +619,20 @@ write_dds (gchar    *filename,
   gimp_progress_init (tmp);
   g_free (tmp);
 
-  rc = write_image (fp, image_id, drawable_id);
+  /* If destructive changes are going to happen to the image,
+   * make sure we send a duplicate of it to write_image
+   */
+  if (! is_duplicate_image)
+    {
+      gint32 duplicate_image = gimp_image_duplicate (image_id);
+      rc = write_image (fp, duplicate_image, drawable_id);
+      gimp_image_delete (duplicate_image);
+    }
+  else
+    {
+      rc = write_image (fp, image_id, drawable_id);
+    }
+
 
   fclose (fp);
 
@@ -1268,6 +1283,12 @@ write_image (FILE   *fp,
   gint is_dx10 = 0;
   gint array_size = 1;
 
+  if (dds_write_vals.flip_image)
+    {
+      gimp_image_flip (image_id, GIMP_ORIENTATION_VERTICAL);
+      drawable_id = gimp_image_get_active_drawable (image_id);
+    }
+
   layers = gimp_image_get_layers (image_id, &num_layers);
 
   if (dds_write_vals.mipmaps == DDS_MIPMAP_EXISTING)
@@ -1571,7 +1592,8 @@ write_image (FILE   *fp,
 
   if (is_dx10)
     {
-      array_size = (dds_write_vals.savetype == DDS_SAVE_SELECTED_LAYER) ? 1 : get_array_size (image_id);
+      array_size = (dds_write_vals.savetype == DDS_SAVE_SELECTED_LAYER ||
+                    dds_write_vals.savetype == DDS_SAVE_VISIBLE_LAYERS) ? 1 : get_array_size (image_id);
 
       PUTL32 (hdr10 +  0, dxgi_format);
       PUTL32 (hdr10 +  4, D3D10_RESOURCE_DIMENSION_TEXTURE2D);
@@ -1646,6 +1668,8 @@ write_image (FILE   *fp,
     }
   else
     {
+      if (dds_write_vals.savetype == DDS_SAVE_VISIBLE_LAYERS)
+        drawable_id = gimp_image_merge_visible_layers (image_id, 1);
       write_layer (fp, image_id, drawable_id, w, h, bpp, fmtbpp, num_mipmaps);
     }
 
@@ -1798,6 +1822,7 @@ savetype_selected (GtkWidget *widget,
   switch (dds_write_vals.savetype)
     {
     case DDS_SAVE_SELECTED_LAYER:
+    case DDS_SAVE_VISIBLE_LAYERS:
     case DDS_SAVE_CUBEMAP:
     case DDS_SAVE_ARRAY:
       gtk_widget_set_sensitive (compress_opt, TRUE);
@@ -2034,8 +2059,19 @@ save_dialog (gint32 image_id,
   string_value_combo_set_item_sensitive (opt, DDS_SAVE_VOLUMEMAP, is_volume);
   string_value_combo_set_item_sensitive (opt, DDS_SAVE_ARRAY, is_array);
 
+  check = gtk_check_button_new_with_mnemonic (_("Flip the image _vertically on export"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
+                                dds_write_vals.flip_image);
+  gtk_table_attach (GTK_TABLE (table), check, 1, 2, 4, 5,
+                    GTK_FILL, 0, 0, 0);
+  gtk_widget_show (check);
+
+  g_signal_connect (check, "clicked",
+                    G_CALLBACK (toggle_clicked),
+                    &dds_write_vals.flip_image);
+
   opt = string_value_combo_new (mipmap_strings, dds_write_vals.mipmaps);
-  gimp_table_attach_aligned (GTK_TABLE (table), 0, 4,
+  gimp_table_attach_aligned (GTK_TABLE (table), 0, 5,
                              _("_Mipmaps:"),
                              0.0, 0.5,
                              opt, 1, FALSE);


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