Commit e8f48d7a authored by Øyvind Kolås's avatar Øyvind Kolås

moved the sample_envelopes function which is common between stress and c2g

* operations/workshop/c2g.c: (c2g):
* operations/workshop/stress.c: (stress):
* operations/workshop/envelopes.h: moved the sample_envelopes function
which is common between stress and c2g out into it's own header.

svn path=/trunk/; revision=1462
parent c51783a1
2007-05-15 Øyvind Kolås <pippin@gimp.org>
* operations/workshop/c2g.c: (c2g):
* operations/workshop/stress.c: (stress):
* operations/workshop/envelopes.h: moved the sample_envelopes function
which is common between stress and c2g out into it's own header.
2007-05-15 Øyvind Kolås <oeyvindk@hig.no>
* operations/workshop/c2g.c: color to grayscale convertor, that
......
......@@ -63,7 +63,6 @@ process (GeglOperation *operation,
filter = GEGL_OPERATION_FILTER (operation);
self = GEGL_CHANT_OPERATION (operation);
compute_luts ();
input = GEGL_BUFFER (gegl_operation_get_data (operation, context_id, "input"));
{
......@@ -119,171 +118,7 @@ process (GeglOperation *operation,
return TRUE;
}
#define ANGLE_PRIME 95273
#define RADIUS_PRIME 29537
#define SCALE_PRIME 85643
static gfloat lut_cos[ANGLE_PRIME];
static gfloat lut_sin[ANGLE_PRIME];
static gfloat radiuses[RADIUS_PRIME];
static gboolean luts_computed = FALSE;
static gint angle_no=0;
static gint radius_no=0;
static void compute_luts(void)
{
gint i;
if (luts_computed)
return;
luts_computed = TRUE;
for (i=0;i<ANGLE_PRIME;i++)
{
gfloat angle = (random() / (RAND_MAX*1.0)) * 3.141592653589793*2;
lut_cos[i] = cos(angle);
lut_sin[i] = sin(angle);
}
for (i=0;i<RADIUS_PRIME;i++)
{
radiuses[i] = (random() / (RAND_MAX*1.0));
}
}
static inline void
sample (gfloat *buf,
gint width,
gint height,
gint x,
gint y,
gfloat *dst)
{
gfloat *pixel = buf + ((width * y) + x) * 4;
gint c;
for (c=0;c<4;c++)
{
dst[c]=pixel[c];
}
}
static inline void
sample_min_max (gfloat *buf,
gfloat *center_pix,
gint width,
gint height,
gint x,
gint y,
gint radius,
gint samples,
gfloat *min,
gfloat *max)
{
gfloat best_min[3];
gfloat best_max[3];
gint i, c;
for (c=0;c<3;c++)
{
best_min[c]=center_pix[c];
best_max[c]=center_pix[c];
}
for (i=0; i<samples; i++)
{
gint u, v;
gint angle = angle_no++;
gfloat rmag = radiuses[radius_no++] * radius;
if (angle_no>=ANGLE_PRIME)
angle_no=0;
if (radius_no>=RADIUS_PRIME)
radius_no=0;
u = x + rmag * lut_cos[angle];
v = y + rmag * lut_sin[angle];
if (u>=width)
u=width-1;
if (u<0)
u=0;
if (v>=height)
v=height-1;
if (v<0)
v=0;
{
gfloat pixel[4];
sample (buf, width, height, u, v, pixel);
for (c=0;c<3;c++)
{
if (pixel[3]!=0.0 &&
pixel[c]<best_min[c])
best_min[c]=pixel[c];
if (pixel[3]!=0.0 &&
pixel[c]>best_max[c])
best_max[c]=pixel[c];
}
}
}
for (c=0;c<3;c++)
{
min[c]=best_min[c];
max[c]=best_max[c];
}
}
static gfloat colordiff (gfloat *a,
gfloat *b)
{
return sqrt(sq(a[0]-b[0])+
sq(a[1]-b[1])+
sq(a[2]-b[2]));
}
static void compute_envelopes (gfloat *buf,
gfloat *center_pixel,
gint width,
gint height,
gint x,
gint y,
gint radius,
gint samples,
gint iterations,
gfloat *min_envelope,
gfloat *max_envelope)
{
gint i;
gint c;
for (i=0;i<iterations;i++)
{
gfloat min[3];
gfloat max[3];
gfloat alpha = (i/(i+1.0));
sample_min_max (buf,
center_pixel,
width,
height,
x, y,
radius, samples,
min, max);
for (c=0;c<3;c++)
{
min_envelope[c] *= alpha;
min_envelope[c] += min[c] * (1.0-alpha);
max_envelope[c] *= alpha;
max_envelope[c] += max[c] * (1.0-alpha);
}
}
}
#include "envelopes.h"
static void c2g (GeglBuffer *src,
GeglBuffer *dst,
......@@ -296,6 +131,8 @@ static void c2g (GeglBuffer *src,
gfloat *src_buf;
gfloat *dst_buf;
compute_luts ();
src_buf = g_malloc0 (src->width * src->height * 4 * 4);
dst_buf = g_malloc0 (dst->width * dst->height * 4 * 4);
......@@ -306,8 +143,8 @@ static void c2g (GeglBuffer *src,
for (x=radius; x<dst->width-radius; x++)
{
gfloat *pixel = src_buf + offset;
gfloat min_envelope[3];
gfloat max_envelope[3];
gfloat min_envelope[4];
gfloat max_envelope[4];
compute_envelopes (src_buf,
pixel,
......@@ -324,37 +161,22 @@ static void c2g (GeglBuffer *src,
gint c;
gray = pixel[0]*0.212671 + pixel[1] * 0.715160 + pixel[2] * 0.072169;
#if 0
{
gfloat black_dist;
gfloat white_dist;
white_dist = colordiff (pixel, max_envelope);
black_dist = colordiff (pixel, min_envelope);
if (black_dist+white_dist>0.001)
{
gray *= (1.0-strength);
gray += strength * (black_dist / (black_dist + white_dist));
}
}
#endif
{
gfloat teller = 0;
gfloat nevner = 0;
for (c=0; c<3; c++)
{
gfloat delta = max_envelope[c]-min_envelope[c];
teller += (pixel[c] - min_envelope[c]) * delta;
nevner += delta*delta;
}
if (nevner>0.000) /* if we found a range, modify the result */
{
gray *= (1.0-strength);
gray += strength * (teller/nevner);
}
}
{
gfloat nominator = 0;
gfloat denominator = 0;
for (c=0; c<3; c++)
{
gfloat delta = max_envelope[c]-min_envelope[c];
nominator += (pixel[c] - min_envelope[c]) * delta;
denominator += delta*delta;
}
if (denominator>0.000) /* if we found a range, modify the result */
{
gray *= (1.0-strength);
gray += strength * (nominator/denominator);
}
}
for (c=0; c<3;c++)
dst_buf[offset+c] = gray;
......
/* 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 2 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, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* Copyright 2007 Øyvind Kolås <pippin@gimp.org>
*/
#define ANGLE_PRIME 95273
#define RADIUS_PRIME 29537
#define SCALE_PRIME 85643
static gfloat lut_cos[ANGLE_PRIME];
static gfloat lut_sin[ANGLE_PRIME];
static gfloat radiuses[RADIUS_PRIME];
static gboolean luts_computed = FALSE;
static gint angle_no=0;
static gint radius_no=0;
static void compute_luts(void)
{
gint i;
if (luts_computed)
return;
luts_computed = TRUE;
for (i=0;i<ANGLE_PRIME;i++)
{
gfloat angle = (random() / (RAND_MAX*1.0)) * 3.141592653589793*2;
lut_cos[i] = cos(angle);
lut_sin[i] = sin(angle);
}
for (i=0;i<RADIUS_PRIME;i++)
{
radiuses[i] = (random() / (RAND_MAX*1.0));
}
}
static inline void
sample (gfloat *buf,
gint width,
gint height,
gint x,
gint y,
gfloat *dst)
{
gfloat *pixel = (buf + ((width * y) + x) * 4);
gint c;
for (c=0;c<4;c++)
{
dst[c] = pixel[c];
}
}
static inline void
sample_min_max (gfloat *buf,
gfloat *center_pix,
gint width,
gint height,
gint x,
gint y,
gint radius,
gint samples,
gfloat *min,
gfloat *max)
{
gfloat best_min[3];
gfloat best_max[3];
gint i, c;
for (c=0;c<3;c++)
{
best_min[c]=center_pix[c];
best_max[c]=center_pix[c];
}
for (i=0; i<samples; i++)
{
gint u, v;
gint angle = angle_no++;
gfloat rmag = radiuses[radius_no++] * radius;
if (angle_no>=ANGLE_PRIME)
angle_no=0;
if (radius_no>=RADIUS_PRIME)
radius_no=0;
u = x + rmag * lut_cos[angle];
v = y + rmag * lut_sin[angle];
if (u>=width)
u=width-1;
if (u<0)
u=0;
if (v>=height)
v=height-1;
if (v<0)
v=0;
{
gfloat pixel[4];
sample (buf, width, height, u, v, pixel);
for (c=0;c<3;c++)
{
if (pixel[3]!=0.0 &&
pixel[c]<best_min[c])
best_min[c]=pixel[c];
if (pixel[3]!=0.0 &&
pixel[c]>best_max[c])
best_max[c]=pixel[c];
}
}
}
for (c=0;c<3;c++)
{
min[c]=best_min[c];
max[c]=best_max[c];
}
}
static void compute_envelopes (gfloat *buf,
gfloat *center_pixel,
gint width,
gint height,
gint x,
gint y,
gint radius,
gint samples,
gint iterations,
gfloat *min_envelope,
gfloat *max_envelope)
{
gint i;
gint c;
for (i=0;i<iterations;i++)
{
gfloat min[3];
gfloat max[3];
gfloat alpha = (i/(i+1.0));
sample_min_max (buf,
center_pixel,
width,
height,
x, y,
radius, samples,
min, max);
for (c=0;c<3;c++)
{
min_envelope[c] *= alpha;
min_envelope[c] += min[c] * (1.0-alpha);
max_envelope[c] *= alpha;
max_envelope[c] += max[c] * (1.0-alpha);
}
}
}
......@@ -117,122 +117,7 @@ process (GeglOperation *operation,
return TRUE;
}
#define ANGLE_PRIME 95273
#define RADIUS_PRIME 29537
#define SCALE_PRIME 85643
static gfloat lut_cos[ANGLE_PRIME];
static gfloat lut_sin[ANGLE_PRIME];
static gfloat radiuses[RADIUS_PRIME];
static gboolean luts_computed = FALSE;
static gint angle_no=0;
static gint radius_no=0;
static void compute_luts(void)
{
gint i;
if (luts_computed)
return;
luts_computed = TRUE;
for (i=0;i<ANGLE_PRIME;i++)
{
gfloat angle = (random() / (RAND_MAX*1.0)) * 3.141592653589793*2;
lut_cos[i] = cos(angle);
lut_sin[i] = sin(angle);
}
for (i=0;i<RADIUS_PRIME;i++)
{
radiuses[i] = (random() / (RAND_MAX*1.0));
}
}
static inline void
sample (gfloat *buf,
gint width,
gint height,
gint x,
gint y,
gfloat *dst)
{
gfloat *pixel = buf + ((width * y) + x) * 4;
gint c;
for (c=0;c<4;c++)
{
dst[c]=pixel[c];
}
}
static inline void
sample_min_max (gfloat *buf,
gfloat *center_pix,
gint width,
gint height,
gint x,
gint y,
gint radius,
gint samples,
gfloat *min,
gfloat *max)
{
gfloat best_min[3];
gfloat best_max[3];
gint i, c;
for (c=0;c<3;c++)
{
best_min[c]=center_pix[c];
best_max[c]=center_pix[c];
}
for (i=0; i<samples; i++)
{
gint u, v;
gint angle = angle_no++;
gfloat rmag = radiuses[radius_no++] * radius;
if (angle_no>=ANGLE_PRIME)
angle_no=0;
if (radius_no>=RADIUS_PRIME)
radius_no=0;
u = x + rmag * lut_cos[angle];
v = y + rmag * lut_sin[angle];
if (u>=width)
u=width-1;
if (u<0)
u=0;
if (v>=height)
v=height-1;
if (v<0)
v=0;
{
gfloat pixel[4];
sample (buf, width, height, u, v, pixel);
for (c=0;c<3;c++)
{
if (pixel[3]!=0.0 &&
pixel[c]<best_min[c])
best_min[c]=pixel[c];
if (pixel[3]!=0.0 &&
pixel[c]>best_max[c])
best_max[c]=pixel[c];
}
}
}
for (c=0;c<3;c++)
{
min[c]=best_min[c];
max[c]=best_max[c];
}
}
#include "envelopes.h"
static void stress (GeglBuffer *src,
GeglBuffer *dst,
......@@ -254,42 +139,31 @@ static void stress (GeglBuffer *src,
gint offset = ((src->width*y)+radius)*4;
for (x=radius; x<dst->width-radius; x++)
{
gfloat amin[3]={0.0,0.0,0.0}, amax[3]={0.0,0.0,0.0};
gint i;
gfloat *center_pix = src_buf + offset;
gfloat *center_pix= src_buf + offset;
gfloat min_envelope[4];
gfloat max_envelope[4];
compute_envelopes (src_buf,
center_pix,
src->width,
src->height,
x, y,
radius, samples,
iterations,
min_envelope, max_envelope);
for (i=0;i<3;i++)
{
amin[i]=center_pix[i];
amax[i]=center_pix[i];
}
for (i=0;i<iterations;i++)
{
gint c;
gfloat min[3], max[3];
sample_min_max (src_buf, center_pix, src->width, src->height, x, y, radius, samples, min, max);
for (c=0;c<3;c++)
{
#define alpha 0.01
amin[c] = amin[c] * (1.0-alpha) + min[c] * alpha;
amax[c] = amax[c] * (1.0-alpha) + max[c] * alpha;
}
}
{
gint c;
gfloat pixel[3];
for (c=0;c<3;c++)
{
pixel[c] = center_pix[c];
/*amin[c] /= iterations;
amax[c] /= iterations;*/
if (amin[c]!=amax[c])
pixel[c] = (pixel[c]-(amin[c]))/(amax[c]-amin[c]);
if (min_envelope[c]!=max_envelope[c])
pixel[c] = (pixel[c]-(min_envelope[c]))/(max_envelope[c]-min_envelope[c]);
}
for (i=0; i<3;i++)
dst_buf[offset+i] = pixel[i];
dst_buf[offset+i] = center_pix[i];
for (c=0; c<3;c++)
dst_buf[offset+c] = pixel[c];
dst_buf[offset+c] = center_pix[c];
}
offset+=4;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment