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:

committed by
Raphaël Quinet

parent
438d30f38f
commit
1999e437d4
15
ChangeLog
15
ChangeLog
@ -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>
|
2006-08-04 Michael Natterer <mitch@gimp.org>
|
||||||
|
|
||||||
* app/widgets/gimppropwidgets.c: some doc fixes.
|
* app/widgets/gimppropwidgets.c: some doc fixes.
|
||||||
|
@ -70,7 +70,8 @@ static const guchar webpal[] =
|
|||||||
#define DM_HEIGHT 32
|
#define DM_HEIGHT 32
|
||||||
#define DM_HEIGHTMASK ((DM_HEIGHT)-1)
|
#define DM_HEIGHTMASK ((DM_HEIGHT)-1)
|
||||||
/* matrix values should be scaled/biased to 1..255 range */
|
/* 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},
|
{ 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},
|
{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},
|
{ 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}
|
{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__ */
|
#endif /* __CONVERT_DATA_H__ */
|
||||||
|
@ -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 *
|
static QuantizeObj *
|
||||||
initialize_median_cut (GimpImageBaseType type,
|
initialize_median_cut (GimpImageBaseType type,
|
||||||
|
@ -36,5 +36,9 @@ void gimp_image_convert (GimpImage *image,
|
|||||||
GimpPalette *custom_palette,
|
GimpPalette *custom_palette,
|
||||||
GimpProgress *progress);
|
GimpProgress *progress);
|
||||||
|
|
||||||
|
void gimp_image_convert_set_dither_matrix (gint width,
|
||||||
|
gint height,
|
||||||
|
guchar *source);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GIMP_IMAGE_CONVERT_H__ */
|
#endif /* __GIMP_IMAGE_CONVERT_H__ */
|
||||||
|
@ -143,6 +143,32 @@ image_convert_indexed_invoker (GimpProcedure *procedure,
|
|||||||
return gimp_procedure_get_return_values (procedure, success);
|
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
|
void
|
||||||
register_convert_procs (GimpPDB *pdb)
|
register_convert_procs (GimpPDB *pdb)
|
||||||
{
|
{
|
||||||
@ -252,4 +278,43 @@ register_convert_procs (GimpPDB *pdb)
|
|||||||
GIMP_PARAM_READWRITE));
|
GIMP_PARAM_READWRITE));
|
||||||
gimp_pdb_register_procedure (pdb, procedure);
|
gimp_pdb_register_procedure (pdb, procedure);
|
||||||
g_object_unref (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);
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
|
|||||||
free_status = TRUE;
|
free_status = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
status = N_("Click-Drag to create a new selection.");
|
status = _("Click-Drag to create a new selection.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SELECTION_ADD:
|
case SELECTION_ADD:
|
||||||
|
@ -146,3 +146,42 @@ gimp_image_convert_indexed (gint32 image_ID,
|
|||||||
|
|
||||||
return success;
|
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;
|
||||||
|
}
|
||||||
|
@ -38,6 +38,10 @@ gboolean gimp_image_convert_indexed (gint32 image_ID,
|
|||||||
gboolean alpha_dither,
|
gboolean alpha_dither,
|
||||||
gboolean remove_unused,
|
gboolean remove_unused,
|
||||||
const gchar *palette);
|
const gchar *palette);
|
||||||
|
gboolean gimp_image_convert_set_dither_matrix (gint width,
|
||||||
|
gint height,
|
||||||
|
gint matrix_length,
|
||||||
|
const guint8 *matrix);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -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"
|
@headers = qw("core/gimp.h" "core/gimpcontainer.h" "core/gimpdatafactory.h"
|
||||||
"core/gimpimage.h" "core/gimpimage-convert.h"
|
"core/gimpimage.h" "core/gimpimage-convert.h"
|
||||||
@ -159,7 +189,8 @@ CODE
|
|||||||
|
|
||||||
@procs = qw(image_convert_rgb
|
@procs = qw(image_convert_rgb
|
||||||
image_convert_grayscale
|
image_convert_grayscale
|
||||||
image_convert_indexed);
|
image_convert_indexed
|
||||||
|
image_convert_set_dither_matrix);
|
||||||
|
|
||||||
%exports = (app => [@procs], lib => [@procs]);
|
%exports = (app => [@procs], lib => [@procs]);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user