286 lines
8.6 KiB
Plaintext
286 lines
8.6 KiB
Plaintext
|
# PIKA - Photo and Image Kooker Application
|
||
|
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||
|
|
||
|
# 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 <https://www.gnu.org/licenses/>.
|
||
|
|
||
|
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
|
||
|
|
||
|
sub image_convert_rgb {
|
||
|
$blurb = 'Convert specified image to RGB color';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This procedure converts the specified image to RGB color. This process
|
||
|
requires an image in Grayscale or Indexed color mode. No image content is
|
||
|
lost in this process aside from the colormap for an indexed image.
|
||
|
HELP
|
||
|
|
||
|
&std_pdb_misc;
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
if (pika_pdb_image_is_not_base_type (image, PIKA_RGB, error) &&
|
||
|
pika_babl_is_valid (PIKA_RGB, pika_image_get_precision (image)))
|
||
|
{
|
||
|
success = pika_image_convert_type (image, PIKA_RGB, NULL, NULL, error);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
success = FALSE;
|
||
|
}
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
sub image_convert_grayscale {
|
||
|
$blurb = 'Convert specified image to grayscale';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This procedure converts the specified image to grayscale. This process
|
||
|
requires an image in RGB or Indexed color mode.
|
||
|
HELP
|
||
|
|
||
|
&std_pdb_misc;
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
if (pika_pdb_image_is_not_base_type (image, PIKA_GRAY, error) &&
|
||
|
pika_babl_is_valid (PIKA_GRAY, pika_image_get_precision (image)))
|
||
|
{
|
||
|
success = pika_image_convert_type (image, PIKA_GRAY, NULL, NULL, error);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
success = FALSE;
|
||
|
}
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
sub image_convert_indexed {
|
||
|
$blurb = 'Convert specified image to and Indexed image';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This procedure converts the specified image to 'indexed' color. This
|
||
|
process requires an image in RGB or Grayscale mode. The 'palette_type'
|
||
|
specifies what kind of palette to use, A type of '0' means to use an
|
||
|
optimal palette of 'num_cols' generated from the colors in the
|
||
|
image. A type of '1' means to re-use the previous palette (not
|
||
|
currently implemented). A type of '2' means to use the so-called
|
||
|
WWW-optimized palette. Type '3' means to use only black and white
|
||
|
colors. A type of '4' means to use a palette from the pika palettes
|
||
|
directories. The 'dither type' specifies what kind of dithering to
|
||
|
use. '0' means no dithering, '1' means standard Floyd-Steinberg error
|
||
|
diffusion, '2' means Floyd-Steinberg error diffusion with reduced
|
||
|
bleeding, '3' means dithering based on pixel location ('Fixed'
|
||
|
dithering).
|
||
|
HELP
|
||
|
|
||
|
&std_pdb_misc;
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'dither_type', type => 'enum PikaConvertDitherType',
|
||
|
desc => 'The dither type to use' },
|
||
|
{ name => 'palette_type', type => 'enum PikaConvertPaletteType',
|
||
|
desc => 'The type of palette to use' },
|
||
|
{ name => 'num_cols', type => 'int32',
|
||
|
desc => 'The number of colors to quantize to, ignored unless
|
||
|
(palette_type == PIKA_CONVERT_PALETTE_GENERATE)' },
|
||
|
{ name => 'alpha_dither', type => 'boolean',
|
||
|
desc => 'Dither transparency to fake partial opacity' },
|
||
|
{ name => 'remove_unused', type => 'boolean',
|
||
|
desc => 'Remove unused or duplicate color entries from final
|
||
|
palette, ignored if (palette_type ==
|
||
|
PIKA_CONVERT_PALETTE_GENERATE)' },
|
||
|
{ name => 'palette', type => 'string',
|
||
|
desc => 'The name of the custom palette to use, ignored unless
|
||
|
(palette_type == PIKA_CONVERT_PALETTE_CUSTOM)' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPalette *pal = NULL;
|
||
|
|
||
|
if (pika_pdb_image_is_not_base_type (image, PIKA_INDEXED, error) &&
|
||
|
pika_pdb_image_is_precision (image, PIKA_PRECISION_U8_NON_LINEAR, error) &&
|
||
|
pika_babl_is_valid (PIKA_INDEXED, pika_image_get_precision (image)) &&
|
||
|
pika_item_stack_is_flat (PIKA_ITEM_STACK (pika_image_get_layers (image))))
|
||
|
{
|
||
|
switch (palette_type)
|
||
|
{
|
||
|
case PIKA_CONVERT_PALETTE_GENERATE:
|
||
|
if (num_cols < 1 || num_cols > MAXNUMCOLORS)
|
||
|
success = FALSE;
|
||
|
break;
|
||
|
|
||
|
case PIKA_CONVERT_PALETTE_CUSTOM:
|
||
|
pal = PIKA_PALETTE (pika_pdb_get_resource (pika, PIKA_TYPE_PALETTE, palette,
|
||
|
PIKA_PDB_DATA_ACCESS_READ, error));
|
||
|
if (! pal)
|
||
|
{
|
||
|
success = FALSE;
|
||
|
}
|
||
|
else if (pal->n_colors > MAXNUMCOLORS)
|
||
|
{
|
||
|
g_set_error_literal (error,
|
||
|
PIKA_PDB_ERROR,
|
||
|
PIKA_PDB_ERROR_INVALID_ARGUMENT,
|
||
|
_("Cannot convert to a palette "
|
||
|
"with more than 256 colors."));
|
||
|
success = FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
success = FALSE;
|
||
|
}
|
||
|
|
||
|
if (success)
|
||
|
success = pika_image_convert_indexed (image,
|
||
|
palette_type, num_cols, remove_unused,
|
||
|
dither_type, alpha_dither, FALSE,
|
||
|
pal,
|
||
|
NULL, error);
|
||
|
}
|
||
|
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
|
||
|
|
||
|
&david_pdb_misc('2006', '2.4');
|
||
|
|
||
|
@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 => 'bytes',
|
||
|
desc => 'The matrix -- all values must be >= 1' },
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
if (width == 0 || height == 0 || g_bytes_get_size (matrix) == width * height)
|
||
|
{
|
||
|
pika_image_convert_indexed_set_dither_matrix (g_bytes_get_data (matrix, NULL),
|
||
|
width, height);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_set_error_literal (error, PIKA_PDB_ERROR,
|
||
|
PIKA_PDB_ERROR_INVALID_ARGUMENT,
|
||
|
"Dither matrix length must be width * height");
|
||
|
success = FALSE;
|
||
|
}
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
sub image_convert_precision {
|
||
|
$blurb = 'Convert the image to the specified precision';
|
||
|
|
||
|
$help = <<'HELP';
|
||
|
This procedure converts the image to the specified precision. Note
|
||
|
that indexed images cannot be converted and are always in
|
||
|
PIKA_PRECISION_U8.
|
||
|
HELP
|
||
|
|
||
|
&mitch_pdb_misc('2012', '2.10');
|
||
|
|
||
|
@inargs = (
|
||
|
{ name => 'image', type => 'image',
|
||
|
desc => 'The image' },
|
||
|
{ name => 'precision', type => 'enum PikaPrecision',
|
||
|
desc => 'The new precision' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
if (pika_pdb_image_is_not_base_type (image, PIKA_INDEXED, error) &&
|
||
|
pika_pdb_image_is_not_precision (image, precision, error) &&
|
||
|
pika_babl_is_valid (pika_image_get_base_type (image), precision))
|
||
|
{
|
||
|
pika_image_convert_precision (image, precision,
|
||
|
GEGL_DITHER_NONE,
|
||
|
GEGL_DITHER_NONE,
|
||
|
GEGL_DITHER_NONE,
|
||
|
progress);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
success = FALSE;
|
||
|
}
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@headers = qw("gegl/pika-babl.h"
|
||
|
"core/pika.h"
|
||
|
"core/pikaimage.h"
|
||
|
"core/pikaimage-convert-indexed.h"
|
||
|
"core/pikaimage-convert-precision.h"
|
||
|
"core/pikaimage-convert-type.h"
|
||
|
"core/pikaitemstack.h"
|
||
|
"core/pikapalette.h"
|
||
|
"pikapdberror.h"
|
||
|
"pikapdb-utils.h"
|
||
|
"pika-intl.h");
|
||
|
|
||
|
@procs = qw(image_convert_rgb
|
||
|
image_convert_grayscale
|
||
|
image_convert_indexed
|
||
|
image_convert_set_dither_matrix
|
||
|
image_convert_precision);
|
||
|
|
||
|
%exports = (app => [@procs], lib => [@procs]);
|
||
|
|
||
|
$desc = 'Image Convert';
|
||
|
$doc_title = 'pikaimageconvert';
|
||
|
$doc_short_desc = 'Conversions between RGB, indexed, and grayscale modes.';
|
||
|
$doc_long_desc = 'Conversions between RGB, indexed, and grayscale modes.';
|
||
|
|
||
|
1;
|