forked from openkylin/gimp
482 lines
18 KiB
C
482 lines
18 KiB
C
/*
|
|
* DDS GIMP plugin
|
|
*
|
|
* Copyright (C) 2004-2012 Shawn Kirst <skirst@gmail.com>,
|
|
* with parts (C) 2003 Arne Reuter <homepage@arnereuter.de> where specified.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 51 Franklin Street, Fifth Floor
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <libgimp/gimp.h>
|
|
#include <libgimp/gimpui.h>
|
|
|
|
#include <libgimp/stdplugins-intl.h>
|
|
|
|
#include "ddsplugin.h"
|
|
#include "dds.h"
|
|
#include "misc.h"
|
|
|
|
|
|
static void query (void);
|
|
static void run (const gchar *name,
|
|
gint nparams,
|
|
const GimpParam *param,
|
|
gint *nreturn_vals,
|
|
GimpParam **return_vals);
|
|
|
|
|
|
GimpPlugInInfo PLUG_IN_INFO =
|
|
{
|
|
0,
|
|
0,
|
|
query,
|
|
run
|
|
};
|
|
|
|
DDSWriteVals dds_write_vals =
|
|
{
|
|
DDS_COMPRESS_NONE,
|
|
DDS_MIPMAP_NONE,
|
|
DDS_SAVE_SELECTED_LAYER,
|
|
DDS_FORMAT_DEFAULT,
|
|
-1,
|
|
DDS_MIPMAP_FILTER_DEFAULT,
|
|
DDS_MIPMAP_WRAP_DEFAULT,
|
|
0,
|
|
0,
|
|
0.0,
|
|
0,
|
|
0,
|
|
0,
|
|
0.5
|
|
};
|
|
|
|
DDSReadVals dds_read_vals =
|
|
{
|
|
1,
|
|
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, 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"}
|
|
};
|
|
|
|
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[] =
|
|
{
|
|
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive"},
|
|
{ GIMP_PDB_IMAGE, "image", "Input image"},
|
|
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to save"}
|
|
};
|
|
#endif
|
|
|
|
|
|
MAIN ()
|
|
|
|
|
|
static void
|
|
query (void)
|
|
{
|
|
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);
|
|
|
|
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 (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",
|
|
"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");*/
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
run (const gchar *name,
|
|
gint nparams,
|
|
const GimpParam *param,
|
|
gint *nreturn_vals,
|
|
GimpParam **return_vals)
|
|
{
|
|
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);
|
|
|
|
run_mode = param[0].data.d_int32;
|
|
|
|
*nreturn_vals = 1;
|
|
*return_vals = values;
|
|
|
|
values[0].type = GIMP_PDB_STATUS;
|
|
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
|
{
|
|
status = read_dds (param[1].data.d_string, &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;
|
|
}
|
|
}
|
|
}
|
|
else if (! strcmp (name, SAVE_PROC) ||
|
|
! strcmp (name, SAVE_PROC2))
|
|
{
|
|
imageID = param[1].data.d_int32;
|
|
drawableID = param[2].data.d_int32;
|
|
|
|
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;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (run_mode)
|
|
{
|
|
case GIMP_RUN_INTERACTIVE:
|
|
gimp_get_data (SAVE_PROC, &dds_write_vals);
|
|
break;
|
|
|
|
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;
|
|
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))
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
|
|
if ((dds_write_vals.mipmaps < DDS_MIPMAP_NONE) ||
|
|
(dds_write_vals.mipmaps >= DDS_MIPMAP_MAX))
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
|
|
if ((dds_write_vals.savetype < DDS_SAVE_SELECTED_LAYER) ||
|
|
(dds_write_vals.savetype >= DDS_SAVE_MAX))
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
|
|
if ((dds_write_vals.format < DDS_FORMAT_DEFAULT) ||
|
|
(dds_write_vals.format >= DDS_FORMAT_MAX))
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
|
|
if ((dds_write_vals.mipmap_filter < DDS_MIPMAP_FILTER_DEFAULT) ||
|
|
(dds_write_vals.mipmap_filter >= DDS_MIPMAP_FILTER_MAX))
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
|
{
|
|
status = write_dds (param[3].data.d_string, imageID, drawableID,
|
|
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));
|
|
}
|
|
|
|
if (export == GIMP_EXPORT_EXPORT)
|
|
gimp_image_delete (imageID);
|
|
}
|
|
#if 0
|
|
else if (! strcmp (name, DECODE_YCOCG_PROC))
|
|
{
|
|
imageID = param[1].data.d_int32;
|
|
drawableID = param[2].data.d_int32;
|
|
|
|
decode_ycocg_image (drawableID, TRUE);
|
|
|
|
status = GIMP_PDB_SUCCESS;
|
|
|
|
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
|
gimp_displays_flush ();
|
|
}
|
|
else if (! strcmp (name, DECODE_YCOCG_SCALED_PROC))
|
|
{
|
|
imageID = param[1].data.d_int32;
|
|
drawableID = param[2].data.d_int32;
|
|
|
|
decode_ycocg_scaled_image (drawableID, TRUE);
|
|
|
|
status = GIMP_PDB_SUCCESS;
|
|
|
|
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
|
gimp_displays_flush ();
|
|
}
|
|
else if (! strcmp (name, DECODE_ALPHA_EXP_PROC))
|
|
{
|
|
imageID = param[1].data.d_int32;
|
|
drawableID = param[2].data.d_int32;
|
|
|
|
decode_alpha_exp_image (drawableID, TRUE);
|
|
|
|
status = GIMP_PDB_SUCCESS;
|
|
|
|
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
|
gimp_displays_flush ();
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
}
|
|
|
|
values[0].data.d_status = status;
|
|
}
|