app/core/gimpimage-convert-data.h app/core/gimpimage-convert.c

2006-08-04  Raphael Quinet  <raphael@gimp.org>

	* app/core/gimpimage-convert-data.h
	* app/core/gimpimage-convert.c
	* app/core/gimpimage-convert.h
	* tools/pdbgen/pdb/convert.pdb: Applied slightly modified patch
	from David Gowers allowing a custom dither matrix to be used when
	converting images to indexed mode.  Fixes bug #136604.

	* app/pdb/convert_cmds.c
	* libgimp/gimpconvert_pdb.h
	* libgimp/gimpconvert_pdb.c: Regenerated.

	* app/tools/gimpselectiontool.c: N_() should have been _().
This commit is contained in:
Raphael Quinet 2006-08-04 17:54:26 +00:00 committed by Raphaël Quinet
parent 438d30f38f
commit 1999e437d4
9 changed files with 249 additions and 12 deletions

View File

@ -1,3 +1,18 @@
2006-08-04 Raphaël Quinet <raphael@gimp.org>
* app/core/gimpimage-convert-data.h
* app/core/gimpimage-convert.c
* app/core/gimpimage-convert.h
* tools/pdbgen/pdb/convert.pdb: Applied slightly modified patch
from David Gowers allowing a custom dither matrix to be used when
converting images to indexed mode. Fixes bug #136604.
* app/pdb/convert_cmds.c
* libgimp/gimpconvert_pdb.h
* libgimp/gimpconvert_pdb.c: Regenerated.
* app/tools/gimpselectiontool.c: N_() should have been _().
2006-08-04 Michael Natterer <mitch@gimp.org>
* app/widgets/gimppropwidgets.c: some doc fixes.

View File

