plug-ins: port file-dds to GimpPlugIn and libgimp objects

This is such a monster, I'm sure I broke something here...
This commit is contained in:
Michael Natterer 2019-08-27 14:43:38 +02:00
parent 3d7c044181
commit 10b798c198
7 changed files with 715 additions and 560 deletions

View file

@ -27,30 +27,29 @@ libexecdir = $(gimpplugindir)/plug-ins/file-dds
libexec_PROGRAMS = file-dds
file_dds_SOURCES = \
dds.c \
dds.h \
color.c \
color.h \
ddsplugin.h \
ddsread.c \
ddswrite.c \
dxt.c \
dxt.h \
dds.c \
dds.h \
color.c \
color.h \
ddsplugin.h \
ddsread.c \
ddswrite.c \
dxt.c \
dxt.h \
dxt_tables.h \
endian_rw.h \
imath.h \
mipmap.c \
mipmap.h \
misc.c \
misc.h \
mktables.c \
endian_rw.h \
imath.h \
mipmap.c \
mipmap.h \
misc.c \
misc.h \
mktables.c \
vec.h
AM_CPPFLAGS = \
-DGIMP_DEPRECATED_REPLACE_NEW_API \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
$(GEGL_CFLAGS) \
$(GEGL_CFLAGS) \
-I$(includedir)
LDADD = \

View file

