1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
|
/* -*- mode: c tab-width: 2; c-basic-indent: 2; indent-tabs-mode: nil -*-
* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
*
* Gimp image compositing
* Copyright (C) 2003 Helvetix Victorinox, a pseudonym, <helvetix@gimp.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <glib-object.h>
#include "base/base-types.h"
#include "gimp-composite.h"
#include "gimp-composite-generic.h"
#ifdef ARCH_X86
#include "gimp-composite-mmx.h"
#include "gimp-composite-sse.h"
#endif
/*
* Details about pixel formats, bits-per-pixel alpha and non alpha
* versions of pixel formats.
*/
/*
* Report on the number of bytes a particular pixel format consumes per pixel.
*/
const guchar gimp_composite_pixel_bpp[] =
{
1, /* GIMP_PIXELFORMAT_V8 */
2, /* GIMP_PIXELFORMAT_VA8 */
3, /* GIMP_PIXELFORMAT_RGB8 */
4, /* GIMP_PIXELFORMAT_RGBA8 */
#if GIMP_COMPOSITE_16BIT
2, /* GIMP_PIXELFORMAT_V16 */
4, /* GIMP_PIXELFORMAT_VA16 */
6, /* GIMP_PIXELFORMAT_RGB16 */
8, /* GIMP_PIXELFORMAT_RGBA16 */
#endif
#if GIMP_COMPOSITE_32BIT
2, /* GIMP_PIXELFORMAT_V32 */
4, /* GIMP_PIXELFORMAT_VA32 */
6, /* GIMP_PIXELFORMAT_RGB32 */
8, /* GIMP_PIXELFORMAT_RGBA32 */
#endif
0, /* GIMP_PIXELFORMAT_ANY */
};
const gchar *gimp_composite_pixel_name[] =
{
"GIMP_PIXELFORMAT_V8",
"GIMP_PIXELFORMAT_VA8",
"GIMP_PIXELFORMAT_RGB8",
"GIMP_PIXELFORMAT_RGBA8",
#if GIMP_COMPOSITE_16BIT
"GIMP_PIXELFORMAT_V16",
"GIMP_PIXELFORMAT_VA16",
"GIMP_PIXELFORMAT_RGB16 ",
"GIMP_PIXELFORMAT_RGBA16 ",
#endif
#if GIMP_COMPOSITE_32BIT
"GIMP_PIXELFORMAT_V32",
"GIMP_PIXELFORMAT_VA32",
"GIMP_PIXELFORMAT_RGB32 ",
"GIMP_PIXELFORMAT_RGBA32 ",
#endif
"GIMP_PIXELFORMAT_ANY",
};
/*
* Report true (non-zero) if a pixel format has alpha.
*/
const guchar gimp_composite_pixel_alphap[] =
{
0, /* GIMP_PIXELFORMAT_V8 */
1, /* GIMP_PIXELFORMAT_VA8 */
0, /* GIMP_PIXELFORMAT_RGB8 */
1, /* GIMP_PIXELFORMAT_RGBA8 */
#if GIMP_COMPOSITE_16BIT
0, /* GIMP_PIXELFORMAT_V16 */
1, /* GIMP_PIXELFORMAT_VA16 */
0, /* GIMP_PIXELFORMAT_RGB16 */
1, /* GIMP_PIXELFORMAT_RGBA16 */
#endif
#if GIMP_COMPOSITE_32BIT
0, /* GIMP_PIXELFORMAT_V32 */
1, /* GIMP_PIXELFORMAT_VA32 */
0, /* GIMP_PIXELFORMAT_RGB32 */
1, /* GIMP_PIXELFORMAT_RGBA32 */
#endif
0, /* GIMP_PIXELFORMAT_UNKNOWN */
};
/*
* Convert to/from pixel formats with/without alpha.
*/
const GimpPixelFormat gimp_composite_pixel_alpha[] =
{
GIMP_PIXELFORMAT_VA8, /* GIMP_PIXELFORMAT_V8 */
GIMP_PIXELFORMAT_V8, /* GIMP_PIXELFORMAT_VA8 */
GIMP_PIXELFORMAT_RGBA8, /* GIMP_PIXELFORMAT_RGB8 */
GIMP_PIXELFORMAT_RGB8, /* GIMP_PIXELFORMAT_RGBA8 */
#if GIMP_COMPOSITE_16BIT
GIMP_PIXELFORMAT_VA16,
GIMP_PIXELFORMAT_V16,
GIMP_PIXELFORMAT_RGBA16,
GIMP_PIXELFORMAT_RGB16
#endif
#if GIMP_COMPOSITE_32BIT
GIMP_PIXELFORMAT_VA32,
GIMP_PIXELFORMAT_V32,
GIMP_PIXELFORMAT_RGBA32,
GIMP_PIXELFORMAT_RGB32
#endif
GIMP_PIXELFORMAT_ANY, /* GIMP_PIXELFORMAT_ANY */
};
/*
* XXX I don't like to put this here. I think this information,
* specific to the functions, ought to be with the function.
*/
struct GimpCompositeOperationEffects gimp_composite_operation_effects[] =
{
{ TRUE, TRUE, FALSE, }, /* GIMP_NORMAL_MODE */
{ TRUE, TRUE, FALSE, }, /* GIMP_DISSOLVE_MODE */
{ TRUE, TRUE, FALSE, }, /* GIMP_BEHIND_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_MULTIPLY_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_SCREEN_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_OVERLAY_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_DIFFERENCE_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_ADDITION_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_SUBTRACT_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_DARKEN_ONLY_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_LIGHTEN_ONLY_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_HUE_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_SATURATION_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_COLOR_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_VALUE_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_DIVIDE_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_DODGE_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_BURN_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_HARDLIGHT_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_SOFTLIGHT_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_GRAIN_EXTRACT_MODE */
{ FALSE, FALSE, FALSE, }, /* GIMP_GRAIN_MERGE_MODE */
{ TRUE, FALSE, TRUE, }, /* GIMP_COLOR_ERASE_MODE */
{ TRUE, FALSE, TRUE, }, /* GIMP_ERASE_MODE */
{ TRUE, TRUE, TRUE, }, /* GIMP_REPLACE_MODE */
{ TRUE, TRUE, FALSE, }, /* GIMP_ANTI_ERASE_MODE */
{ FALSE, FALSE, FALSE }, /* GIMP_SWAP */
{ FALSE, FALSE, FALSE }, /* GIMP_SCALE */
{ FALSE, FALSE, FALSE }, /* GIMP_CONVERT */
};
struct
{
gchar announce_function;
} gimp_composite_debug;
struct GimpCompositeOptions gimp_composite_options =
{
GIMP_COMPOSITE_OPTION_USE
};
const gchar * gimp_composite_function_name[GIMP_COMPOSITE_N][GIMP_PIXELFORMAT_N][GIMP_PIXELFORMAT_N][GIMP_PIXELFORMAT_N];
void (*gimp_composite_function[GIMP_COMPOSITE_N][GIMP_PIXELFORMAT_N][GIMP_PIXELFORMAT_N][GIMP_PIXELFORMAT_N])(GimpCompositeContext *);
/**
* gimp_composite_dispatch:
* @ctx: The compositing context
*
* Given a compositing context, perform the compositing function
* dictated by the compositing context operation. There is no return
* value, all results are in the compositing context.
**/
void
gimp_composite_dispatch (GimpCompositeContext *ctx)
{
void (*function) (GimpCompositeContext *);
function = gimp_composite_function[ctx->op][ctx->pixelformat_A][ctx->pixelformat_B][ctx->pixelformat_D];
if (function)
{
if (gimp_composite_options.bits & GIMP_COMPOSITE_OPTION_VERBOSE)
{
printf ("%s %s %s %s = %p\n",
gimp_composite_mode_astext (ctx->op),
gimp_composite_pixelformat_astext (ctx->pixelformat_A),
gimp_composite_pixelformat_astext (ctx->pixelformat_B),
gimp_composite_pixelformat_astext (ctx->pixelformat_D),
function);
}
(*function) (ctx);
}
else
{
printf ("gimp_composite: unsupported operation: %s %s %s %s\n",
gimp_composite_mode_astext (ctx->op),
gimp_composite_pixelformat_astext (ctx->pixelformat_A),
gimp_composite_pixelformat_astext (ctx->pixelformat_B),
gimp_composite_pixelformat_astext (ctx->pixelformat_D));
}
}
/**
* gimp_composite_context_print:
* @ctx: The context to print
*
* Print a human readable form of a GimpCompositeContext on stdout.
**/
void
gimp_composite_context_print (GimpCompositeContext *ctx)
{
printf ("%p: op=%s\n A=%s(%d):%p\n B=%s(%d):%p\n D=%s(%d):%p\n M=%s(%d):%p\n n_pixels=%lu\n",
ctx,
gimp_composite_mode_astext (ctx->op),
gimp_composite_pixelformat_astext (ctx->pixelformat_A),
ctx->pixelformat_A, ctx->A,
gimp_composite_pixelformat_astext (ctx->pixelformat_B),
ctx->pixelformat_B, ctx->B,
gimp_composite_pixelformat_astext (ctx->pixelformat_D),
ctx->pixelformat_D, ctx->D,
gimp_composite_pixelformat_astext (ctx->pixelformat_M),
ctx->pixelformat_M, ctx->M,
ctx->n_pixels);
}
/**
* gimp_composite_mode_astext:
* @op:
*
* Given a GimpCompositeOperatin, return a string representation of the name
* of that operation.
*
* Returns: gchar *, the name
**/
const gchar *
gimp_composite_mode_astext (GimpCompositeOperation op)
{
switch (op)
{
case GIMP_COMPOSITE_NORMAL: return ("GIMP_COMPOSITE_NORMAL");
case GIMP_COMPOSITE_DISSOLVE: return ("GIMP_COMPOSITE_DISSOLVE");
case GIMP_COMPOSITE_BEHIND: return ("GIMP_COMPOSITE_BEHIND");
case GIMP_COMPOSITE_MULTIPLY: return ("GIMP_COMPOSITE_MULTIPLY");
case GIMP_COMPOSITE_SCREEN: return ("GIMP_COMPOSITE_SCREEN");
case GIMP_COMPOSITE_OVERLAY: return ("GIMP_COMPOSITE_OVERLAY");
case GIMP_COMPOSITE_DIFFERENCE: return ("GIMP_COMPOSITE_DIFFERENCE");
case GIMP_COMPOSITE_ADDITION: return ("GIMP_COMPOSITE_ADDITION");
case GIMP_COMPOSITE_SUBTRACT: return ("GIMP_COMPOSITE_SUBTRACT");
case GIMP_COMPOSITE_DARKEN: return ("GIMP_COMPOSITE_DARKEN");
case GIMP_COMPOSITE_LIGHTEN: return ("GIMP_COMPOSITE_LIGHTEN");
case GIMP_COMPOSITE_HUE: return ("GIMP_COMPOSITE_HUE");
case GIMP_COMPOSITE_SATURATION: return ("GIMP_COMPOSITE_SATURATION");
case GIMP_COMPOSITE_COLOR_ONLY: return ("GIMP_COMPOSITE_COLOR_ONLY");
case GIMP_COMPOSITE_VALUE: return ("GIMP_COMPOSITE_VALUE");
case GIMP_COMPOSITE_DIVIDE: return ("GIMP_COMPOSITE_DIVIDE");
case GIMP_COMPOSITE_DODGE: return ("GIMP_COMPOSITE_DODGE");
case GIMP_COMPOSITE_BURN: return ("GIMP_COMPOSITE_BURN");
case GIMP_COMPOSITE_HARDLIGHT: return ("GIMP_COMPOSITE_HARDLIGHT");
case GIMP_COMPOSITE_SOFTLIGHT: return ("GIMP_COMPOSITE_SOFTLIGHT");
case GIMP_COMPOSITE_GRAIN_EXTRACT: return ("GIMP_COMPOSITE_GRAIN_EXTRACT");
case GIMP_COMPOSITE_GRAIN_MERGE: return ("GIMP_COMPOSITE_GRAIN_MERGE");
case GIMP_COMPOSITE_COLOR_ERASE: return ("GIMP_COMPOSITE_COLOR_ERASE");
case GIMP_COMPOSITE_ERASE: return ("GIMP_COMPOSITE_ERASE");
case GIMP_COMPOSITE_REPLACE: return ("GIMP_COMPOSITE_REPLACE");
case GIMP_COMPOSITE_ANTI_ERASE: return ("GIMP_COMPOSITE_ANTI_ERASE");
case GIMP_COMPOSITE_BLEND: return ("GIMP_COMPOSITE_BLEND");
case GIMP_COMPOSITE_SHADE: return ("GIMP_COMPOSITE_SHADE");
case GIMP_COMPOSITE_SWAP: return ("GIMP_COMPOSITE_SWAP");
case GIMP_COMPOSITE_SCALE: return ("GIMP_COMPOSITE_SCALE");
case GIMP_COMPOSITE_CONVERT: return ("GIMP_COMPOSITE_CONVERT");
case GIMP_COMPOSITE_XOR: return ("GIMP_COMPOSITE_XOR");
default:
break;
}
return ("bad mode");
}
/**
* gimp_composite_pixelformat_astext:
* @format: The format.
*
* Given a GimpPixelFormat, return a string representation of the name
* of that format.
*
* Returns: gchar *, the name
**/
const gchar *
gimp_composite_pixelformat_astext (GimpPixelFormat format)
{
switch (format) {
case GIMP_PIXELFORMAT_V8: return ("V8");
case GIMP_PIXELFORMAT_VA8: return ("VA8");
case GIMP_PIXELFORMAT_RGB8: return ("RGB8");
case GIMP_PIXELFORMAT_RGBA8: return ("RGBA8");
#if GIMP_COMPOSITE_16BIT
case GIMP_PIXELFORMAT_V16: return ("V16");
case GIMP_PIXELFORMAT_VA16: return ("VA16");
case GIMP_PIXELFORMAT_RGB16: return ("RGB16");
case GIMP_PIXELFORMAT_RGBA16: return ("RGBA16");
#endif
#if GIMP_COMPOSITE_32BIT
case GIMP_PIXELFORMAT_V32: return ("V32");
case GIMP_PIXELFORMAT_VA32: return ("VA32");
case GIMP_PIXELFORMAT_RGB32: return ("RGB32");
case GIMP_PIXELFORMAT_RGBA32: return ("RGBA32");
#endif
case GIMP_PIXELFORMAT_ANY: return ("ANY");
default:
break;
}
return ("bad format");
}
/**
* gimp_composite_init:
* @be_verbose: whether to be verbose on stdout
* @use_cpu_accel: whether to use accelerated routines like MMX
*
* Initialise the Gimp Compositing subsystem. This includes checking
* for user options and environment, installing the generic set of
* compositing operation handlers, followed by overloading those which
* are supported by the current cpu/hardware.
**/
void
gimp_composite_init (gboolean be_verbose,
gboolean use_cpu_accel)
{
const gchar *p;
if ((p = g_getenv ("GIMP_COMPOSITE")))
{
gimp_composite_options.bits = strtoul(p, NULL, 16);
}
if (!use_cpu_accel)
gimp_composite_options.bits |= GIMP_COMPOSITE_OPTION_NOEXTENSIONS;
if (be_verbose)
g_printerr ("gimp_composite: use=%s, verbose=%s\n",
(gimp_composite_options.bits & GIMP_COMPOSITE_OPTION_USE) ?
"yes" : "no",
(gimp_composite_options.bits & GIMP_COMPOSITE_OPTION_VERBOSE) ?
"yes" : "no");
gimp_composite_generic_install ();
/*
* Here is where you "glue" in the initialisation of your
* optimisations.
*
* Declare the install() function external, and then call it. A
* return value of TRUE from the install function means the
* installer was successful in instantiating itself. For example,
* it succeeded in hooking in the functions with the special
* optimisation instructions, or hardware, or whatever.
*/
if (! (gimp_composite_options.bits & GIMP_COMPOSITE_OPTION_NOEXTENSIONS))
{
extern gboolean gimp_composite_mmx_install (void);
extern gboolean gimp_composite_sse_install (void);
extern gboolean gimp_composite_sse2_install (void);
extern gboolean gimp_composite_3dnow_install (void);
extern gboolean gimp_composite_altivec_install (void);
extern gboolean gimp_composite_vis_install (void);
gboolean can_use_mmx = gimp_composite_mmx_install ();
gboolean can_use_sse = gimp_composite_sse_install ();
gboolean can_use_sse2 = gimp_composite_sse2_install ();
gboolean can_use_3dnow = gimp_composite_3dnow_install ();
gboolean can_use_altivec = gimp_composite_altivec_install ();
gboolean can_use_vis = gimp_composite_vis_install ();
if (be_verbose)
g_printerr ("Processor instruction sets: "
"%cmmx %csse %csse2 %c3dnow %caltivec %cvis\n",
can_use_mmx ? '+' : '-',
can_use_sse ? '+' : '-',
can_use_sse2 ? '+' : '-',
can_use_3dnow ? '+' : '-',
can_use_altivec ? '+' : '-',
can_use_vis ? '+' : '-');
}
}
|