@ -70,7 +70,8 @@ static const guchar webpal[] =
#define DM_HEIGHT 32
#define DM_HEIGHTMASK ((DM_HEIGHT)-1)
/* matrix values should be scaled/biased to 1..255 range */
static const guchar DM[32][32] = {
/* this array is not const because it may be overwritten. */
static guchar DM[32][32] = {
{ 1,191, 48,239, 12,203, 60,251, 3,194, 51,242, 15,206, 63,254, 1,192, 49,240, 13,204, 61,252, 4,195, 52,243, 16,207, 64,255},
{128, 64,175,112,140, 76,187,124,131, 67,178,115,143, 79,190,127,128, 65,176,112,140, 77,188,124,131, 68,179,115,143, 80,191,127},
{ 32,223, 16,207, 44,235, 28,219, 35,226, 19,210, 47,238, 31,222, 33,224, 17,208, 45,236, 29,220, 36,227, 20,211, 48,239, 32,223},
@ -105,5 +106,39 @@ static const guchar DM[32][32] = {
{170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85}
};
static const guchar DM_ORIGINAL[32][32] = {
{ 1,191, 48,239, 12,203, 60,251, 3,194, 51,242, 15,206, 63,254, 1,192, 49,240, 13,204, 61,252, 4,195, 52,243, 16,207, 64,255},
{128, 64,175,112,140, 76,187,124,131, 67,178,115,143, 79,190,127,128, 65,176,112,140, 77,188,124,131, 68,179,115,143, 80,191,127},
{ 32,223, 16,207, 44,235, 28,219, 35,226, 19,210, 47,238, 31,222, 33,224, 17,208, 45,236, 29,220, 36,227, 20,211, 48,239, 32,223},
{159, 96,144, 80,171,108,155, 92,162, 99,146, 83,174,111,158, 95,160, 97,144, 81,172,109,156, 93,163,100,147, 84,175,111,159, 96},
{ 8,199, 56,247, 4,195, 52,243, 11,202, 59,250, 7,198, 55,246, 9,200, 57,248, 5,196, 53,244, 12,203, 60,251, 8,199, 56,247},
{136, 72,183,120,132, 68,179,116,139, 75,186,123,135, 71,182,119,136, 73,184,120,132, 69,180,116,139, 76,187,123,135, 72,183,119},
{ 40,231, 24,215, 36,227, 20,211, 43,234, 27,218, 39,230, 23,214, 41,232, 25,216, 37,228, 21,212, 44,235, 28,219, 40,231, 24,215},
{167,104,151, 88,163,100,147, 84,170,107,154, 91,166,103,150, 87,168,105,152, 89,164,101,148, 85,171,108,155, 92,167,104,151, 88},
{ 2,193, 50,241, 14,205, 62,253, 1,192, 49,240, 13,204, 61,252, 3,194, 51,242, 15,206, 63,254, 2,193, 50,241, 14,205, 62,253},
{130, 66,177,114,142, 78,189,126,129, 65,176,113,141, 77,188,125,130, 67,178,114,142, 79,190,126,129, 66,177,113,141, 78,189,125},
{ 34,225, 18,209, 46,237, 30,221, 33,224, 17,208, 45,236, 29,220, 35,226, 19,210, 47,238, 31,222, 34,225, 18,209, 46,237, 30,221},
{161, 98,146, 82,173,110,157, 94,160, 97,145, 81,172,109,156, 93,162, 99,146, 83,174,110,158, 95,161, 98,145, 82,173,109,157, 94},
{ 10,201, 58,249, 6,197, 54,245, 9,200, 57,248, 5,196, 53,244, 11,202, 59,250, 7,198, 55,246, 10,201, 58,249, 6,197, 54,245},
{138, 74,185,122,134, 70,181,118,137, 73,184,121,133, 69,180,117,138, 75,186,122,134, 71,182,118,137, 74,185,121,133, 70,181,117},
{ 42,233, 26,217, 38,229, 22,213, 41,232, 25,216, 37,228, 21,212, 43,234, 27,218, 39,230, 23,214, 42,233, 26,217, 38,229, 22,213},
{169,106,153, 90,165,102,149, 86,168,105,152, 89,164,101,148, 85,170,107,154, 91,166,103,150, 87,169,106,153, 90,165,102,149, 86},
{ 1,192, 49,239, 13,204, 61,251, 4,195, 52,242, 16,207, 64,254, 1,191, 48,239, 13,203, 60,251, 4,194, 51,242, 16,206, 63,254},
{128, 65,176,112,140, 76,188,124,131, 68,179,115,143, 79,191,127,128, 64,176,112,140, 76,187,124,131, 67,179,115,143, 79,190,127},
{ 33,223, 17,208, 45,235, 29,219, 36,226, 20,211, 48,238, 32,222, 33,223, 17,207, 44,235, 29,219, 36,226, 20,210, 47,238, 32,222},
{160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95,160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95},
{ 9,200, 57,247, 5,196, 53,243, 12,203, 60,250, 8,199, 56,246, 9,199, 56,247, 5,195, 52,243, 12,202, 59,250, 8,198, 55,246},
{136, 73,184,120,132, 69,180,116,139, 75,187,123,135, 72,183,119,136, 72,183,120,132, 68,180,116,139, 75,186,123,135, 71,182,119},
{ 41,231, 25,216, 37,227, 21,212, 44,234, 28,218, 40,230, 24,215, 40,231, 25,215, 37,227, 21,211, 43,234, 28,218, 39,230, 24,214},
{168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87},
{ 3,194, 51,241, 15,206, 63,253, 2,193, 50,240, 14,205, 62,252, 3,193, 50,241, 15,205, 62,253, 2,192, 49,240, 14,204, 61,252},
{130, 67,178,114,142, 78,190,126,129, 66,177,113,141, 77,189,125,130, 66,178,114,142, 78,189,126,129, 65,177,113,141, 77,188,125},
{ 35,225, 19,210, 47,237, 31,221, 34,224, 18,209, 46,236, 30,220, 35,225, 19,209, 46,237, 31,221, 34,224, 18,208, 45,236, 30,220},
{162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93,162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93},
{ 11,202, 59,249, 7,198, 55,245, 10,201, 58,248, 6,197, 54,244, 11,201, 58,249, 7,197, 54,245, 10,200, 57,248, 6,196, 53,244},
{138, 74,186,122,134, 71,182,118,137, 73,185,121,133, 70,181,117,138, 74,185,122,134, 70,182,118,137, 73,184,121,133, 69,181,117},
{ 43,233, 27,218, 39,229, 23,214, 42,232, 26,217, 38,228, 22,213, 42,233, 27,217, 38,229, 23,213, 41,232, 26,216, 37,228, 22,212},
{170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85}
};
#endif /* __CONVERT_DATA_H__ */

View File

@ -4006,6 +4006,50 @@ delete_median_cut (QuantizeObj *quantobj)
}
void
gimp_image_convert_set_dither_matrix (gint width,
gint height,
guchar *source)
{
gint x;
gint y;
gint high_value;
gint tmp;
gfloat scale;
/* if source is invalid, restore the default matrix */
if (source == NULL || width == 0 || height == 0)
{
source = (guchar *) (&DM_ORIGINAL);
width = DM_WIDTH;
height = DM_HEIGHT;
}
g_return_if_fail ((DM_WIDTH % width) == 0);
g_return_if_fail ((DM_HEIGHT % height) == 0);
/* find maximum value in input */
high_value = 0;
for (x = 0; x < (width * height); x++)
{
if (source[x] > high_value)
high_value = source[x];
}
scale = 255.0 / (float)high_value;
for (y = 0; y < DM_HEIGHT; y++)
{
for (x = 0; x < DM_WIDTH; x++)
{
tmp = source[((x % width) * height) + (y % height)];
DM[x][y] = (guchar) (ROUND((float)tmp * scale));
}
}
}
/**************************************************************/
static QuantizeObj *
initialize_median_cut (GimpImageBaseType type,

View File

@ -36,5 +36,9 @@ void gimp_image_convert (GimpImage *image,
GimpPalette *custom_palette,
GimpProgress *progress);
void gimp_image_convert_set_dither_matrix (gint width,
gint height,
guchar *source);
#endif /* __GIMP_IMAGE_CONVERT_H__ */

View File

@ -143,6 +143,32 @@ image_convert_indexed_invoker (GimpProcedure *procedure,
return gimp_procedure_get_return_values (procedure, success);
}
static GValueArray *
image_convert_set_dither_matrix_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GValueArray *args)
{
gboolean success = TRUE;
gint32 width;
gint32 height;
gint32 matrix_length;
const guint8 *matrix;
width = g_value_get_int (&args->values[0]);
height = g_value_get_int (&args->values[1]);
matrix_length = g_value_get_int (&args->values[2]);
matrix = gimp_value_get_int8array (&args->values[3]);
if (success)
{
gimp_image_convert_set_dither_matrix (width, height, (guchar *) matrix);
}
return gimp_procedure_get_return_values (procedure, success);
}
void
register_convert_procs (GimpPDB *pdb)
{
@ -252,4 +278,43 @@ register_convert_procs (GimpPDB *pdb)
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-image-convert-set-dither-matrix
*/
procedure = gimp_procedure_new (image_convert_set_dither_matrix_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure), "gimp-image-convert-set-dither-matrix");
gimp_procedure_set_static_strings (procedure,
"gimp-image-convert-set-dither-matrix",
"Set dither matrix for conversion to indexed",
"This procedure sets the dither matrix used when converting images to INDEXED mode with positional dithering.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
NULL);
gimp_procedure_add_argument (procedure,
gimp_param_spec_int32 ("width",
"width",
"Width of the matrix (0 to reset to default matrix)",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_int32 ("height",
"height",
"Height of the matrix (0 to reset to default matrix)",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_int32 ("matrix-length",
"matrix length",
"The length of 'matrix'",
1, 1024, 1,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_int8_array ("matrix",
"matrix",
"The matrix -- all values must be >= 1",
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
}

View File

@ -268,7 +268,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
free_status = TRUE;
}
else
status = N_("Click-Drag to create a new selection.");
status = _("Click-Drag to create a new selection.");
break;
case SELECTION_ADD:

View File

@ -146,3 +146,42 @@ gimp_image_convert_indexed (gint32 image_ID,
return success;
}
/**
* gimp_image_convert_set_dither_matrix:
* @width: Width of the matrix (0 to reset to default matrix).
* @height: Height of the matrix (0 to reset to default matrix).
* @matrix_length: The length of 'matrix'.
* @matrix: The matrix -- all values must be >= 1.
*
* Set dither matrix for conversion to indexed
*
* This procedure sets the dither matrix used when converting images to
* INDEXED mode with positional dithering.
*
* Returns: TRUE on success.
*/
gboolean
gimp_image_convert_set_dither_matrix (gint width,
gint height,
gint matrix_length,
const guint8 *matrix)
{
GimpParam *return_vals;
gint nreturn_vals;
gboolean success = TRUE;
return_vals = gimp_run_procedure ("gimp-image-convert-set-dither-matrix",
&nreturn_vals,
GIMP_PDB_INT32, width,
GIMP_PDB_INT32, height,
GIMP_PDB_INT32, matrix_length,
GIMP_PDB_INT8ARRAY, matrix,
GIMP_PDB_END);
success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
gimp_destroy_params (return_vals, nreturn_vals);
return success;
}

View File

@ -29,15 +29,19 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gboolean gimp_image_convert_rgb (gint32 image_ID);
gboolean gimp_image_convert_grayscale (gint32 image_ID);
gboolean gimp_image_convert_indexed (gint32 image_ID,
GimpConvertDitherType dither_type,
GimpConvertPaletteType palette_type,
gint num_cols,
gboolean alpha_dither,
gboolean remove_unused,
const gchar *palette);
gboolean gimp_image_convert_rgb (gint32 image_ID);
gboolean gimp_image_convert_grayscale (gint32 image_ID);
gboolean gimp_image_convert_indexed (gint32 image_ID,
GimpConvertDitherType dither_type,
GimpConvertPaletteType palette_type,
gint num_cols,
gboolean alpha_dither,
gboolean remove_unused,
const gchar *palette);
gboolean gimp_image_convert_set_dither_matrix (gint width,
gint height,
gint matrix_length,
const guint8 *matrix);
G_END_DECLS

View File

@ -152,6 +152,36 @@ CODE
);
}
sub image_convert_set_dither_matrix {
$blurb = 'Set dither matrix for conversion to indexed';
$help = <<'HELP';
This procedure sets the dither matrix used when converting images to INDEXED mode with
positional dithering.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'width', type => 'int32',
desc => 'Width of the matrix (0 to reset to default matrix)' },
{ name => 'height', type => 'int32',
desc => 'Height of the matrix (0 to reset to default matrix)' },
{ name => 'matrix', type => 'int8array',
desc => 'The matrix -- all values must be >= 1',
array => { name => 'matrix_length', type => '1 <= int32 <= 1024',
desc => "The length of 'matrix'" }
},
);
%invoke = (
code => <<'CODE'
{
gimp_image_convert_set_dither_matrix (width, height, (guchar *) matrix);
}
CODE
);
}
@headers = qw("core/gimp.h" "core/gimpcontainer.h" "core/gimpdatafactory.h"
"core/gimpimage.h" "core/gimpimage-convert.h"
@ -159,7 +189,8 @@ CODE
@procs = qw(image_convert_rgb
image_convert_grayscale
image_convert_indexed);
image_convert_indexed
image_convert_set_dither_matrix);
%exports = (app => [@procs], lib => [@procs]);