Initial checkin of Pika from heckimp
This commit is contained in:
64
plug-ins/flame/README
Normal file
64
plug-ins/flame/README
Normal file
@ -0,0 +1,64 @@
|
||||
flame - cosmic recursive fractal flames
|
||||
Scott Draves <spot@cs.cmu.edu>
|
||||
|
||||
get source code from
|
||||
http://www.cs.cmu.edu/~spot/pika/flame.tar.gz
|
||||
|
||||
images, documentation, and other interfaces (a batch animation
|
||||
renderer and a low-quality interactive editor) are available from
|
||||
http://www.cs.cmu.edu/~spot/flame.html
|
||||
|
||||
-----------------------
|
||||
|
||||
you are encouraged to exhibit the output of this software publicly as
|
||||
long as this software is credited as the source of the images.
|
||||
|
||||
i also encourage you to let me know what you make with it, what you
|
||||
dis/like about it, and how it can be improved.
|
||||
|
||||
-----------------------
|
||||
|
||||
0.12 as of Thu Oct 9
|
||||
added variation_same. made preview have same aspect ratio as final
|
||||
image. included binary in tar file.
|
||||
|
||||
0.11 as of Sun Sep 28
|
||||
patch from Owen Taylor <owt1@cornell.edu> gtk_signal_connect_object ->
|
||||
gtk_signal_connect. hacked mw routines so i can update my previews.
|
||||
removed much of mw code that i don't use.
|
||||
|
||||
0.10 as of Fri Sep 26
|
||||
Added "eight directions" edit window. relayedout other widgets.
|
||||
|
||||
0.9 as of Tue Sep 23
|
||||
reconfigured to use Makefile.am. cleaned warnings out of code.
|
||||
|
||||
0.8 as of Thu Sep 18
|
||||
added Makefile.in.patch, made pika integration easier. changed
|
||||
license. added some built-in cmaps to the menu.
|
||||
|
||||
0.7 as of Sun Sep 14
|
||||
fixed image leak (thx Marcelo Malheiros). removed UI to black cmap
|
||||
(default is now gradient). added preview of the flame, disabled
|
||||
randomize mode in favor of a randomize button. added beginning of
|
||||
edit dialog, including multi-threaded computation of previews, but
|
||||
disabled for the release.
|
||||
|
||||
0.6 as of Thu Sep 11
|
||||
added preview of cmap. added black cmap. added access to current
|
||||
gradient, but there is an image leak.
|
||||
|
||||
0.5 as of Sat Sep 6
|
||||
cmaps now come from image menus. clarified license terms.
|
||||
|
||||
0.4 as of Thu Sep 4
|
||||
added variation menu. removed text display, added load/store buttons.
|
||||
fixed alpha blend to be stable (alpha of 0 has no effect) and protect
|
||||
against overflow.
|
||||
|
||||
0.3 as of Tue Sep 2
|
||||
added alpha channel
|
||||
|
||||
0.2 as of Aug 24 1997
|
||||
real -> double, other header file reorganization. added new cmaps.
|
||||
added pika interface.
|
5776
plug-ins/flame/cmap.c
Normal file
5776
plug-ins/flame/cmap.c
Normal file
File diff suppressed because it is too large
Load Diff
35
plug-ins/flame/cmap.h
Normal file
35
plug-ins/flame/cmap.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
flame - cosmic recursive fractal flames
|
||||
Copyright (C) 1992 Scott Draves <spot@cs.cmu.edu>
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef cmap_included
|
||||
#define cmap_included
|
||||
|
||||
#define cmap_random (-1)
|
||||
|
||||
|
||||
|
||||
#define vlen(x) (sizeof(x)/sizeof(*x))
|
||||
|
||||
typedef double clrmap[256][3];
|
||||
|
||||
extern void rgb2hsv(double *rgb, double *hsv);
|
||||
extern void hsv2rgb(double *hsv, double *rgb);
|
||||
extern int get_cmap(int n, clrmap c, int cmap_len);
|
||||
|
||||
#endif
|
1343
plug-ins/flame/flame.c
Normal file
1343
plug-ins/flame/flame.c
Normal file
File diff suppressed because it is too large
Load Diff
21
plug-ins/flame/flame.h
Normal file
21
plug-ins/flame/flame.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
flame - cosmic recursive fractal flames
|
||||
Copyright (C) 1992 Scott Draves <spot@cs.cmu.edu>
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "libifs.h"
|
||||
#include "rect.h"
|
||||
#include "cmap.h"
|
1487
plug-ins/flame/libifs.c
Normal file
1487
plug-ins/flame/libifs.c
Normal file
File diff suppressed because it is too large
Load Diff
87
plug-ins/flame/libifs.h
Normal file
87
plug-ins/flame/libifs.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
flame - cosmic recursive fractal flames
|
||||
Copyright (C) 1992 Scott Draves <spot@cs.cmu.edu>
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef libifs_included
|
||||
#define libifs_included
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "cmap.h"
|
||||
|
||||
#define EPS (1e-10)
|
||||
|
||||
#define variation_random (-1)
|
||||
|
||||
#define NVARS 29
|
||||
#define NXFORMS 6
|
||||
|
||||
typedef double point[3];
|
||||
|
||||
typedef struct {
|
||||
double var[NVARS]; /* normalized interp coefs between variations */
|
||||
double c[3][2]; /* the coefs to the affine part of the function */
|
||||
double density; /* prob is this function is chosen. 0 - 1 */
|
||||
double color; /* color coord for this function. 0 - 1 */
|
||||
} xform;
|
||||
|
||||
typedef struct {
|
||||
xform xform[NXFORMS];
|
||||
clrmap cmap;
|
||||
double time;
|
||||
int cmap_index;
|
||||
double brightness; /* 1.0 = normal */
|
||||
double contrast; /* 1.0 = normal */
|
||||
double gamma;
|
||||
int width, height; /* of the final image */
|
||||
int spatial_oversample;
|
||||
double center[2]; /* camera center */
|
||||
double zoom; /* effects ppu and sample density */
|
||||
double pixels_per_unit; /* and scale */
|
||||
double spatial_filter_radius; /* variance of gaussian */
|
||||
double sample_density; /* samples per pixel (not bucket) */
|
||||
/* in order to motion blur more accurately we compute the logs of the
|
||||
sample density many times and average the results. we interpolate
|
||||
only this many times. */
|
||||
int nbatches;
|
||||
/* this much color resolution. but making it too high induces clipping */
|
||||
int white_level;
|
||||
int cmap_inter; /* if this is true, then color map interpolates one entry
|
||||
at a time with a bright edge */
|
||||
double pulse[2][2]; /* [i][0]=magnitude [i][1]=frequency */
|
||||
double wiggle[2][2]; /* frequency is /minute, assuming 30 frames/s */
|
||||
} control_point;
|
||||
|
||||
|
||||
|
||||
extern void iterate(control_point *cp, int n, int fuse, point points[]);
|
||||
extern void interpolate(control_point cps[], int ncps, double time, control_point *result);
|
||||
extern void tokenize(char **ss, char *argv[], int *argc);
|
||||
extern void print_control_point(FILE *f, control_point *cp, int quote);
|
||||
extern void random_control_point(control_point *cp, int ivar);
|
||||
extern void parse_control_point(char **ss, control_point *cp);
|
||||
extern void estimate_bounding_box(control_point *cp, double eps, double *bmin, double *bmax);
|
||||
extern double standard_metric(control_point *cp1, control_point *cp2);
|
||||
extern double random_uniform01(void);
|
||||
extern double random_uniform11(void);
|
||||
extern double random_gaussian(void);
|
||||
extern void mult_matrix(double s1[2][2], double s2[2][2], double d[2][2]);
|
||||
void copy_variation(control_point *cp0, control_point *cp1);
|
||||
#endif
|
32
plug-ins/flame/meson.build
Normal file
32
plug-ins/flame/meson.build
Normal file
@ -0,0 +1,32 @@
|
||||
plugin_name = 'flame'
|
||||
|
||||
plugin_sources = [
|
||||
'cmap.c',
|
||||
'flame.c',
|
||||
'libifs.c',
|
||||
'rect.c',
|
||||
]
|
||||
|
||||
if platform_windows
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
'--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
'--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
'--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
executable(plugin_name,
|
||||
plugin_sources,
|
||||
dependencies: [
|
||||
libpikaui_dep,
|
||||
math,
|
||||
],
|
||||
install: true,
|
||||
install_dir: pikaplugindir / 'plug-ins' / plugin_name,
|
||||
)
|
398
plug-ins/flame/rect.c
Normal file
398
plug-ins/flame/rect.c
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
flame - cosmic recursive fractal flames
|
||||
Copyright (C) 1992 Scott Draves <spot@cs.cmu.edu>
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "rect.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libpika/pika.h"
|
||||
|
||||
/* for batch
|
||||
* interpolate
|
||||
* compute colormap
|
||||
* for subbatch
|
||||
* compute samples
|
||||
* buckets += cmap[samples]
|
||||
* accum += time_filter[batch] * log(buckets)
|
||||
* image = filter(accum)
|
||||
*/
|
||||
|
||||
|
||||
typedef short bucket[4];
|
||||
|
||||
/* if you use longs instead of shorts, you
|
||||
get higher quality, and spend more memory */
|
||||
|
||||
#if 1
|
||||
typedef short accum_t;
|
||||
#define MAXBUCKET (1<<14)
|
||||
#define SUB_BATCH_SIZE 10000
|
||||
#else
|
||||
typedef long accum_t;
|
||||
#define MAXBUCKET (1<<30)
|
||||
#define SUB_BATCH_SIZE 10000
|
||||
#endif
|
||||
|
||||
typedef accum_t abucket[4];
|
||||
|
||||
|
||||
|
||||
/* allow this many iterations for settling into attractor */
|
||||
#define FUSE 15
|
||||
|
||||
/* clamp spatial filter to zero at this std dev (2.5 ~= 0.0125) */
|
||||
#define FILTER_CUTOFF 2.5
|
||||
|
||||
/* should be MAXBUCKET / (OVERSAMPLE^2) */
|
||||
#define PREFILTER_WHITE (MAXBUCKET>>4)
|
||||
|
||||
|
||||
#define bump_no_overflow(dest, delta, type) { \
|
||||
type tt_ = dest + delta; \
|
||||
if (tt_ > dest) dest = tt_; \
|
||||
}
|
||||
|
||||
/* sum of entries of vector to 1 */
|
||||
static void
|
||||
normalize_vector(double *v,
|
||||
int n)
|
||||
{
|
||||
double t = 0.0;
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
t += v[i];
|
||||
t = 1.0 / t;
|
||||
for (i = 0; i < n; i++)
|
||||
v[i] *= t;
|
||||
}
|
||||
|
||||
void
|
||||
render_rectangle (frame_spec *spec,
|
||||
unsigned char *out,
|
||||
int out_width,
|
||||
int field,
|
||||
int nchan,
|
||||
int progress(double))
|
||||
{
|
||||
int i, j, k, nsamples, nbuckets, batch_size, batch_num, sub_batch;
|
||||
bucket *buckets;
|
||||
abucket *accumulate;
|
||||
point *points;
|
||||
double *filter, *temporal_filter, *temporal_deltas;
|
||||
double bounds[4], size[2], ppux, ppuy;
|
||||
int image_width, image_height; /* size of the image to produce */
|
||||
int width, height; /* size of histogram */
|
||||
int filter_width;
|
||||
int oversample = spec->cps[0].spatial_oversample;
|
||||
int nbatches = spec->cps[0].nbatches;
|
||||
bucket cmap[CMAP_SIZE];
|
||||
int gutter_width;
|
||||
int sbc;
|
||||
|
||||
image_width = spec->cps[0].width;
|
||||
if (field)
|
||||
{
|
||||
image_height = spec->cps[0].height / 2;
|
||||
if (field == field_odd)
|
||||
out += nchan * out_width;
|
||||
out_width *= 2;
|
||||
}
|
||||
else
|
||||
image_height = spec->cps[0].height;
|
||||
|
||||
if (1)
|
||||
{
|
||||
filter_width = (2.0 * FILTER_CUTOFF * oversample *
|
||||
spec->cps[0].spatial_filter_radius);
|
||||
/* make sure it has same parity as oversample */
|
||||
if ((filter_width ^ oversample) & 1)
|
||||
filter_width++;
|
||||
|
||||
filter = g_malloc (sizeof (double) * filter_width * filter_width);
|
||||
/* fill in the coefs */
|
||||
for (i = 0; i < filter_width; i++)
|
||||
for (j = 0; j < filter_width; j++)
|
||||
{
|
||||
double ii = ((2.0 * i + 1.0) / filter_width - 1.0) * FILTER_CUTOFF;
|
||||
double jj = ((2.0 * j + 1.0) / filter_width - 1.0) * FILTER_CUTOFF;
|
||||
if (field)
|
||||
jj *= 2.0;
|
||||
filter[i + j * filter_width] = exp(-2.0 * (ii * ii + jj * jj));
|
||||
}
|
||||
normalize_vector(filter, filter_width * filter_width);
|
||||
}
|
||||
temporal_filter = g_malloc (sizeof (double) * nbatches);
|
||||
temporal_deltas = g_malloc (sizeof (double) * nbatches);
|
||||
if (nbatches > 1)
|
||||
{
|
||||
double t;
|
||||
/* fill in the coefs */
|
||||
for (i = 0; i < nbatches; i++)
|
||||
{
|
||||
t = temporal_deltas[i] = (2.0 * ((double) i / (nbatches - 1)) - 1.0)
|
||||
* spec->temporal_filter_radius;
|
||||
temporal_filter[i] = exp(-2.0 * t * t);
|
||||
}
|
||||
normalize_vector(temporal_filter, nbatches);
|
||||
}
|
||||
else
|
||||
{
|
||||
temporal_filter[0] = 1.0;
|
||||
temporal_deltas[0] = 0.0;
|
||||
}
|
||||
|
||||
/* the number of additional rows of buckets we put at the edge so
|
||||
that the filter doesn't go off the edge */
|
||||
gutter_width = (filter_width - oversample) / 2;
|
||||
height = oversample * image_height + 2 * gutter_width;
|
||||
width = oversample * image_width + 2 * gutter_width;
|
||||
|
||||
nbuckets = width * height;
|
||||
if (1)
|
||||
{
|
||||
static char *last_block = NULL;
|
||||
static int last_block_size = 0;
|
||||
int memory_rqd = (sizeof (bucket) * nbuckets +
|
||||
sizeof (abucket) * nbuckets +
|
||||
sizeof (point) * SUB_BATCH_SIZE);
|
||||
if (memory_rqd > last_block_size)
|
||||
{
|
||||
if (last_block != NULL)
|
||||
free (last_block);
|
||||
last_block = g_try_malloc (memory_rqd);
|
||||
if (last_block == NULL)
|
||||
{
|
||||
g_printerr ("render_rectangle: cannot malloc %d bytes.\n",
|
||||
memory_rqd);
|
||||
exit (1);
|
||||
}
|
||||
last_block_size = memory_rqd;
|
||||
}
|
||||
buckets = (bucket *) last_block;
|
||||
accumulate = (abucket *) (last_block + sizeof (bucket) * nbuckets);
|
||||
points = (point *) (last_block + (sizeof (bucket) + sizeof (abucket)) * nbuckets);
|
||||
}
|
||||
|
||||
memset ((char *) accumulate, 0, sizeof (abucket) * nbuckets);
|
||||
for (batch_num = 0; batch_num < nbatches; batch_num++)
|
||||
{
|
||||
double batch_time;
|
||||
double sample_density;
|
||||
control_point cp;
|
||||
memset ((char *) buckets, 0, sizeof (bucket) * nbuckets);
|
||||
batch_time = spec->time + temporal_deltas[batch_num];
|
||||
|
||||
/* interpolate and get a control point */
|
||||
interpolate (spec->cps, spec->ncps, batch_time, &cp);
|
||||
|
||||
/* compute the colormap entries. the input colormap is 256 long with
|
||||
entries from 0 to 1.0 */
|
||||
for (j = 0; j < CMAP_SIZE; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
#if 1
|
||||
cmap[j][k] = (int) (cp.cmap[(j * 256) / CMAP_SIZE][k] *
|
||||
cp.white_level);
|
||||
#else
|
||||
/* monochrome if you don't have any cmaps */
|
||||
cmap[j][k] = cp.white_level;
|
||||
#endif
|
||||
}
|
||||
cmap[j][3] = cp.white_level;
|
||||
}
|
||||
/* compute camera */
|
||||
if (1)
|
||||
{
|
||||
double t0, t1, shift = 0.0, corner0, corner1;
|
||||
double scale;
|
||||
|
||||
scale = pow (2.0, cp.zoom);
|
||||
sample_density = cp.sample_density * scale * scale;
|
||||
|
||||
ppux = cp.pixels_per_unit * scale;
|
||||
ppuy = field ? (ppux / 2.0) : ppux;
|
||||
switch (field)
|
||||
{
|
||||
case field_both:
|
||||
shift = 0.0;
|
||||
break;
|
||||
case field_even:
|
||||
shift = -0.5;
|
||||
break;
|
||||
case field_odd:
|
||||
shift = 0.5;
|
||||
break;
|
||||
}
|
||||
shift = shift / ppux;
|
||||
t0 = (double) gutter_width / (oversample * ppux);
|
||||
t1 = (double) gutter_width / (oversample * ppuy);
|
||||
corner0 = cp.center[0] - image_width / ppux / 2.0;
|
||||
corner1 = cp.center[1] - image_height / ppuy / 2.0;
|
||||
bounds[0] = corner0 - t0;
|
||||
bounds[1] = corner1 - t1 + shift;
|
||||
bounds[2] = corner0 + image_width / ppux + t0;
|
||||
bounds[3] = corner1 + image_height / ppuy + t1 + shift;
|
||||
size[0] = 1.0 / (bounds[2] - bounds[0]);
|
||||
size[1] = 1.0 / (bounds[3] - bounds[1]);
|
||||
}
|
||||
nsamples = (int) (sample_density * nbuckets /
|
||||
(oversample * oversample));
|
||||
batch_size = nsamples / cp.nbatches;
|
||||
|
||||
sbc = 0;
|
||||
for (sub_batch = 0;
|
||||
sub_batch < batch_size;
|
||||
sub_batch += SUB_BATCH_SIZE)
|
||||
{
|
||||
if (progress && (sbc++ % 32) == 0)
|
||||
(*progress)(0.5 * sub_batch / (double) batch_size);
|
||||
/* generate a sub_batch_size worth of samples */
|
||||
points[0][0] = random_uniform11 ();
|
||||
points[0][1] = random_uniform11 ();
|
||||
points[0][2] = random_uniform01 ();
|
||||
iterate (&cp, SUB_BATCH_SIZE, FUSE, points);
|
||||
|
||||
/* merge them into buckets, looking up colors */
|
||||
for (j = 0; j < SUB_BATCH_SIZE; j++)
|
||||
{
|
||||
int k, color_index;
|
||||
double *p = points[j];
|
||||
bucket *b;
|
||||
|
||||
/* Note that we must test if p[0] and p[1] is "within"
|
||||
* the valid bounds rather than "not outside", because
|
||||
* p[0] and p[1] might be NaN.
|
||||
*/
|
||||
if (p[0] >= bounds[0] &&
|
||||
p[1] >= bounds[1] &&
|
||||
p[0] <= bounds[2] &&
|
||||
p[1] <= bounds[3])
|
||||
{
|
||||
color_index = (int) (p[2] * CMAP_SIZE);
|
||||
|
||||
if (color_index < 0)
|
||||
color_index = 0;
|
||||
else if (color_index > CMAP_SIZE - 1)
|
||||
color_index = CMAP_SIZE - 1;
|
||||
|
||||
b = buckets +
|
||||
(int) (width * (p[0] - bounds[0]) * size[0]) +
|
||||
width * (int) (height * (p[1] - bounds[1]) * size[1]);
|
||||
|
||||
for (k = 0; k < 4; k++)
|
||||
bump_no_overflow(b[0][k], cmap[color_index][k], short);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
double k1 = (cp.contrast * cp.brightness *
|
||||
PREFILTER_WHITE * 268.0 *
|
||||
temporal_filter[batch_num]) / 256;
|
||||
double area = image_width * image_height / (ppux * ppuy);
|
||||
double k2 = (oversample * oversample * nbatches) /
|
||||
(cp.contrast * area * cp.white_level * sample_density);
|
||||
|
||||
/* log intensity in hsv space */
|
||||
for (j = 0; j < height; j++)
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
abucket *a = accumulate + i + j * width;
|
||||
bucket *b = buckets + i + j * width;
|
||||
double c[4], ls;
|
||||
c[0] = (double) b[0][0];
|
||||
c[1] = (double) b[0][1];
|
||||
c[2] = (double) b[0][2];
|
||||
c[3] = (double) b[0][3];
|
||||
if (0.0 == c[3])
|
||||
continue;
|
||||
|
||||
ls = (k1 * log(1.0 + c[3] * k2))/c[3];
|
||||
c[0] *= ls;
|
||||
c[1] *= ls;
|
||||
c[2] *= ls;
|
||||
c[3] *= ls;
|
||||
|
||||
bump_no_overflow(a[0][0], c[0] + 0.5, accum_t);
|
||||
bump_no_overflow(a[0][1], c[1] + 0.5, accum_t);
|
||||
bump_no_overflow(a[0][2], c[2] + 0.5, accum_t);
|
||||
bump_no_overflow(a[0][3], c[3] + 0.5, accum_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* filter the accumulation buffer down into the image
|
||||
*/
|
||||
if (1)
|
||||
{
|
||||
int x, y;
|
||||
double t[4];
|
||||
double g = 1.0 / spec->cps[0].gamma;
|
||||
y = 0;
|
||||
for (j = 0; j < image_height; j++)
|
||||
{
|
||||
if (progress && (j % 32) == 0)
|
||||
(*progress)(0.5 + 0.5 * j / (double)image_height);
|
||||
x = 0;
|
||||
for (i = 0; i < image_width; i++)
|
||||
{
|
||||
int ii, jj, a;
|
||||
unsigned char *p;
|
||||
t[0] = t[1] = t[2] = t[3] = 0.0;
|
||||
for (ii = 0; ii < filter_width; ii++)
|
||||
for (jj = 0; jj < filter_width; jj++)
|
||||
{
|
||||
double k = filter[ii + jj * filter_width];
|
||||
abucket *a = accumulate + x + ii + (y + jj) * width;
|
||||
|
||||
t[0] += k * a[0][0];
|
||||
t[1] += k * a[0][1];
|
||||
t[2] += k * a[0][2];
|
||||
t[3] += k * a[0][3];
|
||||
}
|
||||
/* FIXME: we should probably use glib facilities to make
|
||||
* this code readable
|
||||
*/
|
||||
p = out + nchan * (i + j * out_width);
|
||||
a = 256.0 * pow((double) t[0] / PREFILTER_WHITE, g) + 0.5;
|
||||
if (a < 0) a = 0; else if (a > 255) a = 255;
|
||||
p[0] = a;
|
||||
a = 256.0 * pow((double) t[1] / PREFILTER_WHITE, g) + 0.5;
|
||||
if (a < 0) a = 0; else if (a > 255) a = 255;
|
||||
p[1] = a;
|
||||
a = 256.0 * pow((double) t[2] / PREFILTER_WHITE, g) + 0.5;
|
||||
if (a < 0) a = 0; else if (a > 255) a = 255;
|
||||
p[2] = a;
|
||||
if (nchan > 3)
|
||||
{
|
||||
a = 256.0 * pow((double) t[3] / PREFILTER_WHITE, g) + 0.5;
|
||||
if (a < 0) a = 0; else if (a > 255) a = 255;
|
||||
p[3] = a;
|
||||
}
|
||||
x += oversample;
|
||||
}
|
||||
y += oversample;
|
||||
}
|
||||
}
|
||||
|
||||
free (filter);
|
||||
free (temporal_filter);
|
||||
free (temporal_deltas);
|
||||
}
|
41
plug-ins/flame/rect.h
Normal file
41
plug-ins/flame/rect.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
flame - cosmic recursive fractal flames
|
||||
Copyright (C) 1992 Scott Draves <spot@cs.cmu.edu>
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "libifs.h"
|
||||
|
||||
|
||||
/* size of the cmap actually used. may be smaller than input cmap size */
|
||||
#define CMAP_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
double temporal_filter_radius;
|
||||
control_point *cps;
|
||||
int ncps;
|
||||
double time;
|
||||
} frame_spec;
|
||||
|
||||
|
||||
#define field_both 0
|
||||
#define field_even 1
|
||||
#define field_odd 2
|
||||
|
||||
|
||||
extern void render_rectangle(frame_spec *spec, unsigned char *out,
|
||||
int out_width, int field, int nchan,
|
||||
int progress(double));
|
||||
|
Reference in New Issue
Block a user