Files
gimp/plug-ins/common/file-csource.c
Ell 98f7fc85ac plug-ins: in file-csource, add RLE support for RGB565
Currently, toggling RGB565 makes the RLE toggle insensitive, but
if RLE is checked beforehand RLE is used anyway, with incorrect
results.

Fix this by adding RLE support for RGB565 data.
2017-07-07 04:32:51 -04:00

1034 lines
29 KiB
C

/* CSource - GIMP Plugin to dump image data in RGB(A) format for C source
* Copyright (C) 1999 Tim Janik
*
* 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 3
* 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. If not, see <http://www.gnu.org/licenses/>.
*
* This plugin is heavily based on the header plugin by Spencer Kimball and
* Peter Mattis.
*/
#include "config.h"
#include <string.h>
#include <errno.h>
#include <glib/gstdio.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
#define SAVE_PROC "file-csource-save"
#define PLUG_IN_BINARY "file-csource"
#define PLUG_IN_ROLE "gimp-file-csource"
typedef struct
{
gchar *prefixed_name;
gchar *comment;
gboolean use_comment;
gboolean glib_types;
gboolean alpha;
gboolean rgb565;
gboolean use_macros;
gboolean use_rle;
gdouble opacity;
} Config;
static void query (void);
static void run (const gchar *name,
gint nparams,
const GimpParam *param,
gint *nreturn_vals,
GimpParam **return_vals);
static gboolean save_image (GFile *file,
Config *config,
gint32 image_ID,
gint32 drawable_ID,
GError **error);
static gboolean run_save_dialog (Config *config);
const GimpPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static Config config =
{
"gimp_image", /* prefixed_name */
NULL, /* comment */
FALSE, /* use_comment */
TRUE, /* glib_types */
FALSE, /* alpha */
FALSE, /* rgb565 */
FALSE, /* use_macros */
FALSE, /* use_rle */
100.0, /* opacity */
};
MAIN ()
static void
query (void)
{
static const GimpParamDef save_args[] =
{
{ GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0) }" },
{ 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 in" },
{ GIMP_PDB_STRING, "raw-filename", "The name of the file to save the image in" }
};
gimp_install_procedure (SAVE_PROC,
"Dump image data in RGB(A) format for C source",
"CSource cannot be run non-interactively.",
"Tim Janik",
"Tim Janik",
"1999",
N_("C source code"),
"RGB*",
GIMP_PLUGIN,
G_N_ELEMENTS (save_args), 0,
save_args, NULL);
gimp_register_file_handler_mime (SAVE_PROC, "text/x-csrc");
gimp_register_file_handler_uri (SAVE_PROC);
gimp_register_save_handler (SAVE_PROC, "c", "");
}
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;
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GError *error = NULL;
INIT_I18N ();
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 (run_mode == GIMP_RUN_INTERACTIVE &&
strcmp (name, SAVE_PROC) == 0)
{
gint32 image_ID = param[1].data.d_int32;
gint32 drawable_ID = param[2].data.d_int32;
GimpParasite *parasite;
gchar *x;
gimp_get_data (SAVE_PROC, &config);
config.prefixed_name = "gimp_image";
config.comment = NULL;
config.alpha = gimp_drawable_has_alpha (drawable_ID);
parasite = gimp_image_get_parasite (image_ID, "gimp-comment");
if (parasite)
{
config.comment = g_strndup (gimp_parasite_data (parasite),
gimp_parasite_data_size (parasite));
gimp_parasite_free (parasite);
}
x = config.comment;
gimp_ui_init (PLUG_IN_BINARY, FALSE);
export = gimp_export_image (&image_ID, &drawable_ID, "C Source",
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
return;
}
if (run_save_dialog (&config))
{
if (x != config.comment &&
!(x && config.comment && strcmp (x, config.comment) == 0))
{
if (!config.comment || !config.comment[0])
{
gimp_image_detach_parasite (image_ID, "gimp-comment");
}
else
{
parasite = gimp_parasite_new ("gimp-comment",
GIMP_PARASITE_PERSISTENT,
strlen (config.comment) + 1,
config.comment);
gimp_image_attach_parasite (image_ID, parasite);
gimp_parasite_free (parasite);
}
}
if (! save_image (g_file_new_for_uri (param[3].data.d_string),
&config, image_ID, drawable_ID, &error))
{
status = GIMP_PDB_EXECUTION_ERROR;
if (error)
{
*nreturn_vals = 2;
values[1].type = GIMP_PDB_STRING;
values[1].data.d_string = error->message;
}
}
else
{
gimp_set_data (SAVE_PROC, &config, sizeof (config));
}
}
else
{
status = GIMP_PDB_CANCEL;
}
if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image_ID);
}
else
{
status = GIMP_PDB_CALLING_ERROR;
}
values[0].data.d_status = status;
}
static gboolean
diff2_rgb565 (guint8 *ip)
{
return ip[0] != ip[2] || ip[1] != ip[3];
}
static gboolean
diff2_rgb (guint8 *ip)
{
return ip[0] != ip[3] || ip[1] != ip[4] || ip[2] != ip[5];
}
static gboolean
diff2_rgba (guint8 *ip)
{
return ip[0] != ip[4] || ip[1] != ip[5] || ip[2] != ip[6] || ip[3] != ip[7];
}
static guint8 *
rl_encode_rgbx (guint8 *bp,
guint8 *ip,
guint8 *limit,
guint bpp)
{
gboolean (*diff2_pix) (guint8 *);
guint8 *ilimit = limit - bpp;
switch (bpp)
{
case 2: diff2_pix = diff2_rgb565; break;
case 3: diff2_pix = diff2_rgb; break;
case 4: diff2_pix = diff2_rgba; break;
default: g_assert_not_reached ();
}
while (ip < limit)
{
g_assert (ip < ilimit); /* paranoid */
if (diff2_pix (ip))
{
guint8 *s_ip = ip;
guint l = 1;
ip += bpp;
while (l < 127 && ip < ilimit && diff2_pix (ip))
{ ip += bpp; l += 1; }
if (ip == ilimit && l < 127)
{ ip += bpp; l += 1; }
*(bp++) = l;
memcpy (bp, s_ip, l * bpp);
bp += l * bpp;
}
else
{
guint l = 2;
ip += bpp;
while (l < 127 && ip < ilimit && !diff2_pix (ip))
{ ip += bpp; l += 1; }
*(bp++) = l | 128;
memcpy (bp, ip, bpp);
ip += bpp;
bp += bpp;
}
if (ip == ilimit)
{
*(bp++) = 1;
memcpy (bp, ip, bpp);
ip += bpp;
bp += bpp;
}
}
return bp;
}
static gboolean print (GOutputStream *stream,
GError **error,
const gchar *format,
...) G_GNUC_PRINTF (3, 4);
static gboolean
print (GOutputStream *stream,
GError **error,
const gchar *format,
...)
{
va_list args;
gboolean success;
va_start (args, format);
success = g_output_stream_vprintf (stream, NULL, NULL,
error, format, args);
va_end (args);
return success;
}
static inline gboolean
save_rle_decoder (GOutputStream *output,
const gchar *macro_name,
const gchar *s_uint,
const gchar *s_uint_8,
guint bpp,
GError **error)
{
return
print (output, error,
"#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \\\n",
macro_name) &&
print (output, error,
"{ %s __bpp; %s *__ip; const %s *__il, *__rd; \\\n",
s_uint, s_uint_8, s_uint_8) &&
print (output, error,
" __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \\\n"
" __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \\\n"
" while (__ip < __il) { %s __l = *(__rd++); \\\n",
s_uint) &&
print (output, error,
" if (__l & 128) { __l = __l - 128; \\\n"
" do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \\\n"
" } else { __l *= 4; memcpy (__ip, __rd, __l); \\\n"
" __ip += __l; __rd += __l; } } \\\n"
" } else if (__bpp == 3) { /* RGB */ \\\n"
" while (__ip < __il) { %s __l = *(__rd++); \\\n",
s_uint) &&
print (output, error,
" if (__l & 128) { __l = __l - 128; \\\n"
" do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \\\n"
" } else { __l *= 3; memcpy (__ip, __rd, __l); \\\n"
" __ip += __l; __rd += __l; } } \\\n"
" } else { /* RGB16 */ \\\n"
" while (__ip < __il) { %s __l = *(__rd++); \\\n",
s_uint) &&
print (output, error,
" if (__l & 128) { __l = __l - 128; \\\n"
" do { memcpy (__ip, __rd, 2); __ip += 2; } while (--__l); __rd += 2; \\\n"
" } else { __l *= 2; memcpy (__ip, __rd, __l); \\\n"
" __ip += __l; __rd += __l; } } \\\n"
" } } while (0)\n");
}
static inline gboolean
save_uchar (GOutputStream *output,
guint *c,
guint8 d,
Config *config,
GError **error)
{
static guint8 pad = 0;
if (*c > 74)
{
if (! config->use_macros)
{
if (! print (output, error, "\"\n \""))
return FALSE;
*c = 3;
}
else
{
if (! print (output, error, "\"\n \""))
return FALSE;
*c = 2;
}
}
if (d < 33 || (d >= 48 && d <= 57) || d > 126)
{
if (! print (output, error, "\\%03o", d))
return FALSE;
*c += 1 + 1 + (d > 7) + (d > 63);
pad = d < 64;
return TRUE;
}
if (d == '\\')
{
if (! print (output, error, "\\\\"))
return FALSE;
*c += 2;
}
else if (d == '"')
{
if (! print (output, error, "\\\""))
return FALSE;
*c += 2;
}
else if (pad && d >= '0' && d <= '9')
{
if (! print (output, error, "\"\"%c", d))
return FALSE;
*c += 3;
}
else
{
if (! print (output, error, "%c", d))
return FALSE;
*c += 1;
}
pad = 0;
return TRUE;
}
static gboolean
save_image (GFile *file,
Config *config,
gint32 image_ID,
gint32 drawable_ID,
GError **error)
{
GOutputStream *output;
GeglBuffer *buffer;
GimpImageType drawable_type = gimp_drawable_type (drawable_ID);
gchar *s_uint_8, *s_uint, *s_char, *s_null;
guint c;
gchar *macro_name;
guint8 *img_buffer, *img_buffer_end;
gchar *basename;
guint8 *data, *p;
gint width;
gint height;
gint x, y, pad, n_bytes, bpp;
gint drawable_bpp;
output = G_OUTPUT_STREAM (g_file_replace (file,
NULL, FALSE, G_FILE_CREATE_NONE,
NULL, error));
if (output)
{
GOutputStream *buffered;
buffered = g_buffered_output_stream_new (output);
g_object_unref (output);
output = buffered;
}
else
{
return FALSE;
}
buffer = gimp_drawable_get_buffer (drawable_ID);
width = gegl_buffer_get_width (buffer);
height = gegl_buffer_get_height (buffer);
drawable_bpp = gimp_drawable_bpp (drawable_ID);
bpp = config->rgb565 ? 2 : (config->alpha ? 4 : 3);
n_bytes = width * height * bpp;
pad = width * bpp;
if (config->use_rle)
pad = MAX (pad, 130 + n_bytes / 127);
data = g_new (guint8, pad + n_bytes);
p = data + pad;
for (y = 0; y < height; y++)
{
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, y, width, 1), 1.0,
NULL, data,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
if (bpp == 2)
{
for (x = 0; x < width; x++)
{
guint8 *d = data + x * drawable_bpp;
guint8 r, g, b;
gushort rgb16;
gdouble alpha = drawable_type == GIMP_RGBA_IMAGE ? d[3] : 0xff;
alpha *= config->opacity / 25500.0;
r = (0.5 + alpha * (gdouble) d[0]);
g = (0.5 + alpha * (gdouble) d[1]);
b = (0.5 + alpha * (gdouble) d[2]);
r >>= 3;
g >>= 2;
b >>= 3;
rgb16 = (r << 11) + (g << 5) + b;
*(p++) = (guchar) rgb16;
*(p++) = (guchar) (rgb16 >> 8);
}
}
else if (config->alpha)
{
for (x = 0; x < width; x++)
{
guint8 *d = data + x * drawable_bpp;
gdouble alpha = drawable_type == GIMP_RGBA_IMAGE ? d[3] : 0xff;
alpha *= config->opacity / 100.0;
*(p++) = d[0];
*(p++) = d[1];
*(p++) = d[2];
*(p++) = alpha + 0.5;
}
}
else
{
for (x = 0; x < width; x++)
{
guint8 *d = data + x * drawable_bpp;
gdouble alpha = drawable_type == GIMP_RGBA_IMAGE ? d[3] : 0xff;
alpha *= config->opacity / 25500.0;
*(p++) = 0.5 + alpha * (gdouble) d[0];
*(p++) = 0.5 + alpha * (gdouble) d[1];
*(p++) = 0.5 + alpha * (gdouble) d[2];
}
}
}
img_buffer = data + pad;
if (config->use_rle)
{
img_buffer_end = rl_encode_rgbx (data, img_buffer,
img_buffer + n_bytes, bpp);
img_buffer = data;
}
else
{
img_buffer_end = img_buffer + n_bytes;
}
if (!config->use_macros && config->glib_types)
{
s_uint_8 = "guint8 ";
s_uint = "guint ";
s_char = "gchar ";
s_null = "NULL";
}
else if (!config->use_macros)
{
s_uint_8 = "unsigned char";
s_uint = "unsigned int ";
s_char = "char ";
s_null = "(char*) 0";
}
else if (config->use_macros && config->glib_types)
{
s_uint_8 = "guint8";
s_uint = "guint";
s_char = "gchar";
s_null = "NULL";
}
else /* config->use_macros && !config->glib_types */
{
s_uint_8 = "unsigned char";
s_uint = "unsigned int";
s_char = "char";
s_null = "(char*) 0";
}
macro_name = g_ascii_strup (config->prefixed_name, -1);
basename = g_file_get_basename (file);
if (! print (output, error,
"/* GIMP %s C-Source image dump %s(%s) */\n\n",
config->alpha ? "RGBA" : "RGB",
config->use_rle ? "1-byte-run-length-encoded " : "",
basename))
goto fail;
g_free (basename);
if (config->use_rle && !config->use_macros)
{
if (! save_rle_decoder (output,
macro_name,
config->glib_types ? "guint" : "unsigned int",
config->glib_types ? "guint8" : "unsigned char",
bpp,
error))
goto fail;
}
if (!config->use_macros)
{
if (! print (output, error,
"static const struct {\n"
" %s\t width;\n"
" %s\t height;\n"
" %s\t bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ \n",
s_uint, s_uint, s_uint))
goto fail;
if (config->use_comment)
{
if (! print (output, error, " %s\t*comment;\n", s_char))
goto fail;
}
if (! print (output, error,
" %s\t %spixel_data[",
s_uint_8,
config->use_rle ? "rle_" : ""))
goto fail;
if (config->use_rle)
{
if (! print (output, error,
"%u + 1];\n",
(guint) (img_buffer_end - img_buffer)))
goto fail;
}
else
{
if (! print (output, error,
"%u * %u * %u + 1];\n",
width,
height,
bpp))
goto fail;
}
if (! print (output, error, "} %s = {\n", config->prefixed_name))
goto fail;
if (! print (output, error,
" %u, %u, %u,\n",
width,
height,
bpp))
goto fail;
}
else /* use macros */
{
if (! print (output, error,
"#define %s_WIDTH (%u)\n"
"#define %s_HEIGHT (%u)\n"
"#define %s_BYTES_PER_PIXEL (%u) /* 2:RGB16, 3:RGB, 4:RGBA */\n",
macro_name, width,
macro_name, height,
macro_name, bpp))
{
goto fail;
}
}
if (config->use_comment && !config->comment)
{
if (! config->use_macros)
{
if (! print (output, error, " %s,\n", s_null))
goto fail;
}
else
{
if (! print (output, error,
"#define %s_COMMENT (%s)\n",
macro_name, s_null))
goto fail;
}
}
else if (config->use_comment)
{
gchar *p = config->comment - 1;
if (config->use_macros)
{
if (! print (output, error, "#define %s_COMMENT \\\n", macro_name))
goto fail;
}
if (! print (output, error, " \""))
goto fail;
while (*(++p))
{
gboolean success = FALSE;
if (*p == '\\')
success = print (output, error, "\\\\");
else if (*p == '"')
success = print (output, error, "\\\"");
else if (*p == '\n' && p[1])
success = print (output, error,
"\\n\"%s\n \"",
config->use_macros ? " \\" : "");
else if (*p == '\n')
success = print (output, error, "\\n");
else if (*p == '\r')
success = print (output, error, "\\r");
else if (*p == '\b')
success = print (output, error, "\\b");
else if (*p == '\f')
success = print (output, error, "\\f");
else if (( *p >= 32 && *p <= 47 ) || (*p >= 58 && *p <= 126))
success = print (output, error, "%c", *p);
else
success = print (output, error, "\\%03o", *p);
if (! success)
goto fail;
}
if (! config->use_macros)
{
if (! print (output, error, "\",\n"))
goto fail;
}
else
{
if (! print (output, error, "\"\n"))
goto fail;
}
}
if (config->use_macros)
{
if (! print (output, error,
"#define %s_%sPIXEL_DATA ((%s*) %s_%spixel_data)\n",
macro_name,
config->use_rle ? "RLE_" : "",
s_uint_8,
macro_name,
config->use_rle ? "rle_" : ""))
goto fail;
if (config->use_rle)
{
if (! save_rle_decoder (output,
macro_name,
s_uint,
s_uint_8,
bpp,
error))
goto fail;
}
if (! print (output, error,
"static const %s %s_%spixel_data[",
s_uint_8,
macro_name,
config->use_rle ? "rle_" : ""))
goto fail;
if (config->use_rle)
{
if (! print (output, error,
"%u] =\n",
(guint) (img_buffer_end - img_buffer)))
goto fail;
}
else
{
if (! print (output, error,
"%u * %u * %u + 1] =\n",
width,
height,
bpp))
goto fail;
}
if (! print (output, error, "(\""))
goto fail;
c = 2;
}
else
{
if (! print (output, error, " \""))
goto fail;
c = 3;
}
switch (drawable_type)
{
case GIMP_RGB_IMAGE:
case GIMP_RGBA_IMAGE:
do
{
if (! save_uchar (output, &c, *(img_buffer++), config, error))
goto fail;
}
while (img_buffer < img_buffer_end);
break;
default:
g_warning ("unhandled drawable type (%d)", drawable_type);
goto fail;
}
if (! config->use_macros)
{
if (! print (output, error, "\",\n};\n\n"))
goto fail;
}
else
{
if (! print (output, error, "\");\n\n"))
goto fail;
}
if (! g_output_stream_close (output, NULL, error))
goto fail;
g_object_unref (output);
g_object_unref (buffer);
return TRUE;
fail:
g_object_unref (output);
g_object_unref (buffer);
return FALSE;
}
static void
rgb565_toggle_button_update (GtkWidget *toggle,
gpointer data)
{
GtkWidget *widget;
gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
gimp_toggle_button_update (toggle, data);
widget = g_object_get_data (G_OBJECT (toggle), "set-insensitive-1");
if (widget)
gtk_widget_set_sensitive (widget, ! active);
}
static gboolean
run_save_dialog (Config *config)
{
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *table;
GtkWidget *prefixed_name;
GtkWidget *centry;
GtkWidget *toggle;
GtkWidget *alpha_toggle;
GtkObject *adj;
gboolean run;
dialog = gimp_export_dialog_new (_("C-Source"), PLUG_IN_BINARY, SAVE_PROC);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
table = gtk_table_new (2, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
/* Prefixed Name
*/
prefixed_name = gtk_entry_new ();
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("_Prefixed name:"), 0.0, 0.5,
prefixed_name, 1, FALSE);
gtk_entry_set_text (GTK_ENTRY (prefixed_name),
config->prefixed_name ? config->prefixed_name : "");
/* Comment Entry
*/
centry = gtk_entry_new ();
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("Co_mment:"), 0.0, 0.5,
centry, 1, FALSE);
gtk_entry_set_text (GTK_ENTRY (centry),
config->comment ? config->comment : "");
/* Use Comment
*/
toggle = gtk_check_button_new_with_mnemonic (_("_Save comment to file"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
config->use_comment);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&config->use_comment);
/* GLib types
*/
toggle = gtk_check_button_new_with_mnemonic (_("_Use GLib types (guint8*)"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
config->glib_types);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&config->glib_types);
/* Use Macros
*/
toggle =
gtk_check_button_new_with_mnemonic (_("Us_e macros instead of struct"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
config->use_macros);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&config->use_macros);
/* Use RLE
*/
toggle =
gtk_check_button_new_with_mnemonic (_("Use _1 byte Run-Length-Encoding"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
config->use_rle);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&config->use_rle);
/* Alpha
*/
alpha_toggle = toggle =
gtk_check_button_new_with_mnemonic (_("Sa_ve alpha channel (RGBA/RGB)"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
config->alpha);
gtk_widget_show (toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (gimp_toggle_button_update),
&config->alpha);
/* RGB-565
*/
toggle = gtk_check_button_new_with_mnemonic (_("Save as _RGB565 (16-bit)"));
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
/* Alpha setting is not used with RGB-565 */
g_object_set_data (G_OBJECT (toggle), "set-insensitive-1", alpha_toggle);
g_signal_connect (toggle, "toggled",
G_CALLBACK (rgb565_toggle_button_update),
&config->rgb565);
gtk_widget_show (toggle);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
config->rgb565);
/* Max Alpha Value
*/
table = gtk_table_new (1, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
_("Op_acity:"), 100, 0,
config->opacity, 0, 100, 1, 10, 1,
TRUE, 0, 0,
NULL, NULL);
g_signal_connect (adj, "value-changed",
G_CALLBACK (gimp_double_adjustment_update),
&config->opacity);
gtk_widget_show (dialog);
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
if (run)
{
config->prefixed_name =
g_strdup (gtk_entry_get_text (GTK_ENTRY (prefixed_name)));
config->comment = g_strdup (gtk_entry_get_text (GTK_ENTRY (centry)));
}
gtk_widget_destroy (dialog);
if (!config->prefixed_name || !config->prefixed_name[0])
config->prefixed_name = "tmp";
if (config->comment && !config->comment[0])
config->comment = NULL;
return run;
}