Skip to content
Commits on Source (71)
lua_files = files(
'cairo_h.lua',
'cairo.lua',
'gegl_box-blur.lua',
'gegl_c2g.lua',
'gegl_crop.lua',
'gegl_edge-neon.lua',
'gegl_fill-path.lua',
'gegl_gaussian-blur.lua',
'gegl_linear-gradient.lua',
'gegl_median-blur.lua',
'gegl_radial-gradient.lua',
'gegl_rectangle.lua',
'gegl_rotate.lua',
'gegl_snn-mean.lua',
......@@ -25,6 +23,27 @@ lua_files = files(
'viewer.lua',
)
lua_symlink_files = {
'gegl_crop.lua' : 'gegl_rectangle.lua',
'gegl_fill-path.lua' : 'gegl_vector-stroke.lua',
'gegl_radial-gradient.lua' : 'gegl_linear-gradient.lua',
}
# Windows doesn't like *nix symlinks so we check if the symlinked lua
# files are valid and if not copy the original to the build dir in place
# of the symlink
fs=import('fs')
foreach _link, _file : lua_symlink_files
if fs.is_symlink(_link)
lua_files += _link
else
lua_files += configure_file(
input: _file,
output: _link,
copy: true,
)
endif
endforeach
if lua.found()
install_data(
lua_files,
......
subdir('lua')
subdir('lua', if_found: lua)
gegl_sources = files(
'gegl-options.c',
......@@ -11,11 +12,10 @@ gegl_deps = [
glib,
gobject,
math,
#libdl
]
if libpng.found()
gegl_deps += [ libpng, ]
gegl_deps += libpng
endif
if mrg.found() and gexiv2.found() and lua.found()
......@@ -30,21 +30,21 @@ if mrg.found() and gexiv2.found() and lua.found()
gegl_sources += custom_target('argvs-commands.inc',
input : gegl_sources,
output: 'argvs-commands.inc',
command: [ argvs_extract, '@INPUT@' ],
command: [argvs_extract, '@INPUT@'],
capture: true,
)
gegl_deps += [ mrg, gexiv2, sdl1, lua, gio ]
gegl_deps += [mrg, gexiv2, lua, gio]
endif
if libspiro.found()
gegl_sources += files('gegl-path-spiro.c')
gegl_deps += [ libspiro, ]
gegl_deps += libspiro
endif
gegl_bin = executable('gegl',
gegl_sources,
include_directories: [ rootInclude, geglInclude, ],
include_directories: [rootInclude, geglInclude],
dependencies: gegl_deps,
export_dynamic: true,
link_with: gegl_lib,
......
GEGL-0.4.30 2021-03-27
----------------------
Build:
~~~~~~
libjpeg and libpng are now required.
Reduce babl requirement to 0.1.78, it is *highly* recommended to build with
a newer babl though despite it being what wants to increase the meson
version requirement. Improved gir build options, fixes for cross compilation.
Large improvements of integration of tests with meson. XML tests are now
outputting in TAP format. As well as many related cleanups of tests that have
been in a state of slight bitrot since the migration to meson.
Upload meson logs as artifcats, use release and debugoptimized build types.
Pin glibc package in arch CI build to a version before it hard depends on linux
4.4.
New Operations:
~~~~~~~~~~~~~~~
negative-darkroom: This operation is for artists who use hybrid workflow
technique of analog photography. After scanning a developed negative, this
operation is used to invert the scan to create a positive image by simulating
the light behaviour of darkroom enlarger and common photographic papers.
Operations:
~~~~~~~~~~~
jpg-load,png-load,tiff-load: show ICC relatd problems as warnings.
rgbe-load : fix handling of exponent=0 in RLE encoded files.
color-reduction : Added blue-noise modes, the patents are expired for some
years already, also added fix to levels parameters; enabling bi-level.
fattal02 : ensure gaussian pyramid has at least one level.
paint-select (in workshop): multi-level banded graphcut, sub-region rather
than full buffer rcomputations and other improvements.
Contributors to this release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dimspingos, Jan Vesely, John Marshall, JonnyRobbie, Jordi Mas, Милош Поповић,
Olivier Tilloy, Øyvind Kolås, Philipp Kiemle, Piotr Drąg, Sabri Ünal,
scootergrisen, Thomas Manni, Yuri Chornoivan.
GEGL-0.4.28 2020-12-20
----------------------
......
......@@ -44,9 +44,9 @@ foreach example : examples
# Fore use as tests for ff-load-save
if example_name == 'gegl-video'
gegl_video_example = exe
gegl_video = exe
endif
if example_name == 'frame-counter'
frame_counter_example = exe
frame_counter = exe
endif
endforeach
......@@ -39,6 +39,8 @@ gegl_dither_method_get_type (void)
{ GEGL_DITHER_ARITHMETIC_ADD_COVARIANT, N_("Arithmetic add covariant"), "add-covariant" },
{ GEGL_DITHER_ARITHMETIC_XOR, N_("Arithmetic xor"), "xor" },
{ GEGL_DITHER_ARITHMETIC_XOR_COVARIANT, N_("Arithmetic xor covariant"), "xor-covariant" },
{ GEGL_DITHER_BLUE_NOISE, N_("Blue Noise"), "blue-noise" },
{ GEGL_DITHER_BLUE_NOISE_COVARIANT, N_("Blue Noise Covariant"), "blue-noise-covariant" },
{ 0, NULL, NULL }
};
......
......@@ -46,6 +46,8 @@ typedef enum {
GEGL_DITHER_ARITHMETIC_ADD_COVARIANT,
GEGL_DITHER_ARITHMETIC_XOR,
GEGL_DITHER_ARITHMETIC_XOR_COVARIANT,
GEGL_DITHER_BLUE_NOISE,
GEGL_DITHER_BLUE_NOISE_COVARIANT,
} GeglDitherMethod;
GType gegl_dither_method_get_type (void) G_GNUC_CONST;
......
gegl_library_build_dir = meson.current_build_dir()
geglInclude = include_directories(
'.',
'buffer',
......@@ -91,7 +93,7 @@ gegl_ldflags = os_osx ? ['-framework', 'OpenCL'] : []
gegl_lib = library(api_name,
gegl_sources,
include_directories: [ rootInclude, geglInclude, ],
include_directories: [rootInclude, geglInclude],
dependencies: [
babl,
glib,
......@@ -99,20 +101,18 @@ gegl_lib = library(api_name,
math,
gmodule,
],
c_args: [ gegl_cflags, ],
link_args: [ gegl_ldflags, ],
c_args: gegl_cflags,
link_args: gegl_ldflags,
install: true,
version: so_version,
)
introspection_sources = gegl_introspectable_headers + files(
'gegl-introspection-support.h',
'opencl' / 'gegl-cl-introspection-support.h',
)
if get_option('introspection')
if g_ir.found()
introspection_sources = gegl_introspectable_headers + files(
'gegl-introspection-support.h',
'opencl' / 'gegl-cl-introspection-support.h',
)
gegl_gir = gnome.generate_gir(gegl_lib,
sources: introspection_sources,
......
......@@ -14,6 +14,7 @@
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
* Copyright 2010 Danny Robson <danny@blubinc.net>
* 2021 Øyvind Kolås <pippin@gimp.org>
*/
#include "config.h"
......@@ -529,23 +530,22 @@ rgbe_apply_exponent (const rgbe_file *file,
if (e == 0)
{
rgb[OFFSET_R] = rgb[OFFSET_G] = rgb[OFFSET_B] = 0;
goto cleanup;
}
else
{
mult = ldexp (1.0, e - (128 + 8));
rgb[OFFSET_R] *= mult *
file->header.exposure *
file->header.colorcorr[OFFSET_R];
rgb[OFFSET_G] *= mult *
file->header.exposure *
file->header.colorcorr[OFFSET_G];
rgb[OFFSET_B] *= mult *
file->header.exposure *
file->header.colorcorr[OFFSET_B];
}
mult = ldexp (1.0, e - (128 + 8));
rgb[OFFSET_R] *= mult *
file->header.exposure *
file->header.colorcorr[OFFSET_R];
rgb[OFFSET_G] *= mult *
file->header.exposure *
file->header.colorcorr[OFFSET_G];
rgb[OFFSET_B] *= mult *
file->header.exposure *
file->header.colorcorr[OFFSET_B];
rgb[OFFSET_A] = 1.0f;
cleanup:
return;
rgb[OFFSET_A] = 1.0f;
}
......
project('gegl',
'c', 'cpp',
license: 'GPL3+',
version: '0.4.28',
meson_version: '>=0.54.0',
version: '0.4.30',
meson_version: '>=0.50.0',
default_options: [
'c_std=gnu11',
'cpp_std=gnu++14',
......@@ -19,6 +19,8 @@ project('gegl',
# if backwards compatibility has been broken,
# set binary_age _and_ interface_age to 0.
config = configuration_data()
pkgconfig = import('pkgconfig')
i18n = import('i18n')
gnome = import('gnome')
......@@ -27,7 +29,13 @@ python = import('python').find_installation()
cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
buildtype = get_option('buildtype')
config = configuration_data()
gegl_prefix = get_option('prefix')
gegl_libdir = join_paths(gegl_prefix, get_option('libdir'))
project_build_root = meson.current_build_dir()
project_source_root = meson.current_source_dir()
################################################################################
# Project infos
......@@ -99,16 +107,14 @@ cflags_common = []
cflags_c = []
cflags_cpp = []
cflags_common += [
'-DHAVE_CONFIG_H',
]
cflags_common += '-DHAVE_CONFIG_H'
if buildtype == 'debugoptimized' or buildtype == 'release'
cflags_common += ['-Ofast']
cflags_common += '-Ofast'
endif
if buildtype == 'debugoptimized' or buildtype == 'debug'
cflags_common += ['-DGEGL_ENABLE_DEBUG']
cflags_common += '-DGEGL_ENABLE_DEBUG'
endif
cflags_common += [
......@@ -123,7 +129,7 @@ cflags_c = [
]
if os_win32
cflags_common += [ '-D_FILE_OFFSET_BITS=64' ]
cflags_common += '-D_FILE_OFFSET_BITS=64'
endif
cflags_c = cflags_common + cflags_c
......@@ -133,16 +139,15 @@ add_project_arguments(cc.get_supported_arguments(cflags_c), language: 'c')
add_project_arguments(cpp.get_supported_arguments(cflags_cpp), language: 'cpp')
################################################################################
# Utilities
# Build Utilities
bash = find_program('bash')
dot = os_win32 ? find_program('dot.exe', required: false) : find_program('dot', required: false)
bash = find_program('bash')
perl = find_program('perl5', 'perl', required: false)
asciidoc = find_program('asciidoc', required: false)
enscript = find_program('enscript', required: false)
rsvg_convert= find_program('rsvg-convert', required: false)
ruby = find_program('ruby', required: false)
asciidoc = find_program('asciidoc', required: false, native: true)
dot = find_program('dot', required: false, native: true)
perl = find_program('perl5', 'perl', required: false, native: true)
rsvg_convert = find_program('rsvg-convert', required: false, native: true)
ruby = find_program('ruby', required: false, native: true)
################################################################################
# Required Dependencies
......@@ -157,51 +162,77 @@ math = cc.find_library('m', required: false)
libdl = cc.find_library('dl', required : false)
thread = dependency('threads')
babl = dependency('babl', version: '>=0.1.84')
glib = dependency('glib-2.0', version: '>=2.44.0')
gobject = dependency('gobject-2.0', version: '>=2.44.0')
gmodule = dependency('gmodule-2.0', version: '>=2.44.0')
gthread = dependency('gthread-2.0', version: '>=2.44.0')
babl = dependency('babl', version: '>=0.1.78')
glib = dependency('glib-2.0', version: '>=2.44.0')
gobject = dependency('gobject-2.0', version: '>=2.44.0')
gmodule = dependency('gmodule-2.0', version: '>=2.44.0')
gthread = dependency('gthread-2.0', version: '>=2.44.0')
gio_os = os_win32 ? 'gio-windows-2.0' : 'gio-unix-2.0'
gio = [
dependency('gio-2.0', version: '>=2.44.0'),
dependency(gio_os, version: '>=2.44.0'),
dependency('gio-2.0', version: '>=2.44.0'),
dependency(gio_os, version: '>=2.44.0'),
]
json_glib = dependency('json-glib-1.0', version: '>=1.2.6')
libjpeg = dependency('libjpeg', version: '>=1.0.0')
libpng = dependency('libpng', version: '>=1.6.0')
# Required libraries eventually provided in subprojects/ subdir
poly2tri_c= dependency('poly2tri-c', version: '>=0.0.0',
fallback: [ 'poly2tri-c', 'poly2tri_c' ],
poly2tri_c= dependency('poly2tri-c', version: '>=0.0.0',
fallback: ['poly2tri-c', 'poly2tri_c'],
required: false,
)
libnsgif = dependency('libnsgif',
fallback: [ 'libnsgif', 'libnsgif' ],
fallback: ['libnsgif', 'libnsgif'],
)
################################################################################
# Optionnal Dependencies
# GEGL library
if get_option('introspection') != 'false'
g_ir = dependency('gobject-introspection-1.0', version: '>=1.32.0',
required: get_option('introspection') == 'true' ? true : false,
)
else
g_ir = disabler()
endif
if g_ir.found()
vapigen = dependency('vapigen', version:'>=0.20.0',
required: get_option('vapigen')
)
else
vapigen = disabler()
endif
# GEGL binary
gexiv2 = dependency('gexiv2', version: '>=0.0.0',
required: get_option('gexiv2')
)
config.set('HAVE_GEXIV2', gexiv2.found())
lua = dependency('luajit', version: '>=2.0.4',
required: get_option('lua')
)
config.set('HAVE_LUA', lua.found())
mrg = dependency('mrg', version: '>=0.0.0',
required: get_option('mrg')
)
config.set('HAVE_MRG', mrg.found())
# Operations
gdk_pixbuf= dependency('gdk-pixbuf-2.0', version:'>=2.32.0',
required: get_option('gdk-pixbuf')
)
cairo = dependency('cairo', version: '>=1.12.2',
required: get_option('cairo')
)
pango = dependency('pango', version: '>=1.38.0',
required: get_option('pango')
)
pangocairo= dependency('pangocairo', version: '>=1.38.0',
required: get_option('pangocairo')
)
cairo = dependency('cairo', version: '>=1.12.2',
required: get_option('cairo')
)
exiv2 = dependency('exiv2', version: '>=0.25',
required: get_option('exiv2')
)
gexiv2 = dependency('gexiv2', version: '>=0.0.0',
required: get_option('gexiv2')
)
config.set('HAVE_GEXIV2', gexiv2.found())
jasper = dependency('jasper', version: '>=1.900.1',
required: get_option('jasper')
......@@ -212,12 +243,6 @@ lcms = dependency('lcms2', version: '>=2.8',
lensfun = dependency('lensfun', version: '>=0.2.5',
required: get_option('lensfun')
)
libjpeg = dependency('libjpeg', version: '>=1.0.0',
required: get_option('libjpeg')
)
libpng = dependency('libpng', version: '>=1.6.0',
required: get_option('libpng')
)
libraw = dependency('libraw', version: '>=0.15.4',
required: get_option('libraw')
)
......@@ -236,21 +261,18 @@ libv4l1 = dependency('libv4l1', version: '>=1.0.1',
libv4l2 = dependency('libv4l2', version: '>=1.0.1',
required: get_option('libv4l2')
)
lua = dependency('luajit', version: '>=2.0.4',
required: get_option('lua')
)
config.set('HAVE_LUA', lua.found())
mrg = dependency('mrg', version: '>=0.1.4',
required: get_option('mrg')
libwebp = dependency('libwebp', version:'>=0.5.0',
required: get_option('webp')
)
config.set('HAVE_MRG', mrg.found())
maxflow = dependency('maxflow', version: '>=3.0.4',
required: get_option('maxflow')
)
openexr = dependency('OpenEXR', version: '>=1.6.1',
required: get_option('openexr')
)
poppler = dependency('poppler-glib', version: '>=0.71.0',
required: get_option('poppler')
)
sdl1 = dependency('sdl', version: '>=1.2.0',
required: get_option('sdl1')
)
......@@ -258,25 +280,7 @@ sdl2 = dependency('sdl2', version: '>=2.0.5',
required: get_option('sdl2')
)
vapigen = dependency('vapigen', version:'>=0.20.0',
required: get_option('vapigen')
)
libwebp = dependency('libwebp', version:'>=0.5.0',
required: get_option('webp')
)
poppler = dependency('poppler-glib', version: '>=0.71.0',
required: get_option('poppler')
)
pygobject3 = dependency('pygobject-3.0', version: '>=3.2.0',
required: get_option('pygobject')
)
gobj_introsp = dependency('gobject-introspection-1.0', version: '>=1.32.0',
required: get_option('pygobject')
)
pygobject_found = pygobject3.found() and gobj_introsp.found()
# AV libs
libavcodec = dependency('libavcodec', version: '>=55.69.100',
required: get_option('libav')
)
......@@ -295,8 +299,9 @@ avlibs_found = (
libavutil.found() and
libswscale.found()
)
avlibs = avlibs_found ? [ libavcodec, libavformat, libavutil, libswscale ] : []
avlibs = avlibs_found ? [libavcodec, libavformat, libavutil, libswscale] : []
# libumfpack
libumfpack = cc.find_library('umfpack', required: get_option('umfpack'))
if libumfpack.found()
have_umfpack = cc.has_header('umfpack.h')
......@@ -316,6 +321,15 @@ if libumfpack.found()
config.set('HAVE_SUITESPARSE_UMFPACK_H', have_ss_umfpack)
endif
# Tests
if g_ir.found()
pygobject3 = dependency('pygobject-3.0', version: '>=3.2.0',
required: get_option('pygobject')
)
else
pygobject3 = disabler()
endif
################################################################################
# Subdirs
......@@ -355,7 +369,6 @@ pkgconfig.generate(filebase: 'gegl-' + api_version,
gmodule,
gio,
json_glib,
babl,
],
libraries: [
......@@ -367,43 +380,59 @@ pkgconfig.generate(filebase: 'gegl-' + api_version,
)
message('\n'.join(['',
'Building GEGL with prefix=@0@'.format(get_option('prefix')),
'',
'Optional features:',
' GEGL docs: @0@'.format(get_option('docs')),
' Build workshop: @0@'.format(get_option('workshop')),
' Vala support: @0@'.format(vapigen.found()),
'',
'Optional dependencies:',
' asciidoc: @0@'.format(asciidoc.found()),
' dot: @0@'.format(dot.found()),
' enscript: @0@'.format(enscript.found()),
' mrg: @0@'.format(mrg.found()),
' Ruby: @0@'.format(ruby.found()),
' Luajit: @0@'.format(lua.found()),
' Cairo: @0@'.format(cairo.found()),
' Pango: @0@'.format(pango.found()),
' pangocairo: @0@'.format(pangocairo.found()),
' poppler: @0@'.format(poppler.found()),
' GDKPixbuf: @0@'.format(gdk_pixbuf.found()),
' JPEG: @0@'.format(libjpeg.found()),
' PNG: @0@'.format(libpng.found()),
' OpenEXR: @0@'.format(openexr.found()),
' rsvg: @0@'.format(librsvg.found()),
' SDL: @0@'.format(sdl1.found()),
' libraw: @0@'.format(libraw.found()),
' Jasper: @0@'.format(jasper.found()),
' av libs: @0@'.format(avlibs_found),
' V4L: @0@'.format(libv4l1.found()),
' V4L2: @0@'.format(libv4l2.found()),
' spiro: @0@'.format(libspiro.found()),
' EXIV: @0@'.format(exiv2.found()),
' gexiv2: @0@'.format(gexiv2.found()),
' umfpack: @0@'.format(libumfpack.found()),
' TIFF @0@'.format(libtiff.found()),
' webp: @0@'.format(libwebp.found()),
' maxflow: @0@'.format(maxflow.found()),
' poly2tri-c: @0@ (@1@)'.format(poly2tri_c.found(),poly2tri_c.type_name()),
'']))
################################################################################
# Build summary
summary(
{
'prefix': gegl_prefix,
'libdir': get_option('libdir'),
}, section: 'Directories'
)
summary(
{
'GEGL docs' : get_option('docs'),
'Build workshop' : get_option('workshop'),
'Introspection' : g_ir.found(),
'Vala support' : vapigen.found(),
}, section: 'Optional features'
)
summary(
{
'asciidoc' : asciidoc.found(),
'dot' : dot.found(),
'pygobject' : pygobject3.found(),
'rsvg-convert' : rsvg_convert.found(),
'Ruby' : ruby.found(),
}, section: 'Optional build utilities'
)
summary(
{
'avlibs' : avlibs_found,
'Cairo' : cairo.found(),
'GDKPixbuf' : gdk_pixbuf.found(),
'gexiv2' : gexiv2.found(),
'Jasper' : jasper.found(),
'JPEG' : libjpeg.found(),
'lcms' : lcms.found(),
'libnsgif' : libnsgif.found(),
'libraw' : libraw.found(),
'Luajit' : lua.found(),
'maxflow' : maxflow.found(),
'mrg' : mrg.found(),
'Pango' : pango.found(),
'pangocairo' : pangocairo.found(),
'poly2tri-c' : poly2tri_c.found(),
'poppler' : poppler.found(),
'OpenEXR' : openexr.found(),
'rsvg' : librsvg.found(),
'SDL1' : sdl1.found(),
'SDL2' : sdl2.found(),
'spiro' : libspiro.found(),
'TIFF' : libtiff.found(),
'umfpack' : libumfpack.found(),
'V4L' : libv4l1.found(),
'V4L2' : libv4l2.found(),
'webp' : libwebp.found(),
}, section: 'Optional dependencies'
)
option('docs', type: 'boolean', value: 'false')
option('workshop', type: 'boolean', value: 'false')
option('introspection', type: 'boolean', value: 'true')
# Optional features
option('docs',
type: 'boolean',
value: 'false',
description: 'build documentation'
)
option('workshop',
type: 'boolean',
value: 'false',
description: 'build experimental operations'
)
option('introspection',
type: 'combo',
choices: ['auto', 'true', 'false'],
value: 'auto',
description: 'gobject introspection .gir generation'
)
option('vapigen',
type: 'feature',
value: 'auto',
description: 'Vala .vapi generation - depends on introspection'
)
# Build settings
option('parallel-tests',
type: 'boolean',
value: 'true',
description: 'run tests in parallel or sequentially'
)
option('exiv2', type: 'feature', value: 'auto')
# optional dependencies
option('gdk-pixbuf', type: 'feature', value: 'auto')
option('gexiv2', type: 'feature', value: 'auto')
option('graphviz', type: 'feature', value: 'auto')
......@@ -10,8 +35,6 @@ option('jasper', type: 'feature', value: 'auto')
option('lcms', type: 'feature', value: 'auto')
option('lensfun', type: 'feature', value: 'auto')
option('libav', type: 'feature', value: 'auto')
option('libjpeg', type: 'feature', value: 'auto')
option('libpng', type: 'feature', value: 'auto')
option('libraw', type: 'feature', value: 'auto')
option('librsvg', type: 'feature', value: 'auto')
option('libspiro', type: 'feature', value: 'auto')
......@@ -30,5 +53,9 @@ option('pygobject', type: 'feature', value: 'auto')
option('sdl1', type: 'feature', value: 'disabled')
option('sdl2', type: 'feature', value: 'auto')
option('umfpack', type: 'feature', value: 'auto')
option('vapigen', type: 'feature', value: 'auto')
option('webp', type: 'feature', value: 'auto')
# obsolete - no effect
option('exiv2', type: 'feature', value: 'disabled')
option('libpng', type: 'feature', value: 'disabled')
option('libjpeg', type: 'feature', value: 'disabled')
......@@ -549,19 +549,17 @@ gaussian_deriv (gfloat *src_rgn,
gfloat *sum;
gfloat val;
gfloat total;
gint length;
gfloat initial_p[4], initial_m[4];
gint width = result->width, height = result->height;
gint width = result->width;
gint height = result->height;
gint length = 3;
/* allocate buffers for rows/cols */
length = MAX (result->width, result->height) * NB_CPN;
length = 3;
buf = g_new (gfloat, MAX (width, height) * NB_CPN);
/* initialize */
curve = curve_array + length;
sum = sum_array + length;
buf = g_new (gfloat, MAX (width, height) * NB_CPN);
if (direction == GEGL_ORIENTATION_VERTICAL)
{
......
......@@ -296,7 +296,7 @@ gegl_op_class_init (GeglOpClass *klass)
"reference-hash", "ae2daa632761f829c4a59225f17bf211",
"description",
_("Like a gaussian blur; but where the contribution for each neighbourhood "
"pixel is also weighted by the color difference with the original center pixel. "),
"pixel is also weighted by the color difference with the original center pixel."),
NULL);
}
......
This diff is collapsed.
......@@ -14,7 +14,7 @@
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
* Copyright 2008 Hans Petter Jansson <hpj@copyleft.no>
* 2012 Øyvind Kolås <pippin@gimp.org>
* 2012,2021 Øyvind Kolås <pippin@gimp.org>
*/
#include "config.h"
......@@ -58,6 +58,8 @@ property_seed (seed, _("Random seed"), rand)
#define REDUCE_16B(value) (((value) & ((1 << 17) - 1)) - 65536)
#include "blue-noise-data.inc"
static void
prepare (GeglOperation *operation)
{
......@@ -73,7 +75,7 @@ quantize_value (guint value,
guint n_levels)
{
float recip = 65535.0 / n_levels;
return floorf (value / recip) * recip;
return (int)(value / recip) * recip;
}
static void
......@@ -230,14 +232,16 @@ process_row_bayer (GeglBufferIterator *gi,
}
static void inline
process_row_arithmetic_add (GeglBufferIterator *gi,
guint channel_levels [4],
gint y)
process_row_blue_noise (GeglBufferIterator *gi,
guint channel_levels [4],
gint y,
gint covariant)
{
guint16 *data_in = (guint16*) gi->items[0].data;
guint16 *data_out = (guint16*) gi->items[1].data;
GeglRectangle *roi = &gi->items[0].roi;
guint x;
covariant = covariant?0:1;
for (x = 0; x < roi->width; x++)
{
guint pixel = 4 * (roi->width * y + x);
......@@ -245,49 +249,14 @@ process_row_arithmetic_add (GeglBufferIterator *gi,
for (ch = 0; ch < 4; ch++)
{
gint u = roi->x + x;
gint v = roi->y + y;
gfloat mask;
gfloat value;
gfloat value_clamped;
gfloat quantized;
mask = (((u+ch * 67) + v * 236) * 119) & 255;
mask = ((mask - 128) * 65536.0 / 256.0) / channel_levels [ch];
value = data_in [pixel + ch] + mask;
value_clamped = CLAMP (value, 0.0, 65535.0);
quantized = quantize_value ((guint) (value_clamped + 65536 * 0.5 / channel_levels[ch] ),
channel_levels [ch]);
data_out [pixel + ch] = (guint16) quantized;
}
}
}
static void inline
process_row_arithmetic_xor (GeglBufferIterator *gi,
guint channel_levels [4],
gint y)
{
guint16 *data_in = (guint16*) gi->items[0].data;
guint16 *data_out = (guint16*) gi->items[1].data;
GeglRectangle *roi = &gi->items[0].roi;
guint x;
for (x = 0; x < roi->width; x++)
{
guint pixel = 4 * (roi->width * y + x);
guint ch;
gdouble noise;
gdouble value;
gdouble value_clamped;
gdouble quantized;
for (ch = 0; ch < 4; ch++)
{
gint u = roi->x + x;
gint v = roi->y + y;
gfloat mask;
gfloat value;
gfloat value_clamped;
gfloat quantized;
mask = (((u+ch * 17) ^ v * 149) * 1234) & 511;
mask = ((mask - 257) * 65536.0 / 512.0) / channel_levels [ch];
value = data_in [pixel + ch] + mask;
noise = blue_noise_data_u8[ch * covariant][((roi->y + y) % 256) * 256 + ((roi->x + x) % 256)];
noise = 1.00 * ((noise - 128) * 65536.0 / 257.0) / channel_levels [ch];
value = data_in [pixel + ch] + noise;
value_clamped = CLAMP (value, 0.0, 65535.0);
quantized = quantize_value ((guint) (value_clamped + 65536 * 0.5 / channel_levels[ch] ),
channel_levels [ch]);
......@@ -297,15 +266,18 @@ process_row_arithmetic_xor (GeglBufferIterator *gi,
}
}
static void inline
process_row_arithmetic_add_covariant (GeglBufferIterator *gi,
guint channel_levels [4],
gint y)
process_row_arithmetic_add (GeglBufferIterator *gi,
guint channel_levels [4],
gint y,
gint covariant)
{
guint16 *data_in = (guint16*) gi->items[0].data;
guint16 *data_out = (guint16*) gi->items[1].data;
GeglRectangle *roi = &gi->items[0].roi;
guint x;
covariant = covariant?0:1;
for (x = 0; x < roi->width; x++)
{
guint pixel = 4 * (roi->width * y + x);
......@@ -319,7 +291,7 @@ process_row_arithmetic_add_covariant (GeglBufferIterator *gi,
gfloat value;
gfloat value_clamped;
gfloat quantized;
mask = ((u+ v * 236) * 119) & 255;
mask = (((u+ch * covariant * 67) + v * 236) * 119) & 255;
mask = ((mask - 128) * 65536.0 / 256.0) / channel_levels [ch];
value = data_in [pixel + ch] + mask;
value_clamped = CLAMP (value, 0.0, 65535.0);
......@@ -332,14 +304,16 @@ process_row_arithmetic_add_covariant (GeglBufferIterator *gi,
}
static void inline
process_row_arithmetic_xor_covariant (GeglBufferIterator *gi,
guint channel_levels [4],
gint y)
process_row_arithmetic_xor (GeglBufferIterator *gi,
guint channel_levels [4],
gint y,
gint covariant)
{
guint16 *data_in = (guint16*) gi->items[0].data;
guint16 *data_out = (guint16*) gi->items[1].data;
GeglRectangle *roi = &gi->items[0].roi;
guint x;
covariant = covariant?0:1;
for (x = 0; x < roi->width; x++)
{
guint pixel = 4 * (roi->width * y + x);
......@@ -353,7 +327,7 @@ process_row_arithmetic_xor_covariant (GeglBufferIterator *gi,
gfloat value;
gfloat value_clamped;
gfloat quantized;
mask = ((u ^ v * 149) * 1234) & 511;
mask = (((u+ch*covariant * 17) ^ v * 149) * 1234) & 511;
mask = ((mask - 257) * 65536.0 / 512.0) / channel_levels [ch];
value = data_in [pixel + ch] + mask;
value_clamped = CLAMP (value, 0.0, 65535.0);
......@@ -365,48 +339,18 @@ process_row_arithmetic_xor_covariant (GeglBufferIterator *gi,
}
}
static void inline
process_row_random_covariant (GeglBufferIterator *gi,
guint channel_levels [4],
gint y,
GeglRandom *rand)
{
guint16 *data_in = (guint16*) gi->items[0].data;
guint16 *data_out = (guint16*) gi->items[1].data;
GeglRectangle *roi = &gi->items[0].roi;
guint x;
for (x = 0; x < roi->width; x++)
{
guint pixel = 4 * (roi->width * y + x);
guint ch;
gint r = REDUCE_16B (gegl_random_int (rand, roi->x + x,
roi->y + y, 0, 0)) - (1<<15);
for (ch = 0; ch < 4; ch++)
{
gfloat value;
gfloat value_clamped;
gfloat quantized;
value = data_in [pixel + ch] + (r * 1.0) / channel_levels [ch];
value_clamped = CLAMP (value, 0.0, 65535.0);
quantized = quantize_value ((guint) (value_clamped + 65536 * 0.5 / channel_levels[ch] ),
channel_levels [ch]);
data_out [pixel + ch] = (guint16) quantized;
}
}
}
static void inline
process_row_random (GeglBufferIterator *gi,
guint channel_levels [4],
gint y,
GeglRandom *rand)
GeglRandom *rand,
int covariant)
{
guint16 *data_in = (guint16*) gi->items[0].data;
guint16 *data_out = (guint16*) gi->items[1].data;
GeglRectangle *roi = &gi->items[0].roi;
guint x;
covariant = covariant?0:1;
for (x = 0; x < roi->width; x++)
{
guint pixel = 4 * (roi->width * y + x);
......@@ -417,7 +361,7 @@ process_row_random (GeglBufferIterator *gi,
gdouble value_clamped;
gdouble quantized;
gint r = REDUCE_16B (gegl_random_int (rand, roi->x + x,
roi->y + y, 0, ch)) - (1<<15);
roi->y + y, 0, ch * covariant)) - (1<<15);
value = data_in [pixel + ch] + (r * 1.0) / channel_levels [ch];
value_clamped = CLAMP (value, 0.0, 65535.0);
......@@ -480,34 +424,42 @@ process_standard (GeglBuffer *input,
break;
case GEGL_DITHER_RANDOM:
for (y = 0; y < roi->height; y++)
process_row_random (gi, channel_levels, y, rand);
process_row_random (gi, channel_levels, y, rand, 0);
break;
case GEGL_DITHER_RANDOM_COVARIANT:
for (y = 0; y < roi->height; y++)
process_row_random_covariant (gi, channel_levels, y, rand);
process_row_random (gi, channel_levels, y, rand, 1);
break;
case GEGL_DITHER_BAYER:
for (y = 0; y < roi->height; y++)
process_row_bayer (gi, channel_levels, y);
break;
case GEGL_DITHER_BLUE_NOISE:
for (y = 0; y < roi->height; y++)
process_row_blue_noise (gi, channel_levels, y, 0);
break;
case GEGL_DITHER_BLUE_NOISE_COVARIANT:
for (y = 0; y < roi->height; y++)
process_row_blue_noise (gi, channel_levels, y, 1);
break;
case GEGL_DITHER_FLOYD_STEINBERG:
/* Done separately */
break;
case GEGL_DITHER_ARITHMETIC_ADD:
for (y = 0; y < roi->height; y++)
process_row_arithmetic_add (gi, channel_levels, y);
process_row_arithmetic_add (gi, channel_levels, y, 0);
break;
case GEGL_DITHER_ARITHMETIC_XOR:
for (y = 0; y < roi->height; y++)
process_row_arithmetic_xor (gi, channel_levels, y);
process_row_arithmetic_xor (gi, channel_levels, y, 0);
break;
case GEGL_DITHER_ARITHMETIC_ADD_COVARIANT:
for (y = 0; y < roi->height; y++)
process_row_arithmetic_add_covariant (gi, channel_levels, y);
process_row_arithmetic_add (gi, channel_levels, y, 1);
break;
case GEGL_DITHER_ARITHMETIC_XOR_COVARIANT:
for (y = 0; y < roi->height; y++)
process_row_arithmetic_xor_covariant (gi, channel_levels, y);
process_row_arithmetic_xor (gi, channel_levels, y, 1);
break;
default:
for (y = 0; y < roi->height; y++)
......@@ -553,10 +505,10 @@ process (GeglOperation *operation,
guint channel_levels [4];
const Babl *format = gegl_operation_get_format (operation,"output");
channel_levels [0] = o->red_levels;
channel_levels [1] = o->green_levels;
channel_levels [2] = o->blue_levels;
channel_levels [3] = o->alpha_levels;
channel_levels [0] = o->red_levels - 1;
channel_levels [1] = o->green_levels - 1;
channel_levels [2] = o->blue_levels - 1;
channel_levels [3] = o->alpha_levels - 1;
if (o->dither_method != GEGL_DITHER_FLOYD_STEINBERG)
process_standard (input, output, result, channel_levels,
......@@ -668,4 +620,5 @@ gegl_op_class_init (GeglOpClass *klass)
NULL);
}
#endif
......@@ -1117,6 +1117,11 @@ fattal02_tonemap (const gfloat *input, /* Y */
min_size /= 2;
}
if (! levels)
{
levels = 1;
}
pyramid = g_new (gfloat*, levels);
fattal02_create_gaussian_pyramids (H, extent, pyramid, levels);
}
......
......@@ -63,6 +63,7 @@ gegl_common_sources = files(
'mix.c',
'mono-mixer.c',
'motion-blur-linear.c',
'negative-darkroom.c',
'newsprint.c',
'noise-cell.c',
'noise-cie-lch.c',
......@@ -78,7 +79,7 @@ gegl_common_sources = files(
'opacity.c',
'open-buffer.c',
'over.c',
'pack.c',
'pack.c',
'panorama-projection.c',
'pixelize.c',
'posterize.c',
......
/* This file is an image processing operation for GEGL
* foo
* GEGL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* GEGL 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
*
* Copyright 2015 Red Hat, Inc.
*/
#include "config.h"
#include <glib/gi18n-lib.h>
#include <math.h>
#include <stdio.h>
#ifdef GEGL_PROPERTIES
#include "negative-darkroom/negative-darkroom-curve-enum.c"
property_enum (curve, _("Characteristic curve"),
NegCurve, neg_curve, 0)
description(_("Hardcoded characteristic curve and color data"))
property_double (exposure, _("Exposure"), -9.0)
description(_("Base enlargement exposure"))
value_range (-20, 10)
ui_range (-15, 0)
property_double (expC, _("Filter cyan"), 0.0)
description(_("Cyan exposure compensation for the negative image"))
value_range (-3, 3)
property_double (expM, _("Filter magenta"), 0.0)
description(_("Magenta exposure compensation for the negative image"))
value_range (-3, 3)
property_double (expY, _("Filter yellow"), 0.0)
description(_("Yellow exposure compensation for the negative image"))
value_range (-3, 3)
property_boolean (clip, _("Clip base + fog"), TRUE)
description (_("Clip base + fog to have a pure white output value"))
property_double (boost, _("Density boost"), 1.0)
description(_("Boost paper density to take advantage of increased dynamic range of a monitor compared to a photographic paper"))
value_range (1, 3)
property_double (dodge, _("Dodge/burn multiplier"), 1.0)
description(_("The f-stop of dodge/burn for pure white/black auxillary input"))
value_range (-4.0, 4.0)
property_boolean (preflash, _("Enable preflashing"), FALSE)
description (_("Show preflash controls"))
property_double (flashC, _("Cyan preflash"), 0)
description(_("Preflash the negative with cyan light to reduce contrast of the print"))
value_range (0, 1)
ui_meta("visible", "preflash")
property_double (flashM, _("Magenta preflash"), 0)
description(_("Preflash the negative with magenta light to reduce contrast of the print"))
value_range (0, 1)
ui_meta("visible", "preflash")
property_double (flashY, _("Yellow preflash"), 0)
description(_("Preflash the negative with yellow light to reduce contrast of the print"))
value_range (0, 1)
ui_meta("visible", "preflash")
#else
#define GEGL_OP_POINT_COMPOSER
#define GEGL_OP_NAME negative_darkroom
#define GEGL_OP_C_SOURCE negative-darkroom.c
#include "gegl-op.h"
// Color space
typedef struct cieXYZ {
gfloat X;
gfloat Y;
gfloat Z;
} cieXYZ;
// RGB Hurter–Driffield characteristic curve
typedef struct HDCurve {
gfloat *rx;
gfloat *ry;
guint rn;
gfloat *gx;
gfloat *gy;
guint gn;
gfloat *bx;
gfloat *by;
guint bn;
cieXYZ rsens;
cieXYZ gsens;
cieXYZ bsens;
cieXYZ cdens;
cieXYZ mdens;
cieXYZ ydens;
} HDCurve;
#include "negative-darkroom/negative-darkroom-curve-enum.h"
static void
prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *fXYZ;
const Babl *fRGB;
fXYZ = babl_format_with_space ("CIE XYZ float", space);
fRGB = babl_format ("R~G~B~ float");
gegl_operation_set_format (operation, "input", fXYZ);
gegl_operation_set_format (operation, "aux", fRGB);
gegl_operation_set_format (operation, "output", fXYZ);
}
static gfloat
curve_lerp (gfloat * xs, gfloat * ys, guint n, gfloat in)
{
if (in <= xs[0])
return(ys[0]);
for (guint i = 1; i <= n; i++)
{
if (in <= xs[i])
{
return(ys[i-1] + (in - xs[i-1]) * \
((ys[i] - ys[i-1]) / (xs[i] - xs[i-1])));
}
}
return(ys[n-1]);
}
static gfloat
array_min (gfloat * x, guint n)
{
gfloat min = x[0];
for (guint i = 1; i < n; i++)
{
if (x[i] < min)
min = x[i];
}
return(min);
}
static gboolean
process (GeglOperation *operation,
void *in_buf,
void *aux_buf,
void *out_buf,
glong n_pixels,
const GeglRectangle *roi,
gint level)
{
GeglProperties *o = GEGL_PROPERTIES (operation);
gfloat *in = in_buf;
gfloat *aux = aux_buf;
gfloat *out = out_buf;
gfloat Dfogc = 0;
gfloat Dfogm = 0;
gfloat Dfogy = 0;
gfloat rcomp = 0;
gfloat gcomp = 0;
gfloat bcomp = 0;
gfloat r = 0;
gfloat g = 0;
gfloat b = 0;
// Calculate base+fog
if (o->clip)
{
Dfogc = array_min(curves[o->curve].ry, curves[o->curve].rn) * o->boost;
Dfogm = array_min(curves[o->curve].gy, curves[o->curve].gn) * o->boost;
Dfogy = array_min(curves[o->curve].by, curves[o->curve].bn) * o->boost;
}
for (glong i = 0; i < n_pixels; i++)
{
/*printf("---\n");*/
/*printf("Input XYZ intensity %f %f %f\n", in[0], in[1], in[2]);*/
// Calculate exposure compensation from global+filter+dodge
if (!aux)
{
rcomp = o->exposure + o->expC;
gcomp = o->exposure + o->expM;
bcomp = o->exposure + o->expY;
}
else
{
rcomp = o->exposure + o->expC + 2*o->dodge*(aux[0]-0.5);
gcomp = o->exposure + o->expM + 2*o->dodge*(aux[1]-0.5);
bcomp = o->exposure + o->expY + 2*o->dodge*(aux[2]-0.5);
aux += 3;
}
/*printf("===\nRGB compensation %f %f %f\n", rcomp, gcomp, bcomp);*/
// Calculate RGB from XYZ using paper sensitivity
r = in[0] * curves[o->curve].rsens.X +
in[1] * curves[o->curve].gsens.X +
in[2] * curves[o->curve].bsens.X;
g = in[0] * curves[o->curve].rsens.Y +
in[1] * curves[o->curve].gsens.Y +
in[2] * curves[o->curve].bsens.Y;
b = in[0] * curves[o->curve].rsens.Z +
in[1] * curves[o->curve].gsens.Z +
in[2] * curves[o->curve].bsens.Z;
/*printf("Linear RGB intensity %f %f %f\n", r, g, b);*/
// Apply the preflash
r = r + o->flashC;
g = g + o->flashM;
b = b + o->flashY;
/*printf("Linear RGB intensity after preflash %f %f %f\n", r, g, b);*/
// Logarithmize the input and apply compensation
r = log(r / pow(2, rcomp)) / log(10);
g = log(g / pow(2, gcomp)) / log(10);
b = log(b / pow(2, bcomp)) / log(10);
/*printf("Logarithmic RGB intensity %f %f %f\n", r, g, b);*/
// Apply the DH curve
r = curve_lerp(curves[o->curve].rx,
curves[o->curve].ry,
curves[o->curve].rn,
r);
g = curve_lerp(curves[o->curve].gx,
curves[o->curve].gy,
curves[o->curve].gn,
g);
b = curve_lerp(curves[o->curve].bx,
curves[o->curve].by,
curves[o->curve].bn,
b);
// Apply density boost
r = r * o->boost;
g = g * o->boost;
b = b * o->boost;
// Compensate for fog
r -= Dfogc;
g -= Dfogm;
b -= Dfogy;
/*printf("RGB density %f %f %f\n", r, g, b);*/
// Exponentiate to get the linear representation in tramsmittance back
r = 1-1/pow(10, r);
g = 1-1/pow(10, g);
b = 1-1/pow(10, b);
/*printf("RGB absolute transparency %f %f %f\n", r, g, b);*/
// Calculate and return XYZ
out[0] = 1 - (r * curves[o->curve].cdens.X) -
(g * curves[o->curve].mdens.X) -
(b * curves[o->curve].ydens.X);
out[1] = 1 - (r * curves[o->curve].cdens.Y) -
(g * curves[o->curve].mdens.Y) -
(b * curves[o->curve].ydens.Y);
out[2] = 1 - (r * curves[o->curve].cdens.Z) -
(g * curves[o->curve].mdens.Z) -
(b * curves[o->curve].ydens.Z);
/*printf("XYZ output %f %f %f\n", out[0], out[1], out[2]);*/
in += 3;
out += 3;
}
return TRUE;
}
static void
gegl_op_class_init (GeglOpClass *klass)
{
GeglOperationClass *operation_class;
GeglOperationPointComposerClass *point_composer_class;
operation_class = GEGL_OPERATION_CLASS (klass);
point_composer_class = GEGL_OPERATION_POINT_COMPOSER_CLASS (klass);
operation_class->prepare = prepare;
operation_class->threaded = TRUE;
operation_class->opencl_support = FALSE;
point_composer_class->process = process;
gegl_operation_class_set_keys (operation_class,
"name" , "gegl:negative-darkroom",
"title", _("Negative Darkroom"),
"categories" , "color",
"description", _("Simulate a negative film enlargement in an analog darkroom."),
NULL);
}
#endif
enum_start(neg_curve)
enum_value (NEG_FUJI, "fujicrystal", N_("Fujicolor Crystal Archive Digital Pearl Paper"))
enum_value (NEG_ILFOBROM1, "ilfobrom1", N_("Ilford Ilfobrom Galerie FB 1"))
enum_value (NEG_ILFOBROM2, "ilfobrom2", N_("Ilford Ilfobrom Galerie FB 2"))
enum_value (NEG_ILFOBROM3, "ilfobrom3", N_("Ilford Ilfobrom Galerie FB 3"))
enum_value (NEG_ILFOBROM4, "ilfobrom4", N_("Ilford Ilfobrom Galerie FB 4"))
enum_end (NegCurve)
static HDCurve curves[5] = {
{
.rx = (gfloat[]){0.944085027726432, 1.0854898336414, 1.26016635859519, 1.38909426987061, 1.49722735674677, 1.59288354898336, 1.67606284658041, 1.73844731977819, 1.83410351201479, 1.94639556377079, 2.10027726432532, 2.15850277264325, 2.22088724584103, 2.28327171903882, 2.33733826247689, 2.39556377079482, 2.46210720887246, 2.55360443622921, 2.64510166358595, 2.76571164510166, 2.85720887245841, 2.95702402957486, 3.04436229205176},
.ry = (gfloat[]){0.103950103950104, 0.103950103950104, 0.116424116424116, 0.141372141372141, 0.182952182952183, 0.249480249480249, 0.328482328482329, 0.415800415800416, 0.611226611226611, 0.906444906444906, 1.38877338877339, 1.55509355509356, 1.72972972972973, 1.88357588357588, 2.02079002079002, 2.13721413721414, 2.23700623700624, 2.36590436590437, 2.45738045738046, 2.54885654885655, 2.6029106029106, 2.64449064449064, 2.66528066528067},
.rn = 23,
.gx = (gfloat[]){0.944085027726432, 1.0854898336414, 1.26016635859519, 1.38909426987061, 1.49722735674677, 1.59288354898336, 1.67606284658041, 1.73844731977819, 1.83410351201479, 1.96719038817006, 2.10027726432532, 2.18761552680222, 2.25, 2.31654343807763, 2.38724584103512, 2.47042513863216, 2.6409426987061, 2.76155268022181, 2.93207024029575, 3.04852125693161},
.gy = (gfloat[]){0.103950103950104, 0.103950103950104, 0.116424116424116, 0.141372141372141, 0.182952182952183, 0.249480249480249, 0.328482328482329, 0.415800415800416, 0.611226611226611, 0.981288981288981, 1.43451143451143, 1.74220374220374, 1.91683991683992, 2.05821205821206, 2.1954261954262, 2.2952182952183, 2.42827442827443, 2.48232848232848, 2.51975051975052, 2.53222453222453},
.gn = 20,
.bx = (gfloat[]){0.944085027726432, 1.1728280961183, 1.29343807763401, 1.4681146025878, 1.54297597042514, 1.6677449168207, 1.7634011090573, 1.83826247689464, 1.93391866913124, 2.04205175600739, 2.13770794824399, 2.20841035120148, 2.28327171903882, 2.33733826247689, 2.43715341959335, 2.49537892791128, 2.62014787430684, 2.73243992606285, 2.81977818853974, 2.91127541589649, 3.05683918669131},
.by = (gfloat[]){0.062370062370063, 0.070686070686071, 0.087318087318087, 0.128898128898129, 0.17047817047817, 0.291060291060291, 0.436590436590437, 0.602910602910603, 0.860706860706861, 1.21829521829522, 1.57172557172557, 1.8045738045738, 1.995841995842, 2.1039501039501, 2.24116424116424, 2.30769230769231, 2.39085239085239, 2.43243243243243, 2.45322245322245, 2.46569646569647, 2.47817047817048},
.bn = 21,
.rsens = {1.5489263994697402, -0.7601427199734186, -0.13159136565865906},
.gsens = {-0.6578318104480959, 1.365755119785612, 0.2388452773956612},
.bsens = {-0.31414778017785455, 0.4138731583264843, 0.8534088408788981},
.cdens = {0.5817794731231579, 0.3075301664892215, 0.007804784733728515},
.mdens = {0.25642580250752084, 0.6574414690762187, 0.04462033446059675},
.ydens = {0.1617947243693214, 0.03502836443455983, 0.9475748808056746}
},
{
.rx = (gfloat[]){1, 5},
.ry = (gfloat[]){0, 0},
.rn = 2,
.gx = (gfloat[]){1, 5},
.gy = (gfloat[]){0, 0},
.gn = 2,
.bx = (gfloat[]){1.493581907, 1.576100244, 1.661369193, 1.754889976, 1.878667482, 1.994193154, 2.159229829, 2.269254279, 2.503056235, 2.640586797, 2.758863081, 2.849633252, 2.9349022, 3.006418093, 3.099938875, 3.215464548, 3.319987775, 3.50702934},
.by = (gfloat[]){0.008241758, 0.041208791, 0.085164835, 0.151098901, 0.263736264, 0.431318681, 0.695054945, 0.865384615, 1.263736264, 1.519230769, 1.728021978, 1.876373626, 2.010989011, 2.087912088, 2.151098901, 2.195054945, 2.217032967, 2.21978022},
.bn = 18,
.rsens = {0.797668, 0.28804, 0.0},
.gsens = {0.135193, 0.711884, 0.0},
.bsens = {0.031342, 9.2e-05, 0.824905},
.cdens = {0, 0, 0},
.mdens = {0, 0, 0},
.ydens = {1, 1, 1}
},
{
.rx = (gfloat[]){1, 5},
.ry = (gfloat[]){0, 0},
.rn = 2,
.gx = (gfloat[]){1, 5},
.gy = (gfloat[]){0, 0},
.gn = 2,
.bx = (gfloat[]){1.644865526, 1.686124694, 1.752139364, 1.848410758, 1.958435208, 2.068459658, 2.186735941, 2.305012225, 2.42603912, 2.519559902, 2.588325183, 2.676344743, 2.723105134, 2.786369193, 2.830378973, 2.910146699, 3.009168704, 3.143948655, 3.325488998},
.by = (gfloat[]){0.008241758, 0.021978022, 0.057692308, 0.131868132, 0.269230769, 0.461538462, 0.736263736, 1.010989011, 1.282967033, 1.497252747, 1.64010989, 1.821428571, 1.906593407, 2.0, 2.052197802, 2.10989011, 2.151098901, 2.195054945, 2.217032967},
.bn = 19,
.rsens = {0.797668, 0.28804, 0.0},
.gsens = {0.135193, 0.711884, 0.0},
.bsens = {0.031342, 9.2e-05, 0.824905},
.cdens = {0, 0, 0},
.mdens = {0, 0, 0},
.ydens = {1, 1, 1}
},
{
.rx = (gfloat[]){1, 5},
.ry = (gfloat[]){0, 0},
.rn = 2,
.gx = (gfloat[]){1, 5},
.gy = (gfloat[]){0, 0},
.gn = 2,
.bx = (gfloat[]){1.754889976, 1.851161369, 1.936430318, 1.999694377, 2.054706601, 2.197738386, 2.329767726, 2.439792176, 2.533312958, 2.62408313, 2.670843521, 2.756112469, 2.813875306, 2.890892421, 3.006418093, 3.075183374, 3.182457213, 3.33099022},
.by = (gfloat[]){0.008241758, 0.071428571, 0.148351648, 0.233516484, 0.357142857, 0.760989011, 1.142857143, 1.442307692, 1.678571429, 1.854395604, 1.936813187, 2.027472527, 2.074175824, 2.118131868, 2.156593407, 2.178571429, 2.200549451, 2.217032967},
.bn = 18,
.rsens = {0.797668, 0.28804, 0.0},
.gsens = {0.135193, 0.711884, 0.0},
.bsens = {0.031342, 9.2e-05, 0.824905},
.cdens = {0, 0, 0},
.mdens = {0, 0, 0},
.ydens = {1, 1, 1}
},
{
.rx = (gfloat[]){1, 5},
.ry = (gfloat[]){0, 0},
.rn = 2,
.gx = (gfloat[]){1, 5},
.gy = (gfloat[]){0, 0},
.gn = 2,
.bx = (gfloat[]){1.807151589, 1.873166259, 1.908924205, 1.952933985, 1.996943765, 2.035452323, 2.090464548, 2.134474328, 2.18398533, 2.236246944, 2.277506112, 2.307762836, 2.362775061, 2.395782396, 2.42603912, 2.486552567, 2.527811736, 2.604828851, 2.676344743, 2.734107579, 2.866136919, 3.006418093, 3.165953545},
.by = (gfloat[]){0.002747253, 0.013736264, 0.043956044, 0.096153846, 0.167582418, 0.244505495, 0.414835165, 0.546703297, 0.733516484, 0.901098901, 1.071428571, 1.195054945, 1.412087912, 1.546703297, 1.656593407, 1.818681319, 1.906593407, 2.013736264, 2.085164835, 2.123626374, 2.175824176, 2.208791209, 2.222527473},
.bn = 23,
.rsens = {0.797668, 0.28804, 0.0},
.gsens = {0.135193, 0.711884, 0.0},
.bsens = {0.031342, 9.2e-05, 0.824905},
.cdens = {0, 0, 0},
.mdens = {0, 0, 0},
.ydens = {1, 1, 1}
}
};
......@@ -336,6 +336,32 @@ cl_process (GeglOperation *operation,
return TRUE;
}
/* Pass-through when radius parameter is set to zero */
static gboolean
operation_process (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result,
gint level)
{
GeglOperationClass *operation_class;
GeglProperties *o = GEGL_PROPERTIES (operation);
operation_class = GEGL_OPERATION_CLASS (gegl_op_parent_class);
if (! o->radius)
{
gpointer in = gegl_operation_context_get_object (context, "input");
gegl_operation_context_take_object (context, "output",
g_object_ref (G_OBJECT (in)));
return TRUE;
}
return operation_class->process (operation, context, output_prop, result,
gegl_operation_context_get_level (context));
}
static void
gegl_op_class_init (GeglOpClass *klass)
{
......@@ -347,6 +373,7 @@ gegl_op_class_init (GeglOpClass *klass)
filter_class->process = process;
operation_class->prepare = prepare;
operation_class->process = operation_process;
operation_class->opencl_support = TRUE;
......