allow saving of images with alpha. If the image has alpha, offer the
2000-06-05 Michael Natterer <mitch@gimp.org> * plug-ins/common/xbm.c: allow saving of images with alpha. If the image has alpha, offer the choice of ignoring it or alternatively saving it as a separate XBM file which is the mask of the X cursor we are saving.
This commit is contained in:

committed by
Michael Natterer

parent
c3131277d5
commit
ef2d6c51f4
@ -1,3 +1,10 @@
|
|||||||
|
2000-06-05 Michael Natterer <mitch@gimp.org>
|
||||||
|
|
||||||
|
* plug-ins/common/xbm.c: allow saving of images with alpha.
|
||||||
|
If the image has alpha, offer the choice of ignoring it or
|
||||||
|
alternatively saving it as a separate XBM file which is the
|
||||||
|
mask of the X cursor we are saving.
|
||||||
|
|
||||||
Sun Jun 4 20:17:25 2000 CET Austin Donnelly <austin@gimp.org>
|
Sun Jun 4 20:17:25 2000 CET Austin Donnelly <austin@gimp.org>
|
||||||
|
|
||||||
* app/paths_dialog.c: run the sel2path plugin with a proper
|
* app/paths_dialog.c: run the sel2path plugin with a proper
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
* - Parsing is very tolerant, and the algorithms are quite hairy, so
|
* - Parsing is very tolerant, and the algorithms are quite hairy, so
|
||||||
* load_image should be carefully tested to make sure there are no XBM's
|
* load_image should be carefully tested to make sure there are no XBM's
|
||||||
* that fail.
|
* that fail.
|
||||||
* - Allow the user to specify a hotspot, and preserve it when loading.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Set this for debugging. */
|
/* Set this for debugging. */
|
||||||
@ -55,6 +54,7 @@
|
|||||||
/* Wear your GIMP with pride! */
|
/* Wear your GIMP with pride! */
|
||||||
#define DEFAULT_USE_COMMENT TRUE
|
#define DEFAULT_USE_COMMENT TRUE
|
||||||
#define MAX_COMMENT 72
|
#define MAX_COMMENT 72
|
||||||
|
#define MAX_MASK_EXT 32
|
||||||
|
|
||||||
/* C identifier prefix. */
|
/* C identifier prefix. */
|
||||||
#define DEFAULT_PREFIX "bitmap"
|
#define DEFAULT_PREFIX "bitmap"
|
||||||
@ -65,12 +65,14 @@
|
|||||||
|
|
||||||
typedef struct _XBMSaveVals
|
typedef struct _XBMSaveVals
|
||||||
{
|
{
|
||||||
gchar comment[MAX_COMMENT + 1];
|
gchar comment[MAX_COMMENT + 1];
|
||||||
gint x10_format;
|
gint x10_format;
|
||||||
gint use_hot;
|
gint use_hot;
|
||||||
gint x_hot;
|
gint x_hot;
|
||||||
gint y_hot;
|
gint y_hot;
|
||||||
gchar prefix[MAX_PREFIX + 1];
|
gchar prefix[MAX_PREFIX + 1];
|
||||||
|
gboolean write_mask;
|
||||||
|
gchar mask_ext[MAX_MASK_EXT + 1];
|
||||||
} XBMSaveVals;
|
} XBMSaveVals;
|
||||||
|
|
||||||
static XBMSaveVals xsvals =
|
static XBMSaveVals xsvals =
|
||||||
@ -81,6 +83,8 @@ static XBMSaveVals xsvals =
|
|||||||
0, /* x_hot */
|
0, /* x_hot */
|
||||||
0, /* y_hot */
|
0, /* y_hot */
|
||||||
DEFAULT_PREFIX, /* prefix */
|
DEFAULT_PREFIX, /* prefix */
|
||||||
|
FALSE, /* write_mask */
|
||||||
|
"_mask"
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _XBMSaveInterface
|
typedef struct _XBMSaveInterface
|
||||||
@ -97,25 +101,30 @@ static XBMSaveInterface xsint =
|
|||||||
/* Declare some local functions.
|
/* Declare some local functions.
|
||||||
*/
|
*/
|
||||||
static void query (void);
|
static void query (void);
|
||||||
static void run (gchar *name,
|
static void run (gchar *name,
|
||||||
gint nparams,
|
gint nparams,
|
||||||
GParam *param,
|
GimpParam *param,
|
||||||
gint *nreturn_vals,
|
gint *nreturn_vals,
|
||||||
GParam **return_vals);
|
GimpParam **return_vals);
|
||||||
|
|
||||||
static gint32 load_image (gchar *filename);
|
static gint32 load_image (gchar *filename);
|
||||||
static gint save_image (gchar *filename,
|
static gint save_image (gchar *filename,
|
||||||
gint32 image_ID,
|
gchar *prefix,
|
||||||
gint32 drawable_ID);
|
gchar *comment,
|
||||||
static gint save_dialog (gint32 drawable_ID);
|
gboolean save_mask,
|
||||||
static void save_ok_callback (GtkWidget *widget,
|
gint32 image_ID,
|
||||||
gpointer data);
|
gint32 drawable_ID);
|
||||||
static void comment_entry_callback (GtkWidget *widget,
|
static gint save_dialog (gint32 drawable_ID);
|
||||||
gpointer data);
|
static void save_ok_callback (GtkWidget *widget,
|
||||||
static void prefix_entry_callback (GtkWidget *widget,
|
gpointer data);
|
||||||
gpointer data);
|
static void comment_entry_callback (GtkWidget *widget,
|
||||||
|
gpointer data);
|
||||||
|
static void prefix_entry_callback (GtkWidget *widget,
|
||||||
|
gpointer data);
|
||||||
|
static void mask_ext_entry_callback (GtkWidget *widget,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
GPlugInInfo PLUG_IN_INFO =
|
GimpPlugInInfo PLUG_IN_INFO =
|
||||||
{
|
{
|
||||||
NULL, /* init_proc */
|
NULL, /* init_proc */
|
||||||
NULL, /* quit_proc */
|
NULL, /* quit_proc */
|
||||||
@ -132,7 +141,7 @@ static int verbose = VERBOSE;
|
|||||||
static void
|
static void
|
||||||
query (void)
|
query (void)
|
||||||
{
|
{
|
||||||
static GParamDef load_args[] =
|
static GimpParamDef load_args[] =
|
||||||
{
|
{
|
||||||
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
||||||
{ PARAM_STRING, "filename", "The name of the file to load" },
|
{ PARAM_STRING, "filename", "The name of the file to load" },
|
||||||
@ -140,25 +149,27 @@ query (void)
|
|||||||
};
|
};
|
||||||
static gint nload_args = sizeof (load_args) / sizeof (load_args[0]);
|
static gint nload_args = sizeof (load_args) / sizeof (load_args[0]);
|
||||||
|
|
||||||
static GParamDef load_return_vals[] =
|
static GimpParamDef load_return_vals[] =
|
||||||
{
|
{
|
||||||
{ PARAM_IMAGE, "image", "Output image" }
|
{ PARAM_IMAGE, "image", "Output image" }
|
||||||
};
|
};
|
||||||
static gint nload_return_vals = (sizeof (load_return_vals) /
|
static gint nload_return_vals = (sizeof (load_return_vals) /
|
||||||
sizeof (load_return_vals[0]));
|
sizeof (load_return_vals[0]));
|
||||||
|
|
||||||
static GParamDef save_args[] =
|
static GimpParamDef save_args[] =
|
||||||
{
|
{
|
||||||
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
||||||
{ PARAM_IMAGE, "image", "Input image" },
|
{ PARAM_IMAGE, "image", "Input image" },
|
||||||
{ PARAM_DRAWABLE, "drawable", "Drawable to save" },
|
{ PARAM_DRAWABLE, "drawable", "Drawable to save" },
|
||||||
{ PARAM_STRING, "filename", "The name of the file to save" },
|
{ PARAM_STRING, "filename", "The name of the file to save" },
|
||||||
{ PARAM_STRING, "raw_filename", "The name entered" },
|
{ PARAM_STRING, "raw_filename", "The name entered" },
|
||||||
{ PARAM_STRING, "comment", "Image description (maximum 72 bytes)" },
|
{ PARAM_STRING, "comment", "Image description (maximum 72 bytes)" },
|
||||||
{ PARAM_INT32, "x10", "Save in X10 format" },
|
{ PARAM_INT32, "x10", "Save in X10 format" },
|
||||||
{ PARAM_INT32, "x_hot", "X coordinate of hotspot" },
|
{ PARAM_INT32, "x_hot", "X coordinate of hotspot" },
|
||||||
{ PARAM_INT32, "y_hot", "Y coordinate of hotspot" },
|
{ PARAM_INT32, "y_hot", "Y coordinate of hotspot" },
|
||||||
{ PARAM_STRING, "prefix", "Identifier prefix [determined from filename]"}
|
{ PARAM_STRING, "prefix", "Identifier prefix [determined from filename]"},
|
||||||
|
{ PARAM_INT32, "write_mask", "(0 = ignore, 1 = save as extra file)" },
|
||||||
|
{ PARAM_STRING, "mask_extension", "Extension of the mask file" }
|
||||||
} ;
|
} ;
|
||||||
static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
|
static gint nsave_args = sizeof (save_args) / sizeof (save_args[0]);
|
||||||
|
|
||||||
@ -194,18 +205,13 @@ query (void)
|
|||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gchar *
|
||||||
init_prefix (gchar *filename)
|
init_prefix (gchar *filename)
|
||||||
{
|
{
|
||||||
gchar *p, *prefix;
|
gchar *p, *prefix;
|
||||||
gint len;
|
gint len;
|
||||||
|
|
||||||
/* Mangle the filename to get the prefix. */
|
prefix = g_basename (filename);
|
||||||
prefix = strrchr (filename, '/');
|
|
||||||
if (prefix)
|
|
||||||
prefix ++;
|
|
||||||
else
|
|
||||||
prefix = filename;
|
|
||||||
|
|
||||||
/* Strip any extension. */
|
/* Strip any extension. */
|
||||||
p = strrchr (prefix, '.');
|
p = strrchr (prefix, '.');
|
||||||
@ -216,21 +222,24 @@ init_prefix (gchar *filename)
|
|||||||
|
|
||||||
memset (xsvals.prefix, 0, sizeof (xsvals.prefix));
|
memset (xsvals.prefix, 0, sizeof (xsvals.prefix));
|
||||||
strncpy (xsvals.prefix, prefix, len);
|
strncpy (xsvals.prefix, prefix, len);
|
||||||
|
|
||||||
|
return xsvals.prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
run (gchar *name,
|
run (gchar *name,
|
||||||
gint nparams,
|
gint nparams,
|
||||||
GParam *param,
|
GimpParam *param,
|
||||||
gint *nreturn_vals,
|
gint *nreturn_vals,
|
||||||
GParam **return_vals)
|
GimpParam **return_vals)
|
||||||
{
|
{
|
||||||
static GParam values[2];
|
static GimpParam values[2];
|
||||||
GRunModeType run_mode;
|
GimpRunModeType run_mode;
|
||||||
GStatusType status = STATUS_SUCCESS;
|
GimpPDBStatusType status = STATUS_SUCCESS;
|
||||||
gint32 image_ID;
|
gint32 image_ID;
|
||||||
gint32 drawable_ID;
|
gint32 drawable_ID;
|
||||||
GimpParasite *parasite;
|
GimpParasite *parasite;
|
||||||
|
gchar *mask_filename = NULL;
|
||||||
GimpExportReturnType export = EXPORT_CANCEL;
|
GimpExportReturnType export = EXPORT_CANCEL;
|
||||||
|
|
||||||
INIT_I18N_UI();
|
INIT_I18N_UI();
|
||||||
@ -267,7 +276,7 @@ run (gchar *name,
|
|||||||
{
|
{
|
||||||
image_ID = param[1].data.d_int32;
|
image_ID = param[1].data.d_int32;
|
||||||
drawable_ID = param[2].data.d_int32;
|
drawable_ID = param[2].data.d_int32;
|
||||||
|
|
||||||
/* eventually export the image */
|
/* eventually export the image */
|
||||||
switch (run_mode)
|
switch (run_mode)
|
||||||
{
|
{
|
||||||
@ -275,7 +284,8 @@ run (gchar *name,
|
|||||||
case RUN_WITH_LAST_VALS:
|
case RUN_WITH_LAST_VALS:
|
||||||
gimp_ui_init ("xbm", FALSE);
|
gimp_ui_init ("xbm", FALSE);
|
||||||
export = gimp_export_image (&image_ID, &drawable_ID, "XBM",
|
export = gimp_export_image (&image_ID, &drawable_ID, "XBM",
|
||||||
CAN_HANDLE_INDEXED);
|
CAN_HANDLE_INDEXED |
|
||||||
|
CAN_HANDLE_ALPHA);
|
||||||
if (export == EXPORT_CANCEL)
|
if (export == EXPORT_CANCEL)
|
||||||
{
|
{
|
||||||
values[0].data.d_status = STATUS_CANCEL;
|
values[0].data.d_status = STATUS_CANCEL;
|
||||||
@ -294,8 +304,65 @@ run (gchar *name,
|
|||||||
gimp_get_data ("file_xbm_save", &xsvals);
|
gimp_get_data ("file_xbm_save", &xsvals);
|
||||||
|
|
||||||
/* Always override the prefix with the filename. */
|
/* Always override the prefix with the filename. */
|
||||||
init_prefix (param[3].data.d_string);
|
mask_filename = g_strdup (init_prefix (param[3].data.d_string));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RUN_NONINTERACTIVE:
|
||||||
|
/* Make sure all the required arguments are there! */
|
||||||
|
if (nparams < 5)
|
||||||
|
{
|
||||||
|
status = STATUS_CALLING_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gint i = 5;
|
||||||
|
|
||||||
|
if (nparams > i)
|
||||||
|
{
|
||||||
|
memset (xsvals.comment, 0, sizeof (xsvals.comment));
|
||||||
|
strncpy (xsvals.comment, param[i].data.d_string,
|
||||||
|
MAX_COMMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
i ++;
|
||||||
|
if (nparams > i)
|
||||||
|
xsvals.x10_format = (param[i].data.d_int32) ? TRUE : FALSE;
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
if (nparams > i)
|
||||||
|
{
|
||||||
|
/* They've asked for a hotspot. */
|
||||||
|
xsvals.use_hot = TRUE;
|
||||||
|
xsvals.x_hot = param[i - 1].data.d_int32;
|
||||||
|
xsvals.y_hot = param[i].data.d_int32;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask_filename = g_strdup (init_prefix (param[3].data.d_string));
|
||||||
|
|
||||||
|
i ++;
|
||||||
|
if (nparams > i)
|
||||||
|
{
|
||||||
|
memset (xsvals.prefix, 0, sizeof (xsvals.prefix));
|
||||||
|
strncpy (xsvals.prefix, param[i].data.d_string,
|
||||||
|
MAX_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
if (nparams > i)
|
||||||
|
{
|
||||||
|
xsvals.write_mask = param[i - 1].data.d_int32;
|
||||||
|
memset (xsvals.mask_ext, 0, sizeof (xsvals.mask_ext));
|
||||||
|
strncpy (xsvals.mask_ext, param[i].data.d_string,
|
||||||
|
MAX_MASK_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
i ++;
|
||||||
|
/* Too many arguments. */
|
||||||
|
if (nparams > i)
|
||||||
|
status = STATUS_CALLING_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -336,68 +403,59 @@ run (gchar *name,
|
|||||||
gimp_parasite_free (parasite);
|
gimp_parasite_free (parasite);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (run_mode)
|
if (run_mode == RUN_INTERACTIVE)
|
||||||
{
|
{
|
||||||
case RUN_INTERACTIVE:
|
|
||||||
/* Acquire information with a dialog */
|
/* Acquire information with a dialog */
|
||||||
if (! save_dialog (drawable_ID))
|
if (! save_dialog (drawable_ID))
|
||||||
status = STATUS_CANCEL;
|
status = STATUS_CANCEL;
|
||||||
break;
|
|
||||||
|
|
||||||
case RUN_NONINTERACTIVE:
|
|
||||||
/* Make sure all the required arguments are there! */
|
|
||||||
if (nparams < 5)
|
|
||||||
{
|
|
||||||
status = STATUS_CALLING_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gint i = 5;
|
|
||||||
|
|
||||||
if (nparams > i)
|
|
||||||
{
|
|
||||||
memset (xsvals.comment, 0, sizeof (xsvals.comment));
|
|
||||||
strncpy (xsvals.comment, param[i].data.d_string,
|
|
||||||
MAX_COMMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
i ++;
|
|
||||||
if (nparams > i)
|
|
||||||
xsvals.x10_format = (param[i].data.d_int32) ? TRUE : FALSE;
|
|
||||||
|
|
||||||
i += 2;
|
|
||||||
if (nparams > i)
|
|
||||||
{
|
|
||||||
/* They've asked for a hotspot. */
|
|
||||||
xsvals.use_hot = TRUE;
|
|
||||||
xsvals.x_hot = param[i - 1].data.d_int32;
|
|
||||||
xsvals.y_hot = param[i].data.d_int32;
|
|
||||||
}
|
|
||||||
|
|
||||||
i ++;
|
|
||||||
if (nparams > i)
|
|
||||||
{
|
|
||||||
memset (xsvals.prefix, 0, sizeof (xsvals.prefix));
|
|
||||||
strncpy (xsvals.prefix, param[i].data.d_string,
|
|
||||||
MAX_PREFIX);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
init_prefix (param[3].data.d_string);
|
|
||||||
|
|
||||||
i ++;
|
|
||||||
/* Too many arguments. */
|
|
||||||
if (nparams > i)
|
|
||||||
status = STATUS_CALLING_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
if (save_image (param[3].data.d_string, image_ID, drawable_ID))
|
gchar *temp;
|
||||||
|
gchar *mask_prefix;
|
||||||
|
gchar *dirname;
|
||||||
|
|
||||||
|
temp = mask_filename;
|
||||||
|
|
||||||
|
if ((dirname = g_dirname (param[3].data.d_string)) != NULL)
|
||||||
|
{
|
||||||
|
mask_filename = g_strdup_printf ("%s/%s%s.xbm",
|
||||||
|
dirname, temp, xsvals.mask_ext);
|
||||||
|
g_free (dirname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask_filename = g_strdup_printf ("%s%s.xbm",
|
||||||
|
temp, xsvals.mask_ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (temp);
|
||||||
|
|
||||||
|
/* Change any non-alphanumeric prefix characters to underscores. */
|
||||||
|
temp = xsvals.prefix;
|
||||||
|
while (*temp)
|
||||||
|
{
|
||||||
|
if (!isalnum (*temp))
|
||||||
|
*temp = '_';
|
||||||
|
temp ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask_prefix = g_strdup_printf ("%s%s", xsvals.prefix, xsvals.mask_ext);
|
||||||
|
|
||||||
|
if (save_image (param[3].data.d_string,
|
||||||
|
xsvals.prefix,
|
||||||
|
xsvals.comment,
|
||||||
|
FALSE,
|
||||||
|
image_ID, drawable_ID) &&
|
||||||
|
|
||||||
|
xsvals.write_mask &&
|
||||||
|
|
||||||
|
save_image (mask_filename,
|
||||||
|
mask_prefix,
|
||||||
|
xsvals.comment,
|
||||||
|
TRUE,
|
||||||
|
image_ID, drawable_ID))
|
||||||
{
|
{
|
||||||
/* Store xsvals data */
|
/* Store xsvals data */
|
||||||
gimp_set_data ("file_xbm_save", &xsvals, sizeof (xsvals));
|
gimp_set_data ("file_xbm_save", &xsvals, sizeof (xsvals));
|
||||||
@ -406,6 +464,9 @@ run (gchar *name,
|
|||||||
{
|
{
|
||||||
status = STATUS_EXECUTION_ERROR;
|
status = STATUS_EXECUTION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (mask_prefix);
|
||||||
|
g_free (mask_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (export == EXPORT_EXPORT)
|
if (export == EXPORT_EXPORT)
|
||||||
@ -872,91 +933,53 @@ load_image (gchar *filename)
|
|||||||
return image_ID;
|
return image_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
static int gtk_initialized = FALSE;
|
save_image (gchar *filename,
|
||||||
|
gchar *prefix,
|
||||||
|
gchar *comment,
|
||||||
static void
|
gboolean save_mask,
|
||||||
not_bw_dialog (void)
|
gint32 image_ID,
|
||||||
|
gint32 drawable_ID)
|
||||||
{
|
{
|
||||||
GtkWidget *dlg, *label, *frame, *vbox;
|
GimpDrawable *drawable;
|
||||||
|
GimpPixelRgn pixel_rgn;
|
||||||
if (!gtk_initialized)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "XBM: can only save two color indexed images\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dlg = gimp_dialog_new (_("XBM Warning"), "xbm",
|
|
||||||
gimp_standard_help_func, "filters/xbm.html",
|
|
||||||
GTK_WIN_POS_MOUSE,
|
|
||||||
FALSE, TRUE, FALSE,
|
|
||||||
|
|
||||||
_("Cancel"), gtk_main_quit,
|
|
||||||
NULL, NULL, NULL, TRUE, TRUE,
|
|
||||||
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* the warning message */
|
|
||||||
frame = gtk_frame_new (NULL);
|
|
||||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
|
|
||||||
gtk_container_border_width (GTK_CONTAINER (frame), 6);
|
|
||||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame,
|
|
||||||
TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
vbox = gtk_vbox_new (FALSE, 5);
|
|
||||||
gtk_container_border_width (GTK_CONTAINER (vbox), 4);
|
|
||||||
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
|
||||||
|
|
||||||
label = gtk_label_new (_("The image which you are trying to save as\n"
|
|
||||||
"an XBM contains more than two colors.\n\n"
|
|
||||||
"Please convert it to a black and white\n"
|
|
||||||
"(1-bit) indexed image and try again."));
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
|
|
||||||
|
|
||||||
gtk_widget_show (label);
|
|
||||||
gtk_widget_show (vbox);
|
|
||||||
gtk_widget_show (frame);
|
|
||||||
gtk_widget_show (dlg);
|
|
||||||
|
|
||||||
gtk_main ();
|
|
||||||
gdk_flush ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gint
|
|
||||||
save_image (gchar *filename,
|
|
||||||
gint32 image_ID,
|
|
||||||
gint32 drawable_ID)
|
|
||||||
{
|
|
||||||
GDrawable *drawable;
|
|
||||||
GPixelRgn pixel_rgn;
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
int width, height, colors, dark;
|
gint width, height, colors, dark;
|
||||||
int intbits, lineints, need_comma, nints, rowoffset, tileheight;
|
gint intbits, lineints, need_comma, nints, rowoffset, tileheight;
|
||||||
int c, i, j, k, thisbit;
|
gint c, i, j, k, thisbit;
|
||||||
|
|
||||||
guchar *data, *cmap, *name_buf;
|
gboolean has_alpha;
|
||||||
char *prefix, *p, *intfmt;
|
gint bpp;
|
||||||
|
|
||||||
|
guchar *data, *cmap, *name_buf, *intfmt;
|
||||||
|
|
||||||
drawable = gimp_drawable_get (drawable_ID);
|
drawable = gimp_drawable_get (drawable_ID);
|
||||||
width = drawable->width;
|
width = drawable->width;
|
||||||
height = drawable->height;
|
height = drawable->height;
|
||||||
cmap = gimp_image_get_cmap (image_ID, &colors);
|
cmap = gimp_image_get_cmap (image_ID, &colors);
|
||||||
|
|
||||||
#if 0
|
if (!gimp_drawable_is_indexed (drawable_ID) || colors > 2)
|
||||||
printf ("XBM: run `gdb xbm' and `attach %d'\n", getpid ());
|
|
||||||
kill (getpid (), 19);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gimp_drawable_type (drawable_ID) != INDEXED_IMAGE || colors > 2)
|
|
||||||
{
|
{
|
||||||
/* The image is not black-and-white. */
|
/* The image is not black-and-white. */
|
||||||
not_bw_dialog ();
|
g_message (_("The image which you are trying to save as\n"
|
||||||
|
"an XBM contains more than two colors.\n\n"
|
||||||
|
"Please convert it to a black and white\n"
|
||||||
|
"(1-bit) indexed image and try again."));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has_alpha = gimp_drawable_has_alpha (drawable_ID);
|
||||||
|
|
||||||
|
if (!has_alpha && save_mask)
|
||||||
|
{
|
||||||
|
g_message (_("You cannot save a cursor mask for an image\n"
|
||||||
|
"which has no alpha channel."));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpp = gimp_drawable_bpp (drawable_ID);
|
||||||
|
|
||||||
name_buf = g_strdup_printf (_("Saving %s:"), filename);
|
name_buf = g_strdup_printf (_("Saving %s:"), filename);
|
||||||
gimp_progress_init (name_buf);
|
gimp_progress_init (name_buf);
|
||||||
g_free (name_buf);
|
g_free (name_buf);
|
||||||
@ -965,10 +988,10 @@ save_image (gchar *filename,
|
|||||||
dark = 0;
|
dark = 0;
|
||||||
if (colors > 1)
|
if (colors > 1)
|
||||||
{
|
{
|
||||||
int first, second;
|
gint first, second;
|
||||||
|
|
||||||
/* Maybe the second color is darker than the first. */
|
/* Maybe the second color is darker than the first. */
|
||||||
first = (cmap[0] * cmap[0]) + (cmap[1] * cmap[1]) + (cmap[2] * cmap[2]);
|
first = (cmap[0] * cmap[0]) + (cmap[1] * cmap[1]) + (cmap[2] * cmap[2]);
|
||||||
second = (cmap[3] * cmap[3]) + (cmap[4] * cmap[4]) + (cmap[5] * cmap[5]);
|
second = (cmap[3] * cmap[3]) + (cmap[4] * cmap[4]) + (cmap[5] * cmap[5]);
|
||||||
|
|
||||||
if (second < first)
|
if (second < first)
|
||||||
@ -984,21 +1007,11 @@ save_image (gchar *filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Maybe write the image comment. */
|
/* Maybe write the image comment. */
|
||||||
if (*xsvals.comment)
|
if (*comment)
|
||||||
fprintf (fp, "/* %s */\n", xsvals.comment);
|
fprintf (fp, "/* %s */\n", comment);
|
||||||
|
|
||||||
/* Change any non-alphanumeric prefix characters to underscores. */
|
|
||||||
prefix = xsvals.prefix;
|
|
||||||
p = prefix;
|
|
||||||
while (*p)
|
|
||||||
{
|
|
||||||
if (!isalnum (*p))
|
|
||||||
*p = '_';
|
|
||||||
p ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write out the image height and width. */
|
/* Write out the image height and width. */
|
||||||
fprintf (fp, "#define %s_width %d\n", prefix, width);
|
fprintf (fp, "#define %s_width %d\n", prefix, width);
|
||||||
fprintf (fp, "#define %s_height %d\n", prefix, height);
|
fprintf (fp, "#define %s_height %d\n", prefix, height);
|
||||||
|
|
||||||
/* Write out the hotspot, if any. */
|
/* Write out the hotspot, if any. */
|
||||||
@ -1029,7 +1042,7 @@ save_image (gchar *filename,
|
|||||||
|
|
||||||
/* Allocate a new set of pixels. */
|
/* Allocate a new set of pixels. */
|
||||||
tileheight = gimp_tile_height ();
|
tileheight = gimp_tile_height ();
|
||||||
data = (guchar *) g_malloc(width * tileheight);
|
data = (guchar *) g_malloc (width * tileheight * bpp);
|
||||||
|
|
||||||
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height,
|
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
@ -1052,11 +1065,11 @@ save_image (gchar *filename,
|
|||||||
for (j = 0; j < tileheight; j ++)
|
for (j = 0; j < tileheight; j ++)
|
||||||
{
|
{
|
||||||
/* Write out a row at a time. */
|
/* Write out a row at a time. */
|
||||||
rowoffset = j * width;
|
rowoffset = j * width * bpp;
|
||||||
c = 0;
|
c = 0;
|
||||||
thisbit = 0;
|
thisbit = 0;
|
||||||
|
|
||||||
for (k = 0; k < width; k ++)
|
for (k = 0; k < width * bpp; k += bpp)
|
||||||
{
|
{
|
||||||
if (k != 0 && thisbit == intbits)
|
if (k != 0 && thisbit == intbits)
|
||||||
{
|
{
|
||||||
@ -1079,7 +1092,17 @@ save_image (gchar *filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Pack INTBITS pixels into an integer. */
|
/* Pack INTBITS pixels into an integer. */
|
||||||
c |= ((data[rowoffset + k] == dark) ? 1 : 0) << (thisbit ++);
|
if (save_mask)
|
||||||
|
{
|
||||||
|
c |= ((data[rowoffset + k + 1] < 128) ? 1 : 0) << (thisbit ++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (has_alpha && (data[rowoffset + k + 1] < 128))
|
||||||
|
c |= 0 << (thisbit ++);
|
||||||
|
else
|
||||||
|
c |= ((data[rowoffset + k] == dark) ? 1 : 0) << (thisbit ++);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thisbit != 0)
|
if (thisbit != 0)
|
||||||
@ -1221,6 +1244,40 @@ save_dialog (gint32 drawable_ID)
|
|||||||
_("Y:"), 1.0, 0.5,
|
_("Y:"), 1.0, 0.5,
|
||||||
spinbutton, 1, TRUE);
|
spinbutton, 1, TRUE);
|
||||||
|
|
||||||
|
/* mask file */
|
||||||
|
frame = gtk_frame_new (_("Mask File"));
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||||
|
gtk_widget_show (frame);
|
||||||
|
|
||||||
|
table = gtk_table_new (2, 2, FALSE);
|
||||||
|
gtk_container_set_border_width (GTK_CONTAINER (table), 2);
|
||||||
|
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
||||||
|
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), table);
|
||||||
|
gtk_widget_show (table);
|
||||||
|
|
||||||
|
toggle = gtk_check_button_new_with_label (_("Write Extra Mask File"));
|
||||||
|
gtk_table_attach_defaults (GTK_TABLE (table), toggle, 0, 2, 0, 1);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
|
||||||
|
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
|
||||||
|
&xsvals.write_mask);
|
||||||
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), xsvals.write_mask);
|
||||||
|
gtk_widget_show (toggle);
|
||||||
|
|
||||||
|
entry = gtk_entry_new_with_max_length (MAX_MASK_EXT);
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (entry), xsvals.mask_ext);
|
||||||
|
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
|
||||||
|
_("Mask File Extension:"), 1.0, 0.5,
|
||||||
|
entry, 1, TRUE);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (entry), "changed",
|
||||||
|
GTK_SIGNAL_FUNC (mask_ext_entry_callback),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_object_set_data (GTK_OBJECT (toggle), "set_sensitive", entry);
|
||||||
|
gtk_widget_set_sensitive (entry, xsvals.write_mask);
|
||||||
|
|
||||||
|
gtk_widget_set_sensitive (frame, gimp_drawable_has_alpha (drawable_ID));
|
||||||
|
|
||||||
/* Done. */
|
/* Done. */
|
||||||
gtk_widget_show (vbox);
|
gtk_widget_show (vbox);
|
||||||
gtk_widget_show (dlg);
|
gtk_widget_show (dlg);
|
||||||
@ -1251,6 +1308,15 @@ prefix_entry_callback (GtkWidget *widget,
|
|||||||
gtk_entry_get_text (GTK_ENTRY (widget)), MAX_PREFIX);
|
gtk_entry_get_text (GTK_ENTRY (widget)), MAX_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mask_ext_entry_callback (GtkWidget *widget,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
memset (xsvals.prefix, 0, sizeof (xsvals.mask_ext));
|
||||||
|
strncpy (xsvals.mask_ext,
|
||||||
|
gtk_entry_get_text (GTK_ENTRY (widget)), MAX_MASK_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_ok_callback (GtkWidget *widget,
|
save_ok_callback (GtkWidget *widget,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
|
Reference in New Issue
Block a user