@ -38,22 +38,55 @@
#include "misc.h"
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
typedef struct _Dds Dds;
typedef struct _DdsClass DdsClass;
GimpPlugInInfo PLUG_IN_INFO =
struct _Dds
{
0,
0,
query,
run
GimpPlugIn parent_instance;
};
struct _DdsClass
{
GimpPlugInClass parent_class;
};
#define DDS_TYPE (dds_get_type ())
#define DDS (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DDS_TYPE, Dds))
GType dds_get_type (void) G_GNUC_CONST;
static GList * dds_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * dds_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
static GimpValueArray * dds_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
const GimpValueArray *args,
gpointer run_data);
static GimpValueArray * dds_save (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
GFile *file,
const GimpValueArray *args,
gpointer run_data);
static GimpValueArray * dds_decode (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
const GimpValueArray *args,
gpointer run_data);
G_DEFINE_TYPE (Dds, dds, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (DDS_TYPE)
DDSWriteVals dds_write_vals =
{
DDS_COMPRESS_NONE,
@ -78,357 +111,423 @@ DDSReadVals dds_read_vals =
1
};
static GimpParamDef load_args[] =
{
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive"},
{ GIMP_PDB_STRING, "filename", "The name of the file to load"},
{ GIMP_PDB_STRING, "raw_filename", "The name entered"},
{ GIMP_PDB_INT32, "load_mipmaps", "Load mipmaps if present"},
{ GIMP_PDB_INT32, "decode_images", "Decode YCoCg/AExp images when detected"}
};
static GimpParamDef load_return_vals[] =
{
{ GIMP_PDB_IMAGE, "image", "Output image"}
};
static GimpParamDef save_args[] =
{
{ 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"},
{ 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"}
};
static GimpParamDef decode_args[] =
{
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive"},
{ GIMP_PDB_IMAGE, "image", "Input image"},
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to save"}
};
MAIN ()
static void
query (void)
dds_class_init (DdsClass *klass)
{
gimp_install_procedure (LOAD_PROC,
"Loads files in DDS image format",
"Loads files in DDS image format",
"Shawn Kirst",
"Shawn Kirst",
"2008",
N_("DDS image"),
0,
GIMP_PLUGIN,
G_N_ELEMENTS (load_args),
G_N_ELEMENTS (load_return_vals),
load_args, load_return_vals);
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
gimp_register_file_handler_mime (LOAD_PROC, "image/dds");
gimp_register_magic_load_handler (LOAD_PROC,
"dds",
"",
"0,string,DDS");
gimp_install_procedure (SAVE_PROC,
"Saves files in DDS image format",
"Saves files in DDS image format",
"Shawn Kirst",
"Shawn Kirst",
"2008",
N_("DDS image"),
"INDEXED, GRAY, RGB",
GIMP_PLUGIN,
G_N_ELEMENTS (save_args), 0,
save_args, 0);
gimp_register_file_handler_mime (SAVE_PROC, "image/dds");
gimp_register_save_handler (SAVE_PROC,
"dds",
"");
gimp_install_procedure (DECODE_YCOCG_PROC,
"Converts YCoCg encoded pixels to RGB",
"Converts YCoCg encoded pixels to RGB",
"Shawn Kirst",
"Shawn Kirst",
"2008",
N_("Decode YCoCg"),
"RGBA",
GIMP_PLUGIN,
G_N_ELEMENTS (decode_args), 0,
decode_args, 0);
/*gimp_plugin_menu_register (DECODE_YCOCG_PROC, "<Image>/Filters/Colors");*/
gimp_install_procedure (DECODE_YCOCG_SCALED_PROC,
"Converts YCoCg (scaled) encoded pixels to RGB",
"Converts YCoCg (scaled) encoded pixels to RGB",
"Shawn Kirst",
"Shawn Kirst",
"2008",
N_("Decode YCoCg (scaled)"),
"RGBA",
GIMP_PLUGIN,
G_N_ELEMENTS (decode_args), 0,
decode_args, 0);
/*gimp_plugin_menu_register (DECODE_YCOCG_SCALED_PROC, "<Image>/Filters/Colors");*/
gimp_install_procedure (DECODE_ALPHA_EXP_PROC,
"Converts alpha exponent encoded pixels to RGB",
"Converts alpha exponent encoded pixels to RGB",
"Shawn Kirst",
"Shawn Kirst",
"2008",
N_("Decode Alpha exponent"),
"RGBA",
GIMP_PLUGIN,
G_N_ELEMENTS (decode_args), 0,
decode_args, 0);
/*gimp_plugin_menu_register (DECODE_ALPHA_EXP_PROC, "<Image>/Filters/Colors");*/
plug_in_class->query_procedures = dds_query_procedures;
plug_in_class->create_procedure = dds_create_procedure;
}
static void
run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals)
dds_init (Dds *dds)
{
static GimpParam values[2];
GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gint32 imageID;
gint32 drawableID;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
}
gegl_init (NULL, NULL);
static GList *
dds_query_procedures (GimpPlugIn *plug_in)
{
GList *list = NULL;
run_mode = param[0].data.d_int32;
list = g_list_append (list, g_strdup (LOAD_PROC));
list = g_list_append (list, g_strdup (SAVE_PROC));
list = g_list_append (list, g_strdup (DECODE_YCOCG_PROC));
list = g_list_append (list, g_strdup (DECODE_YCOCG_SCALED_PROC));
list = g_list_append (list, g_strdup (DECODE_ALPHA_EXP_PROC));
*nreturn_vals = 1;
*return_vals = values;
return list;
}
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
static GimpProcedure *
dds_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
if (! strcmp (name, LOAD_PROC))
{
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_ui_init ("dds", 0);
gimp_get_data (LOAD_PROC, &dds_read_vals);
break;
procedure = gimp_load_procedure_new (plug_in, name, GIMP_PLUGIN,
dds_load, NULL, NULL);
case GIMP_RUN_NONINTERACTIVE:
dds_read_vals.mipmaps = param[3].data.d_int32;
dds_read_vals.decode_images = param[4].data.d_int32;
if (nparams != G_N_ELEMENTS (load_args))
status = GIMP_PDB_CALLING_ERROR;
break;
gimp_procedure_set_menu_label (procedure, N_("DDS image"));
default:
break;
}
gimp_procedure_set_documentation (procedure,
"Loads files in DDS image format",
"Loads files in DDS image format",
name);
gimp_procedure_set_attribution (procedure,
"Shawn Kirst",
"Shawn Kirst",
"2008");
if (status == GIMP_PDB_SUCCESS)
{
GFile *file = g_file_new_for_uri (param[1].data.d_string);
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
"image/dds");
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"dds");
gimp_file_procedure_set_magics (GIMP_FILE_PROCEDURE (procedure),
"0,string,DDS");
status = read_dds (g_file_get_path (file), &imageID,
run_mode == GIMP_RUN_INTERACTIVE);
if (status == GIMP_PDB_SUCCESS && imageID != -1)
{
*nreturn_vals = 2;
values[1].type = GIMP_PDB_IMAGE;
values[1].data.d_image = imageID;
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data (LOAD_PROC, &dds_read_vals, sizeof (dds_read_vals));
}
else if (status != GIMP_PDB_CANCEL)
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
GIMP_PROC_ARG_BOOLEAN (procedure, "load-mipmaps",
"Load mipmaps",
"Load mipmaps if present",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_BOOLEAN (procedure, "decode-images",
"Decode images",
"Decode YCoCg/AExp images when detected",
TRUE,
G_PARAM_READWRITE);
}
else if (! strcmp (name, SAVE_PROC))
{
imageID = param[1].data.d_int32;
drawableID = param[2].data.d_int32;
procedure = gimp_save_procedure_new (plug_in, name, GIMP_PLUGIN,
dds_save, NULL, NULL);
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
gimp_ui_init ("dds", 0);
export = gimp_export_image (&imageID, &drawableID, "DDS",
(GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA |
GIMP_EXPORT_CAN_HANDLE_LAYERS));
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
return;
}
gimp_procedure_set_image_types (procedure, "INDEXED, GRAY, RGB");
default:
break;
}
gimp_procedure_set_menu_label (procedure, N_("DDS image"));
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_get_data (SAVE_PROC, &dds_write_vals);
break;
gimp_procedure_set_documentation (procedure,
"Saves files in DDS image format",
"Saves files in DDS image format",
name);
gimp_procedure_set_attribution (procedure,
"Shawn Kirst",
"Shawn Kirst",
"2008");
case GIMP_RUN_NONINTERACTIVE:
if (nparams != G_N_ELEMENTS (save_args))
{
status = GIMP_PDB_CALLING_ERROR;
}
else
{
dds_write_vals.compression = param[5].data.d_int32;
dds_write_vals.mipmaps = param[6].data.d_int32;
dds_write_vals.savetype = param[7].data.d_int32;
dds_write_vals.format = param[8].data.d_int32;
dds_write_vals.transindex = param[9].data.d_int32;
dds_write_vals.mipmap_filter = param[10].data.d_int32;
dds_write_vals.mipmap_wrap = param[11].data.d_int32;
dds_write_vals.gamma_correct = param[12].data.d_int32;
dds_write_vals.srgb = param[13].data.d_int32;
dds_write_vals.gamma = param[14].data.d_float;
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;
gimp_file_procedure_set_mime_types (GIMP_FILE_PROCEDURE (procedure),
"image/dds");
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"dds");
if ((dds_write_vals.compression < DDS_COMPRESS_NONE) ||
(dds_write_vals.compression >= DDS_COMPRESS_MAX))
{
status = GIMP_PDB_CALLING_ERROR;
}
GIMP_PROC_ARG_INT (procedure, "compression-format",
"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))",
0, 10, DDS_COMPRESS_NONE,
G_PARAM_READWRITE);
if ((dds_write_vals.mipmaps < DDS_MIPMAP_NONE) ||
(dds_write_vals.mipmaps >= DDS_MIPMAP_MAX))
{
status = GIMP_PDB_CALLING_ERROR;
}
GIMP_PROC_ARG_INT (procedure, "mipmaps",
"Mipmaps",
"How to handle mipmaps (0 = No mipmaps, "
"1 = Generate mipmaps, "
"2 = Use existing mipmaps (layers)",
0, 2, DDS_MIPMAP_NONE,
G_PARAM_READWRITE);
if ((dds_write_vals.savetype < DDS_SAVE_SELECTED_LAYER) ||
(dds_write_vals.savetype >= DDS_SAVE_MAX))
{
status = GIMP_PDB_CALLING_ERROR;
}
GIMP_PROC_ARG_INT (procedure, "save-type",
"Save type",
"How to save the image (0 = selected layer, "
"1 = cube map, 2 = volume map, 3 = texture array",
0, 3, DDS_SAVE_SELECTED_LAYER,
G_PARAM_READWRITE);
if ((dds_write_vals.format < DDS_FORMAT_DEFAULT) ||
(dds_write_vals.format >= DDS_FORMAT_MAX))
{
status = GIMP_PDB_CALLING_ERROR;
}
GIMP_PROC_ARG_INT (procedure, "format",
"Format",
"Pixel format (0 = default, 1 = R5G6B5, 2 = RGBA4, "
"3 = RGB5A1, 4 = RGB10A2)",
0, 4, DDS_FORMAT_DEFAULT,
G_PARAM_READWRITE);
if ((dds_write_vals.mipmap_filter < DDS_MIPMAP_FILTER_DEFAULT) ||
(dds_write_vals.mipmap_filter >= DDS_MIPMAP_FILTER_MAX))
{
status = GIMP_PDB_CALLING_ERROR;
}
GIMP_PROC_ARG_INT (procedure, "transparent-index",
"Transparent index",
"Index of transparent color or -1 to disable "
"(for indexed images only).",
-1, 255, -1,
G_PARAM_READWRITE);
if ((dds_write_vals.mipmap_wrap < DDS_MIPMAP_WRAP_DEFAULT) ||
(dds_write_vals.mipmap_wrap >= DDS_MIPMAP_WRAP_MAX))
{
status = GIMP_PDB_CALLING_ERROR;
}
}
break;
GIMP_PROC_ARG_INT (procedure, "mipmap-filter",
"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)",
0, 8, DDS_MIPMAP_FILTER_DEFAULT,
G_PARAM_READWRITE);
case GIMP_RUN_WITH_LAST_VALS:
gimp_get_data (SAVE_PROC, &dds_write_vals);
break;
GIMP_PROC_ARG_INT (procedure, "mipmap-wrap",
"Mipmap wrap",
"Wrap mode to use when generating mipmaps "
"(0 = default, 1 = mirror, 2 = repeat, 3 = clamp)",
0, 3, DDS_MIPMAP_WRAP_DEFAULT,
G_PARAM_READWRITE);
default:
break;
}
GIMP_PROC_ARG_BOOLEAN (procedure, "gamma-correct",
"Gamme correct",
"Use gamma correct mipmap filtering",
FALSE,
G_PARAM_READWRITE);
if (dds_write_vals.gamma < 1e-04f)
/* gimp_gamma () got removed and was always returning 2.2 anyway.
* XXX Review this piece of code if we expect gamma value could
* be parameterized.
*/
dds_write_vals.gamma = 2.2;
GIMP_PROC_ARG_BOOLEAN (procedure, "srgb",
"sRGB",
"Use sRGB colorspace for gamma correction",
FALSE,
G_PARAM_READWRITE);
if (status == GIMP_PDB_SUCCESS)
{
GFile *file = g_file_new_for_uri (param[3].data.d_string);
GIMP_PROC_ARG_DOUBLE (procedure, "gamma",
"Gamma",
"Gamma value to use for gamma correction (i.e. 2.2)",
0.0, 10.0, 0.0,
G_PARAM_READWRITE);
status = write_dds (g_file_get_path (file),
imageID, drawableID,
run_mode == GIMP_RUN_INTERACTIVE);
GIMP_PROC_ARG_BOOLEAN (procedure, "perceptual-metric",
"Perceptual metric",
"Use a perceptual error metric during compression",
FALSE,
G_PARAM_READWRITE);
if (status == GIMP_PDB_SUCCESS)
gimp_set_data (SAVE_PROC, &dds_write_vals, sizeof (dds_write_vals));
}
GIMP_PROC_ARG_BOOLEAN (procedure, "preserve-alpha-coverage",
"Preserve alpha coverage",
"Preserve alpha test converage for alpha "
"channel maps",
FALSE,
G_PARAM_READWRITE);
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (imageID);
GIMP_PROC_ARG_DOUBLE (procedure, "alpha-test-threshold",
"Alpha test threshold",
"Alpha test threshold value for which alpha test "
"converage should be preserved",
0.0, 1.0, 0.5,
G_PARAM_READWRITE);
}
else if (! strcmp (name, DECODE_YCOCG_PROC))
{
imageID = param[1].data.d_int32;
drawableID = param[2].data.d_int32;
procedure = gimp_image_procedure_new (plug_in, name, GIMP_PLUGIN,
dds_decode, NULL, NULL);
decode_ycocg_image (drawableID, TRUE);
gimp_procedure_set_image_types (procedure, "RGBA");
status = GIMP_PDB_SUCCESS;
gimp_procedure_set_menu_label (procedure, N_("Decode YCoCg"));
/* gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
gimp_procedure_set_documentation (procedure,
"Converts YCoCg encoded pixels to RGB",
"Converts YCoCg encoded pixels to RGB",
name);
gimp_procedure_set_attribution (procedure,
"Shawn Kirst",
"Shawn Kirst",
"2008");
}
else if (! strcmp (name, DECODE_YCOCG_SCALED_PROC))
{
imageID = param[1].data.d_int32;
drawableID = param[2].data.d_int32;
procedure = gimp_image_procedure_new (plug_in, name, GIMP_PLUGIN,
dds_decode, NULL, NULL);
decode_ycocg_scaled_image (drawableID, TRUE);
gimp_procedure_set_image_types (procedure, "RGBA");
status = GIMP_PDB_SUCCESS;
gimp_procedure_set_menu_label (procedure, N_("Decode YCoCg (scaled)"));
/* gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
gimp_procedure_set_documentation (procedure,
"Converts YCoCg (scaled) encoded "
"pixels to RGB",
"Converts YCoCg (scaled) encoded "
"pixels to RGB",
name);
gimp_procedure_set_attribution (procedure,
"Shawn Kirst",
"Shawn Kirst",
"2008");
}
else if (! strcmp (name, DECODE_ALPHA_EXP_PROC))
{
imageID = param[1].data.d_int32;
drawableID = param[2].data.d_int32;
procedure = gimp_image_procedure_new (plug_in, name, GIMP_PLUGIN,
dds_decode, NULL, NULL);
decode_alpha_exp_image (drawableID, TRUE);
gimp_procedure_set_image_types (procedure, "RGBA");
status = GIMP_PDB_SUCCESS;
gimp_procedure_set_menu_label (procedure, N_("Decode Alpha exponent"));
/* gimp_procedure_add_menu_path (procedure, "<Image>/Filters/Colors"); */
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
}
else
{
status = GIMP_PDB_CALLING_ERROR;
gimp_procedure_set_documentation (procedure,
"Converts alpha exponent encoded "
"pixels to RGB",
"Converts alpha exponent encoded "
"pixels to RGB",
name);
gimp_procedure_set_attribution (procedure,
"Shawn Kirst",
"Shawn Kirst",
"2008");
}
values[0].data.d_status = status;
return procedure;
}
static GimpValueArray *
dds_load (GimpProcedure *procedure,
GimpRunMode run_mode,
GFile *file,
const GimpValueArray *args,
gpointer run_data)
{
GimpValueArray *return_vals;
GimpPDBStatusType status;
GimpImage *image;
GError *error = NULL;
INIT_I18N ();
gegl_init (NULL, NULL);
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_ui_init ("dds", 0);
gimp_get_data (LOAD_PROC, &dds_read_vals);
break;
case GIMP_RUN_NONINTERACTIVE:
dds_read_vals.mipmaps = GIMP_VALUES_GET_BOOLEAN (args, 0);
dds_read_vals.decode_images = GIMP_VALUES_GET_BOOLEAN (args, 1);
break;
default:
break;
}
status = read_dds (g_file_get_path (file), &image,
run_mode == GIMP_RUN_INTERACTIVE);
if (status == GIMP_PDB_SUCCESS &&
run_mode != GIMP_RUN_NONINTERACTIVE)
{
gimp_set_data (LOAD_PROC, &dds_read_vals, sizeof (dds_read_vals));
}
if (! image)
return gimp_procedure_new_return_values (procedure, status, error);
return_vals = gimp_procedure_new_return_values (procedure,
GIMP_PDB_SUCCESS,
NULL);
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
return return_vals;
}
static GimpValueArray *
dds_save (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
GFile *file,
const GimpValueArray *args,
gpointer run_data)
{
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GError *error = NULL;
INIT_I18N ();
gegl_init (NULL, NULL);
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
case GIMP_RUN_WITH_LAST_VALS:
gimp_ui_init ("dds", 0);
export = gimp_export_image (&image, &drawable, "DDS",
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_INDEXED |
GIMP_EXPORT_CAN_HANDLE_ALPHA |
GIMP_EXPORT_CAN_HANDLE_LAYERS);
if (export == GIMP_EXPORT_CANCEL)
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
break;
default:
break;
}
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_get_data (SAVE_PROC, &dds_write_vals);
break;
case GIMP_RUN_NONINTERACTIVE:
dds_write_vals.compression = GIMP_VALUES_GET_INT (args, 0);
dds_write_vals.mipmaps = GIMP_VALUES_GET_INT (args, 1);
dds_write_vals.savetype = GIMP_VALUES_GET_INT (args, 2);
dds_write_vals.format = GIMP_VALUES_GET_INT (args, 3);
dds_write_vals.transindex = GIMP_VALUES_GET_INT (args, 4);
dds_write_vals.mipmap_filter = GIMP_VALUES_GET_INT (args, 5);
dds_write_vals.mipmap_wrap = GIMP_VALUES_GET_INT (args, 6);
dds_write_vals.gamma_correct = GIMP_VALUES_GET_BOOLEAN (args, 7);
dds_write_vals.srgb = GIMP_VALUES_GET_BOOLEAN (args, 8);
dds_write_vals.gamma = GIMP_VALUES_GET_DOUBLE (args, 9);
dds_write_vals.perceptual_metric = GIMP_VALUES_GET_BOOLEAN (args, 10);
dds_write_vals.preserve_alpha_coverage = GIMP_VALUES_GET_BOOLEAN (args, 11);
dds_write_vals.alpha_test_threshold = GIMP_VALUES_GET_DOUBLE (args, 12);
break;
case GIMP_RUN_WITH_LAST_VALS:
gimp_get_data (SAVE_PROC, &dds_write_vals);
break;
default:
break;
}
if (dds_write_vals.gamma < 1e-04f)
/* gimp_gamma () got removed and was always returning 2.2 anyway.
* XXX Review this piece of code if we expect gamma value could be
* parameterized.
*/
dds_write_vals.gamma = 2.2;
status = write_dds (g_file_get_path (file),
image, drawable,
run_mode == GIMP_RUN_INTERACTIVE);
if (status == GIMP_PDB_SUCCESS)
gimp_set_data (SAVE_PROC, &dds_write_vals, sizeof (dds_write_vals));
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image);
return gimp_procedure_new_return_values (procedure, status, error);
}
static GimpValueArray *
dds_decode (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
const GimpValueArray *args,
gpointer run_data)
{
const gchar *name = gimp_procedure_get_name (procedure);
if (! strcmp (name, DECODE_YCOCG_PROC))
{
decode_ycocg_image (drawable, TRUE);
}
else if (! strcmp (name, DECODE_YCOCG_SCALED_PROC))
{
decode_ycocg_scaled_image (drawable, TRUE);
}
else if (! strcmp (name, DECODE_ALPHA_EXP_PROC))
{
decode_alpha_exp_image (drawable, TRUE);
}
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_displays_flush ();
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
}

