[gegl] panorama-projection: merge gnomonic and stereographic ops
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] panorama-projection: merge gnomonic and stereographic ops
- Date: Sat, 3 May 2014 13:27:17 +0000 (UTC)
commit e07393d5b8bfd7fe8a93d1e209dee270060e8f46
Author: Øyvind Kolås <pippin gimp org>
Date: Sat May 3 15:26:47 2014 +0200
panorama-projection: merge gnomonic and stereographic ops
operations/common/Makefile.am | 3 +-
...gnomonic-projection.c => panorama-projection.c} | 134 +++++++++--
operations/common/stereographic-projection.c | 258 --------------------
3 files changed, 111 insertions(+), 284 deletions(-)
---
diff --git a/operations/common/Makefile.am b/operations/common/Makefile.am
index d4bc15d..b798037 100644
--- a/operations/common/Makefile.am
+++ b/operations/common/Makefile.am
@@ -45,7 +45,6 @@ op_LTLIBRARIES = \
gaussian-blur.la \
gegl-buffer-load-op.la \
gegl-buffer-save-op.la \
- gnomonic-projection.la \
grey.la \
grid.la \
high-pass.la \
@@ -84,6 +83,7 @@ op_LTLIBRARIES = \
opacity.la \
open-buffer.la \
over.la \
+ panorama-projection.la \
photocopy.la \
pixelize.la \
plasma.la \
@@ -100,7 +100,6 @@ op_LTLIBRARIES = \
shift.la \
snn-mean.la \
softglow.la \
- stereographic-projection.la \
stress.la \
stretch-contrast-hsv.la \
stretch-contrast.la \
diff --git a/operations/common/gnomonic-projection.c b/operations/common/panorama-projection.c
similarity index 65%
rename from operations/common/gnomonic-projection.c
rename to operations/common/panorama-projection.c
index 0dbebb7..8045724 100644
--- a/operations/common/gnomonic-projection.c
+++ b/operations/common/panorama-projection.c
@@ -13,7 +13,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
- * Copyright 2014 <pippin gimp org>
+ * Copyright 2014 Øyvind Kolås <pippin gimp org>
*
*/
@@ -22,13 +22,17 @@
#ifdef GEGL_CHANT_PROPERTIES
gegl_chant_double (pan, _("pan"), -180.0, 360, 0.0,
- _("pan of camera"))
+ _("camera pan"))
gegl_chant_double (tilt, _("tilt"), -180.0, 180.0, 0.0,
- _("tilt of camera"))
+ _("camera tilt"))
gegl_chant_double (spin, _("spin"), -360.0, 360.0, 0.0,
- _("spin of camera"))
+ _("rotation of camera"))
gegl_chant_double (zoom, _("zoom"), 0.01, 1000.0, 100.0,
_("zoom of camera"))
+gegl_chant_int (width, _("width"), -1, 10000, -1, _("output buffer width, -1 for same as input"))
+gegl_chant_int (height, _("height"), -1, 10000, -1, _("input buffer height, -1 for same as input"))
+
+gegl_chant_boolean (little_planet, _("little planet"), FALSE, _("use the pan/tilt location as center for a
stereographic/little planet projection."))
gegl_chant_enum (sampler_type, _("Sampler"), GeglSamplerType, gegl_sampler_type,
GEGL_SAMPLER_CUBIC, _("Image resampling method to use"))
@@ -36,12 +40,14 @@ gegl_chant_enum (sampler_type, _("Sampler"), GeglSamplerType, gegl_sampler_type,
#else
#define GEGL_CHANT_TYPE_FILTER
-#define GEGL_CHANT_C_FILE "gnomonic-projection.c"
+#define GEGL_CHANT_C_FILE "panorama-projection.c"
#include "config.h"
#include <glib/gi18n-lib.h>
#include "gegl-chant.h"
+//#include "speedmath.inc"
+
static void
prepare (GeglOperation *operation)
{
@@ -52,11 +58,41 @@ prepare (GeglOperation *operation)
}
static GeglRectangle
+get_bounding_box (GeglOperation *operation)
+{
+ GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
+ GeglRectangle result = {0,0,0,0};
+
+ if (o->width <= 0 || o->height <= 0)
+ {
+ GeglRectangle *in_rect;
+ in_rect = gegl_operation_source_get_bounding_box (operation, "input");
+ if (in_rect)
+ {
+ result = *in_rect;
+ }
+ else
+ {
+ result.width = 320;
+ result.height = 200;
+ }
+ }
+ else
+ {
+ result.width = o->width;
+ result.height = o->height;
+ }
+
+ return result;
+}
+
+static GeglRectangle
get_required_for_output (GeglOperation *operation,
const gchar *input_pad,
const GeglRectangle *region)
{
GeglRectangle result = *gegl_operation_source_get_bounding_box (operation, "input");
+ /* XXX: do inverse computations; and use their bounding box */
return result;
}
@@ -66,10 +102,10 @@ get_required_for_output (GeglOperation *operation,
*/
static void inline
-calc_long_lat (float x, float y,
- float tilt, float pan, float spin,
- float sin_tilt, float cos_tilt,
- float *in_long, float *in_lat)
+gnomonic_calc_long_lat (float x, float y,
+ float pan, float spin,
+ float sin_tilt, float cos_tilt,
+ float *in_long, float *in_lat)
{
float p, c;
float longtitude, latitude;
@@ -91,6 +127,32 @@ calc_long_lat (float x, float y,
*in_lat = ((latitude + M_PI/2) / M_PI);
}
+static void inline
+stereographic_calc_long_lat (float x, float y,
+ float pan, float spin,
+ float sin_tilt, float cos_tilt,
+ float *in_long, float *in_lat)
+{
+ float p, c;
+ float longtitude, latitude;
+ float sin_c, cos_c;
+
+ p = sqrtf (x*x+y*y);
+ c = 2 * atan2f (p / 2, 1);
+
+ sin_c = sinf (c);
+ cos_c = cosf (c);
+
+ latitude = asinf (cos_c * sin_tilt + ( y * sin_c * cos_tilt) / p);
+ longtitude = pan + atan2f ( x * sin_c, p * cos_tilt * cos_c - y * sin_tilt * sin_c);
+
+ if (longtitude < 0)
+ longtitude += M_PI * 2;
+
+ *in_long = (longtitude / (M_PI * 2));
+ *in_lat = ((latitude + M_PI/2) / M_PI);
+}
+
static gboolean
process (GeglOperation *operation,
GeglBuffer *input,
@@ -99,22 +161,27 @@ process (GeglOperation *operation,
gint level)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- float pan = o->pan / 360 * M_PI * 2;
+ float pan = o->pan / 360 * M_PI * 2;
float spin = o->spin / 360 * M_PI * 2;
float zoom = o->zoom / 100.0;
float tilt = o->tilt / 360 * M_PI * 2;
float width;
float height;
- const Babl *format_io;
- GeglSampler *sampler;
- GeglBufferIterator *it;
+ const Babl *format_io;
+ GeglSampler *sampler;
+ GeglBufferIterator *it;
float sin_tilt, cos_tilt;
float cos_spin, sin_spin;
- gint index_in, index_out;
+ gint index_in, index_out;
float xoffset = 0.5;
GeglRectangle in_rect = *gegl_operation_source_get_bounding_box (operation, "input");
GeglMatrix2 scale_matrix;
GeglMatrix2 *scale = NULL;
+ void (*calc_long_lat) (float x, float y,
+ float pan, float spin,
+ float sin_tilt, float cos_tilt,
+ float *in_long, float *in_lat) =
+ gnomonic_calc_long_lat;
format_io = babl_format ("RaGaBaA float");
sampler = gegl_buffer_sampler_new (input, format_io, o->sampler_type);
@@ -127,9 +194,26 @@ process (GeglOperation *operation,
sin_spin = sinf (spin);
cos_spin = cosf (spin);
- width = in_rect.height;
- height = width;
- xoffset = ((in_rect.width - height)/height) / 2 + 0.5;
+ width = o->width;
+ height = o->height;
+
+ if (width <= 0 || height <= 0)
+ {
+ width = in_rect.height;
+ height = width;
+ xoffset = ((in_rect.width - height)/height) / 2 + 0.5;
+ }
+ else
+ {
+ width = height;
+ xoffset = ((o->width - height)/height) / 2 + 0.5;
+ }
+
+ if (o->little_planet)
+ {
+ calc_long_lat = stereographic_calc_long_lat;
+ zoom /= 10;
+ }
if (o->sampler_type == GEGL_SAMPLER_NOHALO ||
o->sampler_type == GEGL_SAMPLER_LOHALO)
@@ -167,7 +251,7 @@ process (GeglOperation *operation,
calc_long_lat (\
xx * cos_spin - yy * sin_spin,\
yy * cos_spin + xx * sin_spin,\
- tilt, pan, spin,\
+ pan, spin,\
sin_tilt, cos_tilt,\
&rx, &ry);\
ud = rx;vd = ry;}
@@ -175,8 +259,9 @@ process (GeglOperation *operation,
gegl_unmap(u,v, cx, cy);
#undef gegl_unmap
- gegl_sampler_get (sampler, cx * in_rect.width, cy * in_rect.height,
- scale, out, GEGL_ABYSS_NONE);
+ gegl_sampler_get (sampler,
+ cx * in_rect.width, cy * in_rect.height,
+ scale, out, GEGL_ABYSS_LOOP);
in += 4;
out += 4;
@@ -201,12 +286,12 @@ process (GeglOperation *operation,
calc_long_lat (
u * cos_spin - v * sin_spin,
v * cos_spin + u * sin_spin,
- tilt, pan, spin,
+ pan, spin,
sin_tilt, cos_tilt,
&cx, &cy);
gegl_sampler_get (sampler, cx * in_rect.width, cy * in_rect.height,
- scale, out, GEGL_ABYSS_NONE);
+ scale, out, GEGL_ABYSS_LOOP);
in += 4;
out += 4;
@@ -239,12 +324,13 @@ gegl_chant_class_init (GeglChantClass *klass)
filter_class->process = process;
operation_class->prepare = prepare;
+ operation_class->get_bounding_box = get_bounding_box;
operation_class->get_required_for_output = get_required_for_output;
gegl_operation_class_set_keys (operation_class,
- "name" , "gegl:gnomonic-projection",
+ "name" , "gegl:panorama-projection",
"categories" , "misc",
- "description", _("Perform a gnomonic / equilinear projection of a equirectangular input image. (renders
virtual camera images from a panorama)"),
+ "description", _("Perform a equlinear/gnomonic or little planet/stereographic projection of a
equirectangular input image."),
NULL);
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]