View file

@ -57,13 +57,13 @@ typedef struct
extern DDSWriteVals dds_write_vals;
extern DDSReadVals dds_read_vals;
extern GimpPDBStatusType read_dds (gchar *filename,
gint32 *imageID,
gboolean interactive_dds);
extern GimpPDBStatusType write_dds (gchar *filename,
gint32 image_id,
gint32 drawable_id,
gboolean interactive_dds);
extern GimpPDBStatusType read_dds (gchar *filename,
GimpImage **image,
gboolean interactive_dds);
extern GimpPDBStatusType write_dds (gchar *filename,
GimpImage *image,
GimpDrawable *drawable,
gboolean interactive_dds);
#define LOAD_PROC "file-dds-load"

View file

@ -69,7 +69,7 @@ static int setup_dxgi_format (dds_header_t *hdr,
static int load_layer (FILE *fp,
dds_header_t *hdr,
dds_load_info_t *d,
gint32 image,
GimpImage *image,
unsigned int level,
char *prefix,
unsigned int *l,
@ -78,7 +78,7 @@ static int load_layer (FILE *fp,
static int load_mipmaps (FILE *fp,
dds_header_t *hdr,
dds_load_info_t *d,
gint32 image,
GimpImage *image,
char *prefix,
unsigned int *l,
guchar *pixels,
@ -86,7 +86,7 @@ static int load_mipmaps (FILE *fp,
static int load_face (FILE *fp,
dds_header_t *hdr,
dds_load_info_t *d,
gint32 image,
GimpImage *image,
char *prefix,
unsigned int *l,
guchar *pixels,
@ -98,11 +98,11 @@ static int load_dialog (void);
static gboolean runme = FALSE;
GimpPDBStatusType
read_dds (gchar *filename,
gint32 *imageID,
gboolean interactive_dds)
read_dds (gchar *filename,
GimpImage **ret_image,
gboolean interactive_dds)
{
gint32 image = 0;
GimpImage *image = NULL;
unsigned char *buf;
unsigned int l = 0;
guchar *pixels;
@ -111,13 +111,13 @@ read_dds (gchar *filename,
dds_header_t hdr;
dds_header_dx10_t dx10hdr;
dds_load_info_t d;
gint *layers, layer_count;
GList *layers;
GimpImageBaseType type;
int i, j;
if (interactive_dds)
{
if (!load_dialog ())
if (! load_dialog ())
return GIMP_PDB_CANCEL;
}
@ -275,7 +275,7 @@ read_dds (gchar *filename,
image = gimp_image_new (hdr.width, hdr.height, type);
if (image == -1)
if (! image)
{
g_message ("Can't allocate new image.\n");
fclose (fp);
@ -457,18 +457,18 @@ read_dds (gchar *filename,
g_free (pixels);
fclose (fp);
layers = gimp_image_get_layers (image, &layer_count);
layers = gimp_image_list_layers (image);
if (layers == NULL || layer_count == 0)
if (! layers)
{
g_message ("Oops! NULL image read! Please report this!");
return GIMP_PDB_EXECUTION_ERROR;
}
gimp_image_set_active_layer (image, layers[0]);
g_free (layers);
gimp_image_set_active_layer (image, layers->data);
g_list_free (layers);
*imageID = image;
*ret_image = image;
return GIMP_PDB_SUCCESS;
}
@ -849,7 +849,7 @@ static int
load_layer (FILE *fp,
dds_header_t *hdr,
dds_load_info_t *d,
gint32 image,
GimpImage *image,
unsigned int level,
char *prefix,
unsigned int *l,
@ -861,7 +861,7 @@ load_layer (FILE *fp,
GimpImageType type = GIMP_RGBA_IMAGE;
gchar *layer_name;
gint x, y, z, n;
gint32 layer;
GimpLayer *layer;
unsigned int width = hdr->width >> level;
unsigned int height = hdr->height >> level;
unsigned int size = hdr->pitch_or_linsize >> (2 * level);
@ -925,14 +925,14 @@ load_layer (FILE *fp,
g_strdup_printf ("main surface %s", prefix);
layer = gimp_layer_new (image, layer_name, width, height, type, 100,
GIMP_LAYER_MODE_NORMAL);
gimp_image_get_default_new_layer_mode (image));
g_free (layer_name);
gimp_image_insert_layer (image, layer, 0, *l);
gimp_image_insert_layer (image, layer, NULL, *l);
if ((*l)++) gimp_item_set_visible (layer, FALSE);
if ((*l)++) gimp_item_set_visible (GIMP_ITEM (layer), FALSE);
buffer = gimp_drawable_get_buffer (layer);
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
layerw = gegl_buffer_get_width (buffer);
@ -1155,13 +1155,13 @@ load_layer (FILE *fp,
switch (hdr->reserved.gimp_dds_special.extra_fourcc)
{
case FOURCC ('A','E','X','P'):
decode_alpha_exp_image (layer, FALSE);
decode_alpha_exp_image (GIMP_DRAWABLE (layer), FALSE);
break;
case FOURCC ('Y','C','G','1'):
decode_ycocg_image (layer, FALSE);
decode_ycocg_image (GIMP_DRAWABLE (layer), FALSE);
break;
case FOURCC ('Y','C','G','2'):
decode_ycocg_scaled_image (layer, FALSE);
decode_ycocg_scaled_image (GIMP_DRAWABLE (layer), FALSE);
break;
default:
break;
@ -1175,7 +1175,7 @@ static int
load_mipmaps (FILE *fp,
dds_header_t *hdr,
dds_load_info_t *d,
gint32 image,
GimpImage *image,
char *prefix,
unsigned int *l,
guchar *pixels,
@ -1201,7 +1201,7 @@ static int
load_face (FILE *fp,
dds_header_t *hdr,
dds_load_info_t *d,
gint32 image,
GimpImage *image,
char *prefix,
unsigned int *l,
guchar *pixels,

View file

@ -52,14 +52,14 @@ enum
};
static gint save_dialog (gint32 image_id,
gint32 drawable);
static void save_dialog_response (GtkWidget *widget,
gint response_id,
gpointer data);
static gboolean write_image (FILE *fp,
gint32 image_id,
gint32 drawable_id);
static gint save_dialog (GimpImage *image,
GimpDrawable *drawable);
static void save_dialog_response (GtkWidget *widget,
gint response_id,
gpointer data);
static gboolean write_image (FILE *fp,
GimpImage *image,
GimpDrawable *drawable);
static gboolean runme = FALSE;
@ -88,11 +88,11 @@ static const char *cubemap_face_names[4][6] =
}
};
static gint cubemap_faces[6];
static gboolean is_cubemap = FALSE;
static gboolean is_volume = FALSE;
static gboolean is_array = FALSE;
static gboolean is_mipmap_chain_valid = FALSE;
static GimpLayer *cubemap_faces[6];
static gboolean is_cubemap = FALSE;
static gboolean is_volume = FALSE;
static gboolean is_array = FALSE;
static gboolean is_mipmap_chain_valid = FALSE;
static GtkWidget *compress_opt;
static GtkWidget *format_opt;
@ -218,16 +218,17 @@ static struct
static gboolean
check_mipmaps (gint32 image_id,
gint savetype)
check_mipmaps (GimpImage *image,
gint savetype)
{
gint *layers;
gint num_layers;
gint i, j, w, h, mipw, miph;
gint num_mipmaps;
gint num_surfaces = 0;
gint min_surfaces = 1;
gint max_surfaces = 1;
GList *layers;
GList *list;
gint num_layers;
gint i, j, w, h, mipw, miph;
gint num_mipmaps;
gint num_surfaces = 0;
gint min_surfaces = 1;
gint max_surfaces = 1;
gboolean valid = TRUE;
GimpImageType type;
@ -246,22 +247,23 @@ check_mipmaps (gint32 image_id,
max_surfaces = INT_MAX;
}
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
w = gimp_image_width (image_id);
h = gimp_image_height (image_id);
w = gimp_image_width (image);
h = gimp_image_height (image);
num_mipmaps = get_num_mipmaps (w, h);
type = gimp_drawable_type (layers[0]);
type = gimp_drawable_type (layers->data);
for (i = 0; i < num_layers; ++i)
for (list = layers; list; list = g_list_next (list))
{
if (type != gimp_drawable_type (layers[i]))
if (type != gimp_drawable_type (list->data))
return 0;
if ((gimp_drawable_width (layers[i]) == w) &&
(gimp_drawable_height (layers[i]) == h))
if ((gimp_drawable_width (list->data) == w) &&
(gimp_drawable_height (list->data) == h))
++num_surfaces;
}
@ -272,8 +274,10 @@ check_mipmaps (gint32 image_id,
for (i = 0; valid && i < num_layers; i += num_mipmaps)
{
if ((gimp_drawable_width (layers[i]) != w) ||
(gimp_drawable_height (layers[i]) != h))
GimpDrawable *drawable = g_list_nth_data (layers, i);
if ((gimp_drawable_width (drawable) != w) ||
(gimp_drawable_height (drawable) != h))
{
valid = FALSE;
break;
@ -281,12 +285,14 @@ check_mipmaps (gint32 image_id,
for (j = 1; j < num_mipmaps; ++j)
{
drawable = g_list_nth_data (layers, i + j);
mipw = w >> j;
miph = h >> j;
if (mipw < 1) mipw = 1;
if (miph < 1) miph = 1;
if ((gimp_drawable_width (layers[i + j]) != mipw) ||
(gimp_drawable_height (layers[i + j]) != miph))
if ((gimp_drawable_width (drawable) != mipw) ||
(gimp_drawable_height (drawable) != miph))
{
valid = FALSE;
break;
@ -298,16 +304,18 @@ check_mipmaps (gint32 image_id,
}
static gboolean
check_cubemap (gint32 image_id)
check_cubemap (GimpImage *image)
{
gint *layers;
gint num_layers;
GList *layers;
GList *list;
gint num_layers;
gboolean cubemap = TRUE;
gint i, j, k, w, h;
gchar *layer_name;
GimpImageType type;
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
if (num_layers < 6)
return FALSE;
@ -316,33 +324,37 @@ check_cubemap (gint32 image_id)
if (num_layers > 6)
{
/* check that mipmap layers are in order for a cubemap */
if (! check_mipmaps (image_id, DDS_SAVE_CUBEMAP))
if (! check_mipmaps (image, DDS_SAVE_CUBEMAP))
return FALSE;
/* invalidate cubemap faces */
for (i = 0; i < 6; ++i)
cubemap_faces[i] = -1;
cubemap_faces[i] = NULL;
/* find the mipmap level 0 layers */
w = gimp_image_width (image_id);
h = gimp_image_height (image_id);
w = gimp_image_width (image);
h = gimp_image_height (image);
for (i = 0; i < num_layers; ++i)
for (i = 0, list = layers;
i < num_layers;
++i, list = g_list_next (list))
{
if ((gimp_drawable_width (layers[i]) != w) ||
(gimp_drawable_height (layers[i]) != h))
GimpDrawable *drawable = list->data;
if ((gimp_drawable_width (drawable) != w) ||
(gimp_drawable_height (drawable) != h))
continue;
layer_name = (char*)gimp_item_get_name (layers[i]);
layer_name = (char *) gimp_item_get_name (GIMP_ITEM (drawable));
for (j = 0; j < 6; ++j)
{
for (k = 0; k < 4; ++k)
{
if (strstr (layer_name, cubemap_face_names[k][j]))
{
if (cubemap_faces[j] == -1)
if (cubemap_faces[j] == NULL)
{
cubemap_faces[j] = layers[i];
cubemap_faces[j] = GIMP_LAYER (drawable);
break;
}
}
@ -353,7 +365,7 @@ check_cubemap (gint32 image_id)
/* check for 6 valid faces */
for (i = 0; i < 6; ++i)
{
if (cubemap_faces[i] == -1)
if (cubemap_faces[i] == NULL)
{
cubemap = FALSE;
break;
@ -363,10 +375,10 @@ check_cubemap (gint32 image_id)
/* make sure they are all the same type */
if (cubemap)
{
type = gimp_drawable_type (cubemap_faces[0]);
type = gimp_drawable_type (GIMP_DRAWABLE (cubemap_faces[0]));
for (i = 1; i < 6 && cubemap; ++i)
{
if (gimp_drawable_type (cubemap_faces[i]) != type)
if (gimp_drawable_type (GIMP_DRAWABLE (cubemap_faces[i])) != type)
cubemap = FALSE;
}
}
@ -376,20 +388,25 @@ check_cubemap (gint32 image_id)
{
/* invalidate cubemap faces */
for (i = 0; i < 6; ++i)
cubemap_faces[i] = -1;
cubemap_faces[i] = NULL;
for (i = 0; i < 6; ++i)
for (i = 0, list = layers;
i < 6;
++i, list = g_list_next (layers))
{
layer_name = (char*)gimp_item_get_name (layers[i]);
GimpLayer *layer = list->data;
layer_name = (gchar *) gimp_item_get_name (GIMP_ITEM (layer));
for (j = 0; j < 6; ++j)
{
for (k = 0; k < 4; ++k)
{
if (strstr (layer_name, cubemap_face_names[k][j]))
{
if (cubemap_faces[j] == -1)
if (cubemap_faces[j] == NULL)
{
cubemap_faces[j] = layers[i];
cubemap_faces[j] = layer;
break;
}
}
@ -400,7 +417,7 @@ check_cubemap (gint32 image_id)
/* check for 6 valid faces */
for (i = 0; i < 6; ++i)
{
if (cubemap_faces[i] == -1)
if (cubemap_faces[i] == NULL)
{
cubemap = FALSE;
break;
@ -410,13 +427,13 @@ check_cubemap (gint32 image_id)
/* make sure they are all the same size */
if (cubemap)
{
w = gimp_drawable_width (cubemap_faces[0]);
h = gimp_drawable_height (cubemap_faces[0]);
w = gimp_drawable_width (GIMP_DRAWABLE (cubemap_faces[0]));
h = gimp_drawable_height (GIMP_DRAWABLE (cubemap_faces[0]));
for (i = 1; i < 6 && cubemap; ++i)
{
if ((gimp_drawable_width (cubemap_faces[i]) != w) ||
(gimp_drawable_height (cubemap_faces[i]) != h))
if ((gimp_drawable_width (GIMP_DRAWABLE (cubemap_faces[i])) != w) ||
(gimp_drawable_height (GIMP_DRAWABLE (cubemap_faces[i])) != h))
cubemap = FALSE;
}
}
@ -424,10 +441,10 @@ check_cubemap (gint32 image_id)
/* make sure they are all the same type */
if (cubemap)
{
type = gimp_drawable_type (cubemap_faces[0]);
type = gimp_drawable_type (GIMP_DRAWABLE (cubemap_faces[0]));
for (i = 1; i < 6 && cubemap; ++i)
{
if (gimp_drawable_type (cubemap_faces[i]) != type)
if (gimp_drawable_type (GIMP_DRAWABLE (cubemap_faces[i])) != type)
cubemap = FALSE;
}
}
@ -437,38 +454,45 @@ check_cubemap (gint32 image_id)
}
static gboolean
check_volume (gint32 image_id)
check_volume (GimpImage *image)
{
gint *layers;
gint num_layers;
GList *layers;
GList *list;
gint num_layers;
gboolean volume = FALSE;
gint i, w, h;
GimpImageType type;
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
if (num_layers > 1)
{
volume = TRUE;
/* make sure all layers are the same size */
w = gimp_drawable_width (layers[0]);
h = gimp_drawable_height (layers[0]);
w = gimp_drawable_width (layers->data);
h = gimp_drawable_height (layers->data);
for (i = 1; i < num_layers && volume; ++i)
for (i = 1, list = layers->next;
i < num_layers && volume;
++i, list = g_list_next (list))
{
if ((gimp_drawable_width (layers[i]) != w) ||
(gimp_drawable_height (layers[i]) != h))
if ((gimp_drawable_width (list->data) != w) ||
(gimp_drawable_height (list->data) != h))
volume = FALSE;
}
if (volume)
{
/* make sure all layers are the same type */
type = gimp_drawable_type (layers[0]);
for (i = 1; i < num_layers && volume; ++i)
type = gimp_drawable_type (layers->data);
for (i = 1, list = layers->next;
i < num_layers && volume;
++i, list = g_list_next (list))
{
if (gimp_drawable_type (layers[i]) != type)
if (gimp_drawable_type (list->data) != type)
volume = FALSE;
}
}
@ -478,41 +502,49 @@ check_volume (gint32 image_id)
}
static gboolean
check_array (gint32 image_id)
check_array (GimpImage *image)
{
gint *layers;
gint num_layers;
GList *layers;
gint num_layers;
gboolean array = FALSE;
gint i, w, h;
GimpImageType type;
if (check_mipmaps (image_id, DDS_SAVE_ARRAY))
if (check_mipmaps (image, DDS_SAVE_ARRAY))
return 1;
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
if (num_layers > 1)
{
GList *list;
array = TRUE;
/* make sure all layers are the same size */
w = gimp_drawable_width (layers[0]);
h = gimp_drawable_height (layers[0]);
w = gimp_drawable_width (layers->data);
h = gimp_drawable_height (layers->data);
for (i = 1; i < num_layers && array; ++i)
for (i = 1, list = g_list_next (layers);
i < num_layers && array;
++i, list = g_list_next (list))
{
if ((gimp_drawable_width (layers[i]) != w) ||
(gimp_drawable_height (layers[i]) != h))
if ((gimp_drawable_width (list->data) != w) ||
(gimp_drawable_height (list->data) != h))
array = FALSE;
}
if (array)
{
/* make sure all layers are the same type */
type = gimp_drawable_type (layers[0]);
for (i = 1; i < num_layers; ++i)
type = gimp_drawable_type (layers->data);
for (i = 1, list = g_list_next (layers);
i < num_layers;
++i, list = g_list_next (list))
{
if (gimp_drawable_type (layers[i]) != type)
if (gimp_drawable_type (list->data) != type)
{
array = FALSE;
break;
@ -521,49 +553,57 @@ check_array (gint32 image_id)
}
}
g_list_free (layers);
return array;
}
static int
get_array_size (gint32 image_id)
get_array_size (GimpImage *image)
{
gint *layers;
gint num_layers;
gint i, w, h;
gint elements = 0;
GList *layers;
GList *list;
gint num_layers;
gint i, w, h;
gint elements = 0;
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
w = gimp_image_width (image_id);
h = gimp_image_height (image_id);
w = gimp_image_width (image);
h = gimp_image_height (image);
for (i = 0; i < num_layers; ++i)
for (i = 0, list = layers;
i < num_layers;
++i, list = g_list_next (list))
{
if ((gimp_drawable_width (layers[i]) == w) &&
(gimp_drawable_height (layers[i]) == h))
if ((gimp_drawable_width (list->data) == w) &&
(gimp_drawable_height (list->data) == h))
{
elements++;
}
}
g_list_free (layers);
return elements;
}
GimpPDBStatusType
write_dds (gchar *filename,
gint32 image_id,
gint32 drawable_id,
gboolean interactive_dds)
write_dds (gchar *filename,
GimpImage *image,
GimpDrawable *drawable,
gboolean interactive_dds)
{
FILE *fp;
gchar *tmp;
int rc = 0;
is_mipmap_chain_valid = check_mipmaps (image_id, dds_write_vals.savetype);
is_mipmap_chain_valid = check_mipmaps (image, dds_write_vals.savetype);
is_cubemap = check_cubemap (image_id);
is_volume = check_volume (image_id);
is_array = check_array (image_id);
is_cubemap = check_cubemap (image);
is_volume = check_volume (image);
is_array = check_array (image);
if (interactive_dds)
{
@ -571,7 +611,7 @@ write_dds (gchar *filename,
dds_write_vals.mipmaps == DDS_MIPMAP_EXISTING)
dds_write_vals.mipmaps = DDS_MIPMAP_NONE;
if (! save_dialog (image_id, drawable_id))
if (! save_dialog (image, drawable))
return GIMP_PDB_CANCEL;
}
else
@ -617,7 +657,7 @@ write_dds (gchar *filename,
gimp_progress_init (tmp);
g_free (tmp);
rc = write_image (fp, image_id, drawable_id);
rc = write_image (fp, image, drawable);
fclose (fp);
@ -803,10 +843,12 @@ get_mipmap_chain (unsigned char *dst,
int w,
int h,
int bpp,
gint32 image_id,
gint drawable_id)
GimpImage *image,
GimpDrawable *drawable)
{
gint *layers, num_layers;
GList *layers;
GList *list;
gint num_layers;
GeglBuffer *buffer;
const Babl *format = 0;
int i, idx = 0, offset, mipw, miph;
@ -820,24 +862,28 @@ get_mipmap_chain (unsigned char *dst,
else
format = babl_format ("R'G'B'A u8");
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
for (i = 0; i < num_layers; ++i)
for (i = 0, list = layers;
i < num_layers;
++i, list = g_list_next (list))
{
if (layers[i] == drawable_id)
if (list->data == drawable)
{
idx = i;
break;
}
}
if (i == num_layers) return;
if (i == num_layers)
return;
offset = 0;
while (get_next_mipmap_dimensions (&mipw, &miph, w, h))
{
buffer = gimp_drawable_get_buffer (layers[++idx]);
buffer = gimp_drawable_get_buffer (g_list_nth_data (layers, ++idx));
if ((gegl_buffer_get_width (buffer) != mipw) ||
(gegl_buffer_get_height (buffer) != miph))
@ -861,14 +907,14 @@ get_mipmap_chain (unsigned char *dst,
}
static void
write_layer (FILE *fp,
gint32 image_id,
gint32 drawable_id,
int w,
int h,
int bpp,
int fmtbpp,
int mipmaps)
write_layer (FILE *fp,
GimpImage *image,
GimpDrawable *drawable,
int w,
int h,
int bpp,
int fmtbpp,
int mipmaps)
{
GeglBuffer *buffer;
const Babl *format = 0;
@ -880,10 +926,10 @@ write_layer (FILE *fp,
int compression = dds_write_vals.compression;
int flags = 0;
basetype = gimp_image_base_type (image_id);
type = gimp_drawable_type (drawable_id);
basetype = gimp_image_base_type (image);
type = gimp_drawable_type (drawable);
buffer = gimp_drawable_get_buffer (drawable_id);
buffer = gimp_drawable_get_buffer (drawable);
src = g_malloc (w * h * bpp);
@ -901,7 +947,7 @@ write_layer (FILE *fp,
if (basetype == GIMP_INDEXED)
{
palette = gimp_image_get_colormap (image_id, &colors);
palette = gimp_image_get_colormap (image, &colors);
if (type == GIMP_INDEXEDA_IMAGE)
{
@ -1029,7 +1075,7 @@ write_layer (FILE *fp,
else
{
memcpy (dst, src, w * h * bpp);
get_mipmap_chain (dst + (w * h * bpp), w, h, bpp, image_id, drawable_id);
get_mipmap_chain (dst + (w * h * bpp), w, h, bpp, image, drawable);
}
if (dds_write_vals.format > DDS_FORMAT_DEFAULT)
@ -1108,7 +1154,7 @@ write_layer (FILE *fp,
else
{
memcpy (fmtdst, src, w * h * bpp);
get_mipmap_chain (fmtdst + (w * h * bpp), w, h, bpp, image_id, drawable_id);
get_mipmap_chain (fmtdst + (w * h * bpp), w, h, bpp, image, drawable);
}
g_free (src);
@ -1131,16 +1177,17 @@ write_layer (FILE *fp,
}
static void
write_volume_mipmaps (FILE *fp,
gint32 image_id,
gint32 *layers,
int w,
int h,
int d,
int bpp,
int fmtbpp,
int mipmaps)
write_volume_mipmaps (FILE *fp,
GimpImage *image,
GList *layers,
int w,
int h,
int d,
int bpp,
int fmtbpp,
int mipmaps)
{
GList *list;
int i, size, offset, colors;
unsigned char *src, *dst, *tmp, *fmtdst;
unsigned char *palette = 0;
@ -1148,7 +1195,7 @@ write_volume_mipmaps (FILE *fp,
const Babl *format;
GimpImageBaseType type;
type = gimp_image_base_type (image_id);
type = gimp_image_base_type (image);
if (dds_write_vals.compression != DDS_COMPRESS_NONE) return;
@ -1163,20 +1210,22 @@ write_volume_mipmaps (FILE *fp,
else
format = babl_format ("R'G'B'A u8");
if (gimp_image_base_type (image_id) == GIMP_INDEXED)
palette = gimp_image_get_colormap (image_id, &colors);
if (gimp_image_base_type (image) == GIMP_INDEXED)
palette = gimp_image_get_colormap (image, &colors);
offset = 0;
for (i = 0; i < d; ++i)
for (i = 0, list = layers;
i < d;
++i, list = g_list_next (list))
{
buffer = gimp_drawable_get_buffer (layers[i]);
buffer = gimp_drawable_get_buffer (list->data);
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0, format,
src + offset, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
offset += (w * h * bpp);
g_object_unref (buffer);
}
if (gimp_drawable_type (layers[0]) == GIMP_INDEXEDA_IMAGE)
if (gimp_drawable_type (layers->data) == GIMP_INDEXEDA_IMAGE)
{
tmp = g_malloc (w * h * d);
for (i = 0; i < w * h * d; ++i)
@ -1241,9 +1290,9 @@ write_volume_mipmaps (FILE *fp,
}
static gboolean
write_image (FILE *fp,
gint32 image_id,
gint32 drawable_id)
write_image (FILE *fp,
GimpImage *image,
GimpDrawable *drawable)
{
GimpImageType drawable_type;
GimpImageBaseType basetype;
@ -1259,31 +1308,33 @@ write_image (FILE *fp,
guint fourcc = 0;
DXGI_FORMAT dxgi_format = DXGI_FORMAT_UNKNOWN;
gint32 num_layers;
gint32 *layers;
GList *layers;
GList *list;
guchar *cmap;
gint colors;
guchar zero[4] = {0, 0, 0, 0};
gint is_dx10 = 0;
gint array_size = 1;
layers = gimp_image_get_layers (image_id, &num_layers);
layers = gimp_image_list_layers (image);
num_layers = g_list_length (layers);
if (dds_write_vals.mipmaps == DDS_MIPMAP_EXISTING)
drawable_id = layers[0];
drawable = layers->data;
if (dds_write_vals.savetype == DDS_SAVE_SELECTED_LAYER)
{
w = gimp_drawable_width (drawable_id);
h = gimp_drawable_height (drawable_id);
w = gimp_drawable_width (drawable);
h = gimp_drawable_height (drawable);
}
else
{
w = gimp_image_width (image_id);
h = gimp_image_height (image_id);
w = gimp_image_width (image);
h = gimp_image_height (image);
}
basetype = gimp_image_base_type (image_id);
drawable_type = gimp_drawable_type (drawable_id);
basetype = gimp_image_base_type (image);
drawable_type = gimp_drawable_type (drawable);
switch (drawable_type)
{
@ -1569,7 +1620,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) ?
1 : get_array_size (image));
PUTL32 (hdr10 + 0, dxgi_format);
PUTL32 (hdr10 + 4, D3D10_RESOURCE_DIMENSION_TEXTURE2D);
@ -1592,7 +1644,7 @@ write_image (FILE *fp,
(dds_write_vals.format == DDS_FORMAT_DEFAULT) &&
(dds_write_vals.compression == DDS_COMPRESS_NONE))
{
cmap = gimp_image_get_colormap (image_id, &colors);
cmap = gimp_image_get_colormap (image, &colors);
for (i = 0; i < colors; ++i)
{
@ -1611,31 +1663,36 @@ write_image (FILE *fp,
{
for (i = 0; i < 6; ++i)
{
write_layer (fp, image_id, cubemap_faces[i], w, h, bpp, fmtbpp,
write_layer (fp, image, GIMP_DRAWABLE (cubemap_faces[i]),
w, h, bpp, fmtbpp,
num_mipmaps);
gimp_progress_update ((float)(i + 1) / 6.0);
}
}
else if (dds_write_vals.savetype == DDS_SAVE_VOLUMEMAP)
{
for (i = 0; i < num_layers; ++i)
for (i = 0, list = layers;
i < num_layers;
++i, list = g_list_next (layers))
{
write_layer (fp, image_id, layers[i], w, h, bpp, fmtbpp, 1);
write_layer (fp, image, list->data, w, h, bpp, fmtbpp, 1);
gimp_progress_update ((float)i / (float)num_layers);
}
if (num_mipmaps > 1)
write_volume_mipmaps (fp, image_id, layers, w, h, num_layers,
write_volume_mipmaps (fp, image, layers, w, h, num_layers,
bpp, fmtbpp, num_mipmaps);
}
else if (dds_write_vals.savetype == DDS_SAVE_ARRAY)
{
for (i = 0; i < num_layers; ++i)
for (i = 0, list = layers;
i < num_layers;
++i, list = g_list_next (layers))
{
if ((gimp_drawable_width (layers[i]) == w) &&
(gimp_drawable_height (layers[i]) == h))
if ((gimp_drawable_width (list->data) == w) &&
(gimp_drawable_height (list->data) == h))
{
write_layer (fp, image_id, layers[i],
write_layer (fp, image, list->data,
w, h, bpp, fmtbpp, num_mipmaps);
}
@ -1644,7 +1701,7 @@ write_image (FILE *fp,
}
else
{
write_layer (fp, image_id, drawable_id, w, h, bpp, fmtbpp, num_mipmaps);
write_layer (fp, image, drawable, w, h, bpp, fmtbpp, num_mipmaps);
}
gimp_progress_update (1.0);
@ -1789,7 +1846,7 @@ static void
savetype_selected (GtkWidget *widget,
gpointer data)
{
gint32 image_id = *((gint32 *)data);
GimpImage *image = data;
dds_write_vals.savetype = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
@ -1810,7 +1867,7 @@ savetype_selected (GtkWidget *widget,
}
string_value_combo_set_item_sensitive (mipmap_opt, DDS_MIPMAP_EXISTING,
check_mipmaps (image_id, dds_write_vals.savetype));
check_mipmaps (image, dds_write_vals.savetype));
}
static void
@ -1933,8 +1990,8 @@ alpha_test_threshold_changed (GtkWidget *widget,
}
static gint
save_dialog (gint32 image_id,
gint32 drawable_id)
save_dialog (GimpImage *image,
GimpDrawable *drawable)
{
GtkWidget *dlg;
GtkWidget *vbox;
@ -1949,7 +2006,7 @@ save_dialog (gint32 image_id,
if (is_cubemap || is_volume || is_array)
dds_write_vals.savetype = DDS_SAVE_SELECTED_LAYER;
basetype = gimp_image_base_type (image_id);
basetype = gimp_image_base_type (image);
dlg = gimp_dialog_new (_("Export as DDS"), "dds", NULL, GTK_WIN_POS_MOUSE,
gimp_standard_help_func, SAVE_PROC,
@ -2025,7 +2082,7 @@ save_dialog (gint32 image_id,
g_signal_connect (opt, "changed",
G_CALLBACK (savetype_selected),
&image_id);
image);
string_value_combo_set_item_sensitive (opt, DDS_SAVE_CUBEMAP, is_cubemap);
string_value_combo_set_item_sensitive (opt, DDS_SAVE_VOLUMEMAP, is_volume);
@ -2039,10 +2096,10 @@ save_dialog (gint32 image_id,
g_signal_connect (opt, "changed",
G_CALLBACK (mipmaps_selected),
&image_id);
image);
string_value_combo_set_item_sensitive (opt, DDS_MIPMAP_EXISTING,
check_mipmaps (image_id,
check_mipmaps (image,
dds_write_vals.savetype));
mipmap_opt = opt;

View file

@ -33,8 +33,8 @@ saturate (float a)
}
void
decode_ycocg_image (gint32 drawableID,
gboolean shadow)
decode_ycocg_image (GimpDrawable *drawable,
gboolean shadow)
{
GeglBuffer *buffer, *sbuffer;
const Babl *format;
@ -44,11 +44,11 @@ decode_ycocg_image (gint32 drawableID,
const float offset = 0.5f * 256.0f / 255.0f;
float Y, Co, Cg, R, G, B;
buffer = gimp_drawable_get_buffer (drawableID);
buffer = gimp_drawable_get_buffer (drawable);
if (shadow)
{
sbuffer = gimp_drawable_get_shadow_buffer (drawableID);
sbuffer = gimp_drawable_get_shadow_buffer (drawable);
gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref (buffer);
buffer = sbuffer;
@ -100,9 +100,9 @@ decode_ycocg_image (gint32 drawableID,
gegl_buffer_flush (buffer);
if (shadow)
gimp_drawable_merge_shadow (drawableID, TRUE);
gimp_drawable_merge_shadow (drawable, TRUE);
gimp_drawable_update (drawableID, 0, 0, w, h);
gimp_drawable_update (drawable, 0, 0, w, h);
g_free (data);
@ -110,8 +110,8 @@ decode_ycocg_image (gint32 drawableID,
}
void
decode_ycocg_scaled_image (gint32 drawableID,
gboolean shadow)
decode_ycocg_scaled_image (GimpDrawable *drawable,
gboolean shadow)
{
GeglBuffer *buffer, *sbuffer;
const Babl *format;
@ -121,13 +121,13 @@ decode_ycocg_scaled_image (gint32 drawableID,
const float offset = 0.5f * 256.0f / 255.0f;
float Y, Co, Cg, R, G, B, s;
buffer = gimp_drawable_get_buffer (drawableID);
buffer = gimp_drawable_get_buffer (drawable);
if (shadow)
{
sbuffer = gimp_drawable_get_shadow_buffer(drawableID);
gegl_buffer_copy(buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref(buffer);
sbuffer = gimp_drawable_get_shadow_buffer (drawable);
gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref (buffer);
buffer = sbuffer;
}
@ -180,9 +180,9 @@ decode_ycocg_scaled_image (gint32 drawableID,
gegl_buffer_flush (buffer);
if (shadow)
gimp_drawable_merge_shadow (drawableID, TRUE);
gimp_drawable_merge_shadow (drawable, TRUE);
gimp_drawable_update (drawableID, 0, 0, w, h);
gimp_drawable_update (drawable, 0, 0, w, h);
g_free (data);
@ -190,8 +190,8 @@ decode_ycocg_scaled_image (gint32 drawableID,
}
void
decode_alpha_exp_image (gint32 drawableID,
gboolean shadow)
decode_alpha_exp_image (GimpDrawable *drawable,
gboolean shadow)
{
GeglBuffer *buffer, *sbuffer;
const Babl *format;
@ -199,11 +199,11 @@ decode_alpha_exp_image (gint32 drawableID,
unsigned int i, w, h, num_pixels;
int R, G, B, A;
buffer = gimp_drawable_get_buffer (drawableID);
buffer = gimp_drawable_get_buffer (drawable);
if (shadow)
{
sbuffer = gimp_drawable_get_shadow_buffer (drawableID);
sbuffer = gimp_drawable_get_shadow_buffer (drawable);
gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, sbuffer, NULL);
g_object_unref (buffer);
buffer = sbuffer;
@ -251,9 +251,9 @@ decode_alpha_exp_image (gint32 drawableID,
gegl_buffer_flush (buffer);
if (shadow)
gimp_drawable_merge_shadow (drawableID, TRUE);
gimp_drawable_merge_shadow (drawable, TRUE);
gimp_drawable_update (drawableID, 0, 0, w, h);
gimp_drawable_update (drawable, 0, 0, w, h);
g_free (data);

View file

@ -21,11 +21,11 @@
#ifndef __MISC_H__
#define __MISC_H__
void decode_ycocg_image (gint32 drawableID,
gboolean shadow);
void decode_ycocg_scaled_image (gint32 drawableID,
gboolean shadow);
void decode_alpha_exp_image (gint32 drawableID,
gboolean shadow);
void decode_ycocg_image (GimpDrawable *drawable,
gboolean shadow);
void decode_ycocg_scaled_image (GimpDrawable *drawable,
gboolean shadow);
void decode_alpha_exp_image (GimpDrawable *drawable,
gboolean shadow);
#endif /* __MISC_H__ */