summaryrefslogtreecommitdiffstats
path: root/debian/fireflies/fireflies-2.08/libgfx/src
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2020-09-11 14:38:47 +0900
committerMichele Calgaro <[email protected]>2020-09-11 14:38:47 +0900
commit884c8093d63402a1ad0b502244b791e3c6782be3 (patch)
treea600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/fireflies/fireflies-2.08/libgfx/src
parent14e1aa2006796f147f3f4811fb908a6b01e79253 (diff)
downloadextra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz
extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'debian/fireflies/fireflies-2.08/libgfx/src')
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/Makefile29
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/arcball.cxx192
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/baseball.cxx59
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/color.cxx128
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/geom3d.cxx33
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/geom4d.cxx14
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/gltools.cxx192
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/gui-mfc.cxx297
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/gui.cxx509
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/mat2.cxx89
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/mat3.cxx82
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/mat4.cxx206
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/quat.cxx136
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/raster-jpeg.cxx113
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/raster-png.cxx180
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/raster-pnm.cxx174
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/raster-tiff.cxx158
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/raster.cxx113
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/script.cxx295
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/symmat2.cxx61
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/symmat3.cxx61
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/symmat4.cxx52
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/time.cxx86
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/trackball.cxx153
-rw-r--r--debian/fireflies/fireflies-2.08/libgfx/src/wintools.cxx88
25 files changed, 3500 insertions, 0 deletions
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/Makefile b/debian/fireflies/fireflies-2.08/libgfx/src/Makefile
new file mode 100644
index 00000000..7993f971
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/Makefile
@@ -0,0 +1,29 @@
+include ../gfx-config
+
+CXXFLAGS += -DGFX_NAMESPACE
+
+VEC_SRCS = mat2.cxx mat3.cxx mat4.cxx quat.cxx \
+ symmat2.cxx symmat3.cxx symmat4.cxx
+GEO_SRCS = geom3d.cxx
+IMG_SRCS = raster.cxx raster-pnm.cxx raster-tiff.cxx raster-jpeg.cxx \
+ raster-png.cxx
+MISC_SRCS = time.cxx script.cxx color.cxx
+GUI_SRCS = gui.cxx gltools.cxx baseball.cxx trackball.cxx arcball.cxx
+
+SRCS = $(VEC_SRCS) $(GEO_SRCS) $(IMG_SRCS) $(MISC_SRCS) $(GUI_SRCS)
+OBJS = $(SRCS:.cxx=.o)
+
+libgfx.a: $(OBJS)
+ $(AR) cru libgfx.a $(OBJS)
+ $(RANLIB) libgfx.a
+
+tags: $(SRCS) ../include/gfx/*.h
+ ctags $(SRCS) ../include/gfx/*.h
+
+clean:
+ -$(RM) $(OBJS) libgfx.a
+
+depend:
+ $(CXX_DEPEND) $(SRCS) > Makefile.dep
+
+-include Makefile.dep
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/arcball.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/arcball.cxx
new file mode 100644
index 00000000..3eab9a29
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/arcball.cxx
@@ -0,0 +1,192 @@
+/************************************************************************
+
+ Arcball rotation control. See the original article
+
+ "Arcball Rotation Control"
+ by Ken Shoemake <[email protected]>
+ in "Graphics Gems IV", Academic Press, 1994.
+
+ for more details.
+
+ $Id: arcball.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/arcball.h>
+#include <gfx/gl.h>
+#include <sstream>
+
+namespace gfx
+{
+
+// Converts a unit quaternion to two points on the unit sphere
+static void quat_to_sphere(const Quat& q, Vec3& from, Vec3& to)
+{
+ const Vec3& v = q.vector();
+
+ double s = sqrt(v[0]*v[0] + v[1]*v[1]);
+ if( s==0.0 )
+ from = Vec3(0.0, 1.0, 0.0);
+ else
+ from = Vec3(-v[1]/s, v[0]/s, 0.0);
+
+ to[0] = q.scalar()*from[0] - v[2]*from[1];
+ to[1] = q.scalar()*from[1] + v[2]*from[2];
+ to[2] = v[0]*from[1] - v[1]*from[0];
+
+ if(q.scalar() < 0.0) from = -from;
+}
+
+// Converts to points on unit sphere into a unit quaternion
+static Quat quat_from_sphere(const Vec3& from, const Vec3& to)
+{
+ Vec3 v;
+ v[0] = from[1]*to[2] - from[2]*to[1];
+ v[1] = from[2]*to[0] - from[0]*to[2];
+ v[2] = from[0]*to[1] - from[1]*to[0];
+
+ double s = from*to;
+
+ return Quat(v, s);
+}
+
+
+Vec3 Arcball::proj_to_sphere(const Vec2& mouse)
+{
+ Vec2 p = (mouse - ball_ctr) / ball_radius;
+ double mag = p*p;
+
+ if( mag > 1.0 )
+ {
+ double s = sqrt(mag);
+ return Vec3(p[0]/s, p[1]/s, 0.0);
+ }
+ else
+ {
+ return Vec3(p[0], p[1], sqrt(1-mag));
+ }
+}
+
+void Arcball::update()
+{
+ // constrain v_from & v_to to axes here, if necessary
+
+ if( is_dragging )
+ {
+ q_drag = quat_from_sphere(v_from, v_to);
+ q_now = q_drag * q_down;
+ }
+}
+
+Arcball::Arcball()
+{
+ ball_ctr = Vec2(0, 0);
+ ball_radius = 1.0;
+
+ q_now = Quat::ident();
+ q_down = Quat::ident();
+ q_drag = Quat::ident();
+
+ is_dragging = false;
+}
+
+bool Arcball::mouse_down(int *where, int which)
+{
+ float vp[4];
+ glGetFloatv(GL_VIEWPORT, vp);
+ float W=vp[2], H=vp[3];
+
+ if( which==1 )
+ {
+ is_dragging = true;
+ Vec2 v( (2.0 * where[0] - W)/W, (H - 2.0 * where[1])/H );
+ v_from = proj_to_sphere(v);
+ v_to = v_from;
+ }
+
+ return true;
+}
+
+bool Arcball::mouse_up(int *where, int which)
+{
+ is_dragging = false;
+ q_down = q_now;
+ q_drag = Quat::ident();
+
+ return false;
+}
+
+bool Arcball::mouse_drag(int *where, int *last, int which)
+{
+ float vp[4];
+ glGetFloatv(GL_VIEWPORT, vp);
+ float W=vp[2], H=vp[3];
+
+ float diam = 2*radius;
+
+ if( which==1 )
+ {
+ Vec2 v( (2.0 * where[0] - W)/W, (H - 2.0 * where[1])/H );
+ v_to = proj_to_sphere(v);
+ }
+ else if( which==2 )
+ {
+ trans[0] += diam * (where[0] - last[0]) / W;
+ trans[1] += diam * (last[1] - where[1]) / H;
+ }
+ else if( which==3 )
+ {
+ trans[2] += 0.02*diam*(where[1] - last[1]);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+void Arcball::apply_transform()
+{
+ update();
+ curquat = conjugate(q_now);
+ Baseball::apply_transform();
+}
+
+
+void Arcball::update_animation()
+{
+}
+
+void Arcball::get_transform(Vec3 & c, Vec3 &t, Quat & q)
+{
+ c = ctr;
+ t = trans;
+ q = q_now;
+}
+
+void Arcball::set_transform(const Vec3 & c, const Vec3 &t, const Quat & q)
+{
+ ctr = c;
+ trans = t;
+ q_now = q;
+ q_down = q;
+ q_drag = q;
+}
+
+void Arcball::write(std::ostream& out)
+{
+ out << "arcball ";
+ out << ball_ctr << " " << ball_radius << " ";
+ out << q_now << " " << q_down << " " << q_drag << std::endl;
+ Baseball::write(out);
+}
+
+void Arcball::read(std::istream& in)
+{
+ std::string name;
+ in >> name;
+ in >> ball_ctr >> ball_radius;
+ in >> q_now >> q_down >> q_drag;
+ Baseball::read(in);
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/baseball.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/baseball.cxx
new file mode 100644
index 00000000..8a94cd3c
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/baseball.cxx
@@ -0,0 +1,59 @@
+/************************************************************************
+
+ Common code for ball-based rotation controllers.
+
+ $Id: baseball.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/gl.h>
+#include <gfx/baseball.h>
+#include <sstream>
+
+namespace gfx
+{
+
+Baseball::Baseball()
+{
+ curquat = Quat::ident();
+
+ trans=0.0;
+ ctr=0.0;
+ radius=1;
+}
+
+void Baseball::apply_transform()
+{
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glTranslated(trans[0], trans[1], trans[2]);
+ glTranslated(ctr[0], ctr[1], ctr[2]);
+
+ const Mat4 M=unit_quat_to_matrix(curquat);
+ glMultMatrixd(M);
+
+ glTranslated(-ctr[0], -ctr[1], -ctr[2]);
+}
+
+void Baseball::unapply_transform()
+{
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+}
+
+void Baseball::write(std::ostream& out)
+{
+ out << "baseball ";
+ out << curquat << " " << trans << " " << ctr << " " << radius << std::endl;
+}
+
+void Baseball::read(std::istream& in)
+{
+ std::string name;
+
+ in >> name;
+ in >> curquat >> trans >> ctr >> radius;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/color.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/color.cxx
new file mode 100644
index 00000000..96fdba72
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/color.cxx
@@ -0,0 +1,128 @@
+#include <gfx/color.h>
+#include <gfx/mat3.h>
+
+namespace gfx
+{
+ //
+ // HSV conversion code based on Foley et al (2nd ed. in C, pp. 592-593)
+ //
+
+ static double max3(double x, double y, double z)
+ {
+ if( x>=y && x>=z ) return x;
+ else if( y>=x && y>=z ) return y;
+ else return z;
+ }
+
+ static double min3(double x, double y, double z)
+ {
+ if( x<=y && x<=z ) return x;
+ else if( y<=x && y<=z ) return y;
+ else return z;
+ }
+
+ hsvColor RGBtoHSV(const rgbColor& rgb)
+ {
+ double r=rgb[0], g=rgb[1], b=rgb[2];
+
+ double max = max3(r,g,b);
+ double min = min3(r,g,b);
+ double delta = max - min;
+
+ double h = -1; // undefined value for case where v outside [0,360]
+ double v = max;
+ double s = (max!=0) ? (delta/max) : 0;
+
+ if( s != 0 )
+ {
+ if( r==max ) h = (g-b)/delta;
+ else if( g==max ) h = 2 + (b-r)/delta;
+ else if( b==max ) h = 4 + (r-g)/delta;
+
+ h *= 60;
+ if( h<0 ) h+=360;
+ }
+
+ return hsvColor(h, s, v);
+ }
+
+ rgbColor HSVtoRGB(const hsvColor& hsv)
+ {
+ double h = hsv[0], s=hsv[1], v=hsv[2];
+
+ // Unsaturated means pure gray
+ if(s == 0) return rgbColor(v, v, v);
+
+ if( h==360.0 ) h=0.0; // these are equivalent hues
+ h /= 60.0; // convert to sector [0, 6)
+ int i = (int)floor( h ); // integral part of h
+ float f = h - i; // fractional part of h
+
+ // Compute RGB components
+ float p = v * ( 1 - s );
+ float q = v * ( 1 - s * f );
+ float t = v * ( 1 - s * ( 1 - f ) );
+
+ // Map PQT to RGB based on sector of the color cone
+ switch( i )
+ {
+ case 0: return rgbColor(v, t, p); break;
+ case 1: return rgbColor(q, v, p); break;
+ case 2: return rgbColor(p, v, t); break;
+ case 3: return rgbColor(p, q, v); break;
+ case 4: return rgbColor(t, p, v); break;
+ default: return rgbColor(v, p, q); break;
+ }
+ }
+
+ // Paul Haeberli's comments on luminance coefficients:
+ //
+ // Where rwgt is 0.3086, gwgt is 0.6094, and bwgt is 0.0820. This
+ // is the luminance vector. Notice here that we do not use the
+ // standard NTSC weights of 0.299, 0.587, and 0.114. The NTSC
+ // weights are only applicable to RGB colors in a gamma 2.2 color
+ // space. For linear RGB colors the values above are better.
+ //
+ // Grafica Obscura -- Matrix Operations for Image Processing
+ // http://www.sgi.com/misc/grafica/matrix/index.html
+ //
+ const rgbColor haeberli_factor(0.3086, 0.6094, 0.0820);
+ const rgbColor ntsc_factor(0.299, 0.587, 0.114);
+
+ float rgb_luminance_ntsc(const rgbColor& rgb) { return rgb*ntsc_factor; }
+ float rgb_luminance_alt(const rgbColor& rgb) { return rgb*haeberli_factor; }
+
+
+ const Mat3 M_yiq(ntsc_factor,
+ Vec3(0.596, -0.275, -0.321),
+ Vec3(0.212, -0.523, 0.311));
+
+ yiqColor RGBtoYIQ(const rgbColor& rgb)
+ {
+ return yiqColor(M_yiq * Vec3(rgb));
+ }
+
+ // Matrix conversions taken from the ColorFAQ by Charles Poynton
+ const Mat3 M_rgb(Vec3( 3.240479, -1.537150, -0.498535),
+ Vec3(-0.969256, 1.875992, 0.041556),
+ Vec3( 0.055648, -0.204043, 1.057311));
+
+ const Mat3 M_xyz(Vec3(0.412453, 0.357580, 0.180423),
+ Vec3(0.212671, 0.715160, 0.072169),
+ Vec3(0.019334, 0.119193, 0.950227));
+
+ // Derived from equations provided by EasyRGB:
+ // http://www.easyrgb.com/math.php
+ //
+ xyzColor RGBtoXYZ(const rgbColor& rgb)
+ { return xyzColor(M_xyz * Vec3(rgb)); }
+
+ rgbColor XYZtoRGB(const xyzColor& xyz)
+ { return rgbColor(M_rgb * Vec3(xyz)); }
+
+ xyChromaticity xyz_chromaticity(const xyzColor& xyz)
+ {
+ float w = xyz[0] + xyz[1] + xyz[2];
+ return xyChromaticity(xyz[0]/w, xyz[1]/w);
+ }
+}
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/geom3d.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/geom3d.cxx
new file mode 100644
index 00000000..ff9e8e44
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/geom3d.cxx
@@ -0,0 +1,33 @@
+/************************************************************************
+
+ Handy 3D geometrical primitives
+
+ $Id: geom3d.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/geom3d.h>
+#include <gfx/mat4.h>
+
+namespace gfx
+{
+
+double tetrahedron_determinant(const Vec3& v0, const Vec3& v1,
+ const Vec3& v2, const Vec3& v3)
+{
+ Mat4 A( Vec4(v0, 1),
+ Vec4(v1, 1),
+ Vec4(v2, 1),
+ Vec4(v3, 1));
+
+ return det(A);
+}
+
+double tetrahedron_volume(const Vec3& v0, const Vec3& v1,
+ const Vec3& v2, const Vec3& v3)
+{
+ return fabs(tetrahedron_determinant(v0,v1,v2,v3)/6);
+}
+
+}
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/geom4d.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/geom4d.cxx
new file mode 100644
index 00000000..2973f966
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/geom4d.cxx
@@ -0,0 +1,14 @@
+/************************************************************************
+
+ Handy 4D geometrical primitives
+
+ $Id: geom4d.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/geom4d.h>
+
+namespace gfx
+{
+}
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/gltools.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/gltools.cxx
new file mode 100644
index 00000000..565a382e
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/gltools.cxx
@@ -0,0 +1,192 @@
+/************************************************************************
+
+ Handy functions for common OpenGL tasks
+
+ $Id: gltools.cxx 446 2005-06-18 13:58:15Z garland $
+
+ ************************************************************************/
+
+
+#include <gfx/gfx.h>
+
+#ifdef HAVE_OPENGL
+
+#include <gfx/gltools.h>
+
+#include <cassert>
+
+namespace gfx
+{
+
+using std::cerr;
+using std::endl;
+
+GLuint opengl_pick_nil = (~0);
+GLuint opengl_pick_zmax = (~0);
+
+void begin_opengl_pick(int *where, double radius, GLuint *buffer, int size)
+{
+ GLint vp[4];
+ glGetIntegerv(GL_VIEWPORT, vp);
+
+ glSelectBuffer(size, buffer);
+ glRenderMode(GL_SELECT);
+ glInitNames();
+ glPushName(opengl_pick_nil);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix(); // Save the current transformation
+ glLoadIdentity();
+ gluPickMatrix(where[0], vp[3] - where[1], radius, radius, vp);
+}
+
+GLuint complete_opengl_pick(GLuint *buffer)
+{
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix(); // get rid of the pick matrix
+ glFlush();
+
+ GLint nhits = glRenderMode(GL_RENDER);
+ GLuint *hit = NULL;
+ GLuint hit_nnames = 0;
+ GLuint zmin = opengl_pick_zmax;
+ GLuint *ptr = buffer;
+
+ for(int i=0; i<nhits; i++)
+ {
+ GLuint nnames = *ptr++;
+ GLuint cur_zmin = *ptr++;
+ /* GLuint cur_zmax = */ *ptr++;
+
+ if( cur_zmin < zmin )
+ {
+ zmin = cur_zmin;
+ hit = ptr;
+ hit_nnames = nnames;
+ }
+ ptr+=nnames;
+ }
+
+
+ buffer[0] = hit_nnames;
+ if( hit )
+ {
+ for(int k=0; k<hit_nnames; k++)
+ buffer[k+1] = hit[k];
+
+ return *hit;
+ }
+ else
+ return opengl_pick_nil;
+}
+
+void report_opengl_stacks()
+{
+ GLint depth;
+
+ glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &depth);
+ cerr << " Projection stack depth = " << depth;
+ glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, &depth);
+ cerr << " (" << depth << " max)" << endl;
+
+ glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
+ cerr << " ModelView stack depth = " << depth;
+ glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &depth);
+ cerr << " (" << depth << " max)" << endl;
+
+ glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &depth);
+ cerr << " Texture stack depth = " << depth;
+ glGetIntegerv(GL_MAX_TEXTURE_STACK_DEPTH, &depth);
+ cerr << " (" << depth << " max)" << endl;
+}
+
+void check_opengl_errors(const char *msg)
+{
+ bool stack_error = false;
+
+ for(GLenum err=glGetError(); err!=GL_NO_ERROR; err=glGetError())
+ {
+ cerr << "GL ERROR ";
+ if( msg ) cerr << msg;
+ cerr << ": " << (const char *)gluErrorString(err) << endl;
+
+ if( err==GL_STACK_OVERFLOW || err==GL_STACK_UNDERFLOW )
+ stack_error = true;
+ }
+
+ if( stack_error ) report_opengl_stacks();
+}
+
+void camera_lookat(const Vec3& min, const Vec3& max, double aspect)
+{
+ Vec3 up(0, 1, 0);
+ double fovy = 60.0;
+
+ Vec3 at = (max + min)/2.0; // look at the center of the bbox
+ double radius = norm(max - at); // radius of a bounding sphere
+ double d = 3*radius / tan(fovy * M_PI/180.0);
+
+ Vec3 from = at;
+ from[2] += d;
+
+ double znear = d/20;
+ double zfar = 10*d;
+
+ glMatrixMode(GL_PROJECTION);
+ gluPerspective(fovy, aspect, znear, zfar);
+
+
+ glMatrixMode(GL_MODELVIEW);
+ gluLookAt(from[0], from[1], from[2],
+ at[0], at[1], at[2],
+ up[0], up[1], up[2]);
+}
+
+void ortho_camera_lookat(const Vec3& min, const Vec3& max, double aspect)
+{
+ Vec3 up(0, 1, 0);
+ double fovy = 60.0;
+
+ Vec3 at = (max + min)/2.0; // look at the center of the bbox
+ double radius = norm(max - at); // radius of a bounding sphere
+ double d = 3*radius / tan(fovy * M_PI/180.0);
+
+ Vec3 from = at;
+ from[2] += d;
+
+ Vec3 diag = max-min;
+ double width = MAX(diag[0], diag[1]); width=MAX(width, diag[2]);
+ width *= 1.1;
+
+ double znear = d/20;
+ double zfar = 10*d;
+ glMatrixMode(GL_PROJECTION);
+ glOrtho(-aspect/2*width, aspect/2*width, -0.5*width, 0.5*width, znear, zfar);
+
+ glMatrixMode(GL_MODELVIEW);
+ gluLookAt(from[0], from[1], from[2],
+ at[0], at[1], at[2],
+ up[0], up[1], up[2]);
+}
+
+int unproject_pixel(int *pixel, double *world, double z)
+{
+ GLdouble modelMatrix[16];
+ GLdouble projMatrix[16];
+ GLint viewport[4];
+
+ glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
+ glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
+ glGetIntegerv(GL_VIEWPORT, viewport);
+
+ // Notice that we have to correct the y pixel coordinate. GL
+ // assigns the origin to the lower left corner, while FLTK assigns
+ // the origin to the upper left corner.
+ return gluUnProject(pixel[0], viewport[3]-pixel[1], z,
+ modelMatrix, projMatrix, viewport,
+ world, world+1, world+2);
+}
+
+} // namespace gfx
+
+#endif /* HAVE_OPENGL */
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/gui-mfc.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/gui-mfc.cxx
new file mode 100644
index 00000000..a9ab22e5
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/gui-mfc.cxx
@@ -0,0 +1,297 @@
+/************************************************************************
+
+ MxGUI-like emulation in MFC.
+
+ $Id: gui-mfc.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/win/gui-mfc.h>
+
+namespace gfx
+{
+
+static inline MfcGUI *GuiGetApp() { return (MfcGUI *)AfxGetApp(); }
+
+MfcGUI::MfcGUI()
+{
+ canvas = NULL;
+ timer_id = 0;
+ default_fps = 24.0f;
+ target_fps = 0.0f;
+}
+
+void MfcGUI::status(const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ CString str;
+ str.FormatV(fmt, args);
+ va_end(args);
+
+ if( canvas && canvas->status_line )
+ canvas->status_line->SetPaneText(0, str);
+}
+
+static VOID CALLBACK cb_timeout(HWND w, UINT msg, UINT id, DWORD system_time)
+{
+ GuiGetApp()->update_animation();
+ GuiGetApp()->canvas->post_redraw();
+}
+
+void MfcGUI::animate(bool will)
+{
+ if( will )
+ {
+ target_fps = default_fps;
+
+ float millisecs = 1000 / target_fps;
+ timer_id = ::SetTimer(NULL, 0, (UINT)millisecs, cb_timeout);
+ }
+ else
+ {
+ target_fps = 0;
+ if( timer_id ) ::KillTimer(NULL, timer_id);
+ timer_id = 0;
+ }
+}
+
+BOOL MfcGUI::InitInstance()
+{
+ m_pMainWnd = canvas = new Canvas;
+ m_pMainWnd->ShowWindow(m_nCmdShow);
+ m_pMainWnd->UpdateWindow();
+ return TRUE;
+}
+
+
+
+BEGIN_MESSAGE_MAP(Canvas, CFrameWnd)
+ ON_WM_CREATE()
+ ON_WM_DESTROY()
+ ON_WM_SIZE()
+
+ //ON_WM_ACTIVATE()
+ ON_WM_PAINT()
+ ON_WM_ERASEBKGND()
+
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_RBUTTONDOWN()
+ ON_WM_RBUTTONUP()
+ ON_WM_MBUTTONDOWN()
+ ON_WM_MBUTTONUP()
+ ON_WM_MOUSEMOVE()
+ ON_WM_CHAR()
+END_MESSAGE_MAP()
+
+Canvas::Canvas()
+{
+ last_click[0] = last_click[1] = -1;
+ glcontext = NULL;
+ pixfmt = 0;
+
+
+ Create(NULL, "Sample Application");
+
+ CMenu menu;
+ menu.CreateMenu();
+
+ CMenu popup;
+ popup.CreatePopupMenu();
+ popup.AppendMenu(MF_STRING, 0, "&New\tCtrl+N");
+ menu.AppendMenu(MF_POPUP, (UINT)popup.Detach(), "&File");
+
+ SetMenu(&menu);
+ menu.Detach();
+
+ status_line = new CStatusBar();
+ status_line->Create(this);
+ UINT indicator = ID_SEPARATOR;
+ status_line->SetIndicators(&indicator, 1);
+}
+
+BOOL Canvas::PreCreateWindow(CREATESTRUCT &cs)
+{
+ // Need to set special style requirements for OpenGL windows
+ cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+ return CFrameWnd::PreCreateWindow(cs);
+}
+
+
+int Canvas::OnCreate(LPCREATESTRUCT lpcs)
+{
+ if( CFrameWnd::OnCreate(lpcs) == -1 ) return -1;
+
+ HWND wnd = GetSafeHwnd();
+ HDC dc = ::GetDC(wnd);
+
+ pixfmt = set_pixel_format(dc);
+ if( !pixfmt )
+ MessageBox("Failed to set up proper pixel format.");
+
+ glcontext = create_glcontext(dc);
+ if( !glcontext )
+ MessageBox("Failed to create GL context.");
+
+ return 0;
+}
+
+void Canvas::OnPaint()
+{
+ CPaintDC dc(this);
+
+ HDC hdc = dc.GetSafeHdc();
+ make_current(hdc);
+
+ GuiGetApp()->draw_contents();
+
+ finish(hdc);
+}
+
+void Canvas::OnDestroy()
+{
+ if( wglGetCurrentContext() )
+ wglMakeCurrent(NULL, NULL);
+
+ if( glcontext )
+ {
+ wglDeleteContext(glcontext);
+ glcontext = NULL;
+ }
+
+ CFrameWnd::OnDestroy();
+}
+
+void Canvas::OnSize(UINT type, int width, int height)
+{
+ CFrameWnd::OnSize(type, width, height);
+ glViewport(0, 0, width, height);
+ GuiGetApp()->setup_for_drawing();
+}
+
+BOOL Canvas::OnEraseBkgnd(CDC *dc)
+{
+ return FALSE; // Don't want background to be erased thank you
+}
+
+void Canvas::immediate_redraw()
+{
+ SendMessage(WM_PAINT);
+}
+
+void Canvas::post_redraw()
+{
+ InvalidateRect(NULL, FALSE);
+}
+
+int Canvas::decode_mouse_button(UINT flags, int which)
+{
+ if( which==0 )
+ {
+ if( flags&MK_MBUTTON ) which = 2;
+ else if( flags&MK_LBUTTON ) which = 1;
+ else if( flags&MK_RBUTTON ) which = 3;
+ }
+
+ // Emulate middle button by double click
+ if( flags&MK_LBUTTON && flags&MK_RBUTTON ) which = 2;
+
+ return which;
+}
+
+void Canvas::do_mouse_down(int which, UINT flags, CPoint point)
+{
+ which = decode_mouse_button(flags, which);
+
+ int where[2]; where[0]=point.x; where[1]=point.y;
+ last_click[0]=point.x; last_click[1]=point.y;
+
+ SetCapture();
+ if( GuiGetApp()->mouse_down(where, which) )
+ post_redraw();
+}
+
+void Canvas::do_mouse_up(int which, UINT flags, CPoint point)
+{
+ which = decode_mouse_button(flags, which);
+
+ int where[2]; where[0]=point.x; where[1]=point.y;
+
+ ReleaseCapture();
+ if( GuiGetApp()->mouse_up(where, which) )
+ post_redraw();
+}
+
+void Canvas::do_mouse_move(UINT flags, CPoint point)
+{
+ int which = decode_mouse_button(flags);
+
+ int where[2]; where[0]=point.x; where[1]=point.y;
+
+ if( GuiGetApp()->mouse_drag(where, last_click, which) )
+ post_redraw();
+
+ last_click[0]=point.x; last_click[1]=point.y;
+}
+
+// Each mouse handler is given a set of flags 'f' and a position 'p'
+void Canvas::OnLButtonDown(UINT f, CPoint p) { do_mouse_down(1, f, p); }
+void Canvas::OnRButtonDown(UINT f, CPoint p) { do_mouse_down(3, f, p); }
+void Canvas::OnMButtonDown(UINT f, CPoint p) { do_mouse_down(2, f, p); }
+void Canvas::OnLButtonUp(UINT f, CPoint p) { do_mouse_up(1, f, p); }
+void Canvas::OnRButtonUp(UINT f, CPoint p) { do_mouse_up(3, f, p); }
+void Canvas::OnMButtonUp(UINT f, CPoint p) { do_mouse_up(2, f, p); }
+void Canvas::OnMouseMove(UINT f, CPoint p) { do_mouse_move(f, p); }
+
+void Canvas::OnChar(UINT ch, UINT repcount, UINT flags)
+{
+ GuiGetApp()->key_press(ch);
+}
+
+#if 0
+void Canvas::OnActivate(UINT state, CWnd *other, BOOL is_minimized)
+{
+ if( state==WA_ACTIVE || state==WA_CLICKACTIVE )
+ {
+ wglMakeCurrent(dc, glcontext);
+ }
+}
+#endif
+
+
+
+/*****************************************
+
+NOTES:
+
+ AfxGetApp() returns a CWinApp* to the current application
+ AfxGetAppName() returns a const char* to application name
+
+
+ ****************************************/
+
+void MfcGUI::setup_for_drawing()
+{
+ status("Hello There");
+}
+
+void MfcGUI::draw_contents()
+{
+ glClearColor(0.8f, 0.2f, 0.2f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+bool MfcGUI::mouse_down(int *where, int which) { return false; }
+
+bool MfcGUI::mouse_up(int *where, int which) { return false; }
+
+bool MfcGUI::mouse_drag(int *where, int *last, int which) { return false; }
+
+bool MfcGUI::key_press(int key) { return false; }
+
+void MfcGUI::update_animation() { }
+
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/gui.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/gui.cxx
new file mode 100644
index 00000000..7102aed2
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/gui.cxx
@@ -0,0 +1,509 @@
+/************************************************************************
+
+ MxGUI
+
+ $Id: gui.cxx 447 2005-06-18 14:01:16Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+
+#ifdef HAVE_FLTK
+
+#include <gfx/gui.h>
+#include <gfx/raster.h>
+
+#include <FL/Fl_File_Chooser.H>
+#include <FL/fl_ask.H>
+
+#include <cstdio>
+#include <cstdarg>
+#include <fstream>
+
+namespace gfx
+{
+
+MxGUI *MxGUI::current = NULL;
+
+MxGLCanvas::MxGLCanvas(int x, int y, int w, int h, const char *l)
+ : Fl_Gl_Window(x, y, w, h, l)
+{
+ last_click[0] = last_click[1] = -1;
+ app = NULL;
+}
+
+void MxGLCanvas::attach_app(MxGUI *a)
+{
+ if( !app )
+ app = a;
+}
+
+void MxGLCanvas::resize(int x, int y, int w, int h)
+{
+ Fl_Gl_Window::resize(x, y, w, h);
+
+ if( shown() )
+ {
+ make_current();
+ glViewport(0, 0, w, h);
+ invalidate();
+ }
+}
+
+void MxGLCanvas::draw()
+{
+ if( !valid() )
+ {
+ valid(1);
+ if(app) app->setup_for_drawing();
+ }
+
+ if(app) app->draw_contents();
+}
+
+int MxGLCanvas::handle(int event)
+{
+ bool need_redraw = false;
+
+ int where[2]; where[0] = Fl::event_x(); where[1] = Fl::event_y();
+
+ // NOTE: Normally, we examine event_state() rather than
+ // event_button() because it is valid no matter what the generating
+ // event whereas event_button() is only valid for PUSH and RELEASE
+ // events. However, since event_state() only tells us what buttons
+ // are *pressed*, we need to revert to event_button() on RELEASE
+ // events.
+ //
+ int which = Fl::event_button();
+
+ if( event != FL_RELEASE )
+ {
+ if( Fl::event_state(FL_BUTTON1) )
+ {
+ // emulate middle button by combination of left & right buttons
+ if( Fl::event_state(FL_BUTTON3) ) which = 2;
+ else which = 1;
+ }
+ else if( Fl::event_state(FL_BUTTON2) ) which = 2;
+ else if( Fl::event_state(FL_BUTTON3) ) which = 3;
+ }
+
+ switch( event )
+ {
+ case FL_PUSH:
+ need_redraw = app && app->mouse_down(where, which);
+ last_click[0]=where[0]; last_click[1]=where[1];
+ break;
+
+ case FL_RELEASE:
+ need_redraw = app && app->mouse_up(where, which);
+ break;
+
+ case FL_DRAG:
+ need_redraw = app && app->mouse_drag(where, last_click, which);
+ last_click[0]=where[0]; last_click[1]=where[1];
+ break;
+
+ case FL_FOCUS:
+ case FL_UNFOCUS:
+ // Do nothing special
+ break;
+
+ case FL_KEYBOARD:
+ if( !app || !app->key_press(Fl::event_key()) )
+ return 0;
+ break;
+
+ default:
+ return Fl_Gl_Window::handle(event);
+ }
+
+ if( need_redraw )
+ redraw();
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// Default menu system. Although the application can completely
+// override this, it's expected that most programs will just add their
+// own additional entries.
+//
+
+void MxGUI::cb_new() { }
+
+void MxGUI::cb_exit() { cleanup_for_exit(); exit(0); }
+
+void MxGUI::cb_animate(Fl_Menu_ *m)
+ { animate(m->mvalue()->value()!=0); }
+
+void MxGUI::cb_fps()
+{
+ // Convert default_fps to a string
+ static char fps[64]; sprintf(fps, "%.1f", default_fps);
+
+ const char *result = fl_input("Number of frames per second to draw", fps);
+ if( result )
+ {
+ default_fps = atof(result);
+ if( target_fps>0 ) target_fps=default_fps;
+ }
+}
+
+void MxGUI::cb_snapshot(int format)
+{
+ canvas->redraw(); // don't want to snap menu
+ snapshot_to_file(format); // snapshot what's drawn
+}
+
+void MxGUI::cb_vga_size(int xw)
+{
+ if( toplevel->resizable() )
+ resize_canvas(xw, (3*xw)/4);
+}
+
+void MxGUI::cb_hdtv_size(int xw)
+{
+ if( toplevel->resizable() )
+ MxGUI::current->resize_canvas(xw, (9*xw)/16);
+}
+
+void MxGUI::cb_dv_size(int xw)
+{
+ if( toplevel->resizable() )
+ MxGUI::current->resize_canvas(xw, (2*xw)/3);
+}
+
+void MxGUI::cb_toggle(Fl_Menu_ *m, bool *flag)
+{
+ *flag = m->mvalue()->value()!=0;
+ current->canvas->redraw();
+}
+
+void MxGUI::cb_save_view_to_file() { save_view_to_file(); }
+void MxGUI::cb_load_view_from_file() { load_view_from_file(); }
+
+bool MxGUI::save_view_to_file()
+{
+ fl_alert("This application has not defined a scheme for saving the view.");
+ return false;
+}
+
+bool MxGUI::load_view_from_file()
+{
+ fl_alert("This application has not defined a scheme for loading the view.");
+ return false;
+}
+
+int MxGUI::add_menu(const std::string& s, int key, Fl_Callback *cb, int flags)
+{
+ return menu_bar->add(s.c_str(), key, cb, this, flags);
+}
+
+int MxGUI::add_toggle_menu(const std::string& s, int key, bool& val, int flags)
+{
+ return menu_bar->add(s.c_str(), key, (Fl_Callback *)cb_toggle, &val,
+ FL_MENU_TOGGLE|(val?FL_MENU_VALUE:0)|flags);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifdef __CYGWIN__
+extern "C"{
+ extern int mainCRTStartup();
+ int WinMainCRTStartup() { mainCRTStartup(); return 1; }
+}
+#endif
+
+MxGUI::MxGUI()
+{
+ canvas = NULL;
+ status_line = NULL;
+ default_fps = 24.0f;
+ target_fps = 0.0f;
+ MxGUI::current = this;
+}
+
+Fl_Window *MxGUI::create_window(int xw, int yw, int pad)
+{
+ int yfill = 0;
+
+ Fl_Window *w = new Fl_Window(xw+2*pad, 0);
+ toplevel = w;
+ w->box(FL_UP_BOX);
+
+ menu_bar = new Fl_Menu_Bar(0, yfill, w->w(), 30);
+ menu_bar->menu(menu_layout);
+ yfill += menu_bar->h();
+
+ add_upper_controls(yfill, pad);
+
+ yfill += pad;
+ canvas = new MxGLCanvas(pad, yfill, xw, yw);
+ canvas->box(FL_DOWN_FRAME);
+ canvas->attach_app(this);
+
+ int glmode = 0;
+ if(canvas->can_do(FL_RGB8)) glmode|=FL_RGB8;
+ if(canvas->can_do(FL_DOUBLE)) glmode|=FL_DOUBLE;
+ if(canvas->can_do(FL_DEPTH)) glmode|=FL_DEPTH;
+ if(canvas->can_do(FL_ALPHA)) glmode|=FL_ALPHA;
+ if(glmode) canvas->mode(glmode);
+
+ yfill += canvas->h();
+
+ add_lower_controls(yfill, pad);
+
+ yfill += pad;
+ status_line = new Fl_Output(pad, yfill, xw, 25);
+ status_line->color(48);
+ status_line->labeltype(FL_NO_LABEL);
+ yfill += status_line->h();
+
+ w->end();
+
+ w->size(w->w(), yfill+pad); // adjust window height
+ w->resizable(*canvas); // resize canvas with window
+
+ // These are used by resize_canvas() to resize the window based on
+ // the target size of the canvas.
+ w_offset = w->w() - xw;
+ h_offset = w->h() - yw;
+
+ return w;
+}
+
+static
+int arg_redirect(int argc, char **argv, int& index)
+{
+ MxGUI *app = MxGUI::current;
+ return app?app->cmdline_option(argc, argv, index):0;
+}
+
+void MxGUI::initialize(int argc, char **argv, Fl_Menu_Item *m, int xw, int yw)
+{
+ Fl::visual(FL_RGB8);
+ menu_layout = m?m:NULL;
+
+ int index = 0;
+ if( argv )
+ Fl::args(argc, argv, index, arg_redirect);
+
+ create_window(xw, yw);
+ toplevel->label("Graphics Program");
+
+ // Add dynamic entries
+ typedef MxBinder<MxGUI> CB;
+ std::string snap = "&File/Snapshot to/";
+ std::string view = "&View/";
+ std::string size = "&View/Display &size/";
+
+ add_menu("&File/&New", FL_CTRL+'n', CB::to<&MxGUI::cb_new>);
+
+#if defined(HAVE_LIBPNG)
+ add_menu(snap+"&PNG",
+ FL_CTRL+'p', CB::to_arg<&MxGUI::cb_snapshot, IMG_PNG>);
+#endif
+#if defined(HAVE_LIBTIFF)
+ add_menu("&File/Snapshot to/&TIFF",
+ FL_CTRL+'P', CB::to_arg<&MxGUI::cb_snapshot, IMG_TIFF>);
+#endif
+#if defined(HAVE_LIBJPEG)
+ add_menu("&File/Snapshot to/&JPEG", 0, CB::to_arg<&MxGUI::cb_snapshot, IMG_JPEG>);
+#endif
+ add_menu("&File/Snapshot to/PP&M", 0, CB::to_arg<&MxGUI::cb_snapshot, IMG_PNM>);
+
+ add_menu("&File/E&xit", FL_CTRL+'q', CB::to<&MxGUI::cb_exit>);
+
+ add_menu(view+"Animation speed ...", FL_CTRL+'r', CB::to<&MxGUI::cb_fps>);
+ add_menu(view+"&Animate", FL_CTRL+'a', CB::to_menu<&MxGUI::cb_animate>, FL_MENU_TOGGLE);
+
+ add_menu(view+"Save view ...", 0, CB::to<&MxGUI::cb_save_view_to_file>);
+ add_menu(view+"Load view ...", 0, CB::to<&MxGUI::cb_load_view_from_file>);
+
+ add_menu(size+"320x240",0, CB::to_arg<&MxGUI::cb_vga_size, 320>);
+ add_menu(size+"640x480",0, CB::to_arg<&MxGUI::cb_vga_size, 640>);
+ add_menu(size+"800x600",0, CB::to_arg<&MxGUI::cb_vga_size, 800>);
+ add_menu(size+"1024x768",0,CB::to_arg<&MxGUI::cb_vga_size, 1024>,FL_MENU_DIVIDER);
+ add_menu(size+"720x480",0, CB::to_arg<&MxGUI::cb_dv_size, 720>,FL_MENU_DIVIDER);
+
+ add_menu(size+"480x270",0, CB::to_arg<&MxGUI::cb_hdtv_size, 480>);
+ add_menu(size+"960x540",0, CB::to_arg<&MxGUI::cb_hdtv_size, 960>);
+ add_menu(size+"1920x1080",0, CB::to_arg<&MxGUI::cb_hdtv_size, 1920>);
+
+ if( argv )
+ {
+ if( index==argc )
+ cmdline_file(NULL);
+ else
+ for(; index<argc; index++)
+ cmdline_file(argv[index]);
+ }
+}
+
+int MxGUI::run()
+{
+ toplevel->show();
+ return Fl::run();
+}
+
+static
+void cb_timeout(void *)
+{
+ MxGUI *app = MxGUI::current;
+
+ if(!app || app->target_fps==0.0f) return;
+
+ app->update_animation();
+ app->canvas->redraw();
+ Fl::repeat_timeout(1/app->target_fps, cb_timeout);
+}
+
+void MxGUI::animate(bool will)
+{
+ if( will )
+ {
+ target_fps = default_fps;
+ Fl::add_timeout(1/target_fps, cb_timeout);
+ }
+ else
+ target_fps = 0;
+}
+
+int MxGUI::status(const char *fmt, ...)
+{
+ static char strbuf[1000];
+
+ va_list args;
+ va_start(args, fmt);
+ int n = vsprintf(strbuf, fmt, args);
+
+ status_line->value(strbuf);
+ return n;
+}
+
+bool MxGUI::snapshot_to_file(int format, const char *filenamep)
+{
+ canvas->make_current();
+ Fl::flush();
+
+ GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp);
+
+ glPushAttrib(GL_PIXEL_MODE_BIT);
+ glReadBuffer(GL_FRONT);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+ int nchan = 3;
+ if( format==IMG_PNG || format==IMG_TIFF )
+ // Currently, only TIFF and PNG writers support the alpha channel
+ nchan = 4;
+
+ ByteRaster img(vp[2]-vp[0], vp[3]-vp[1], nchan);
+ glReadPixels(vp[0],vp[1],vp[2],vp[3],
+ nchan==4 ? GL_RGBA : GL_RGB,
+ GL_UNSIGNED_BYTE,img.head());
+
+ glPopAttrib();
+ img.vflip();
+
+ if ( filenamep == NULL )
+ {
+ char msg[80], pat[8], name[16];
+ sprintf(msg, "Save %s Snapshot", image_type_name(format));
+ sprintf(pat, "*.%s", image_type_ext(format));
+ sprintf(name, "snap.%s", image_type_ext(format));
+
+ filenamep = fl_file_chooser(msg, pat, name);
+ }
+
+ if( filenamep )
+ return write_image(filenamep, img, format);
+ else
+ return false;
+}
+
+void MxGUI::lock_size()
+{
+ toplevel->size_range(toplevel->w(), toplevel->h(),
+ toplevel->w(), toplevel->h());
+ toplevel->resizable(NULL);
+}
+
+void MxGUI::unlock_size()
+{
+ toplevel->resizable(*canvas);
+ toplevel->size_range(100, 100, 0, 0);
+}
+
+
+void MxGUI::resize_canvas(int width, int height)
+{
+ toplevel->size(width+w_offset, height+h_offset);
+ toplevel->redraw();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void MxGUI::setup_for_drawing()
+{
+ glClearColor(0.65f, 0.65f, 0.65f, 0.0f);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
+}
+
+void MxGUI::draw_contents()
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glColor3f(0.0, 0.0, 0.0);
+ glBegin(GL_LINES);
+ glVertex2f(-1.0, 0.0); glVertex2f(1.0, 0.0);
+ glVertex2f(0.0, -1.0); glVertex2f(0.0, 1.0);
+ glEnd();
+
+ glPopMatrix();
+}
+
+void MxGUI::update_animation()
+{
+}
+
+bool MxGUI::mouse_down(int *where, int which)
+{
+ return false;
+}
+
+bool MxGUI::mouse_up(int *where, int which)
+{
+ return false;
+}
+
+bool MxGUI::mouse_drag(int *where, int *last, int which)
+{
+ return false;
+}
+
+bool MxGUI::key_press(int key)
+{
+ return false;
+}
+
+int MxGUI::cmdline_option(int argc, char **argv, int& index)
+{
+ return 0;
+}
+
+void MxGUI::cmdline_file(const char *file)
+{
+}
+
+} // namespace gfx
+
+#endif /* HAVE_FLTK */
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/mat2.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/mat2.cxx
new file mode 100644
index 00000000..42ed3e1a
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/mat2.cxx
@@ -0,0 +1,89 @@
+/************************************************************************
+
+ 2x2 Matrix class
+
+ $Id: mat2.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/mat2.h>
+
+namespace gfx
+{
+
+Mat2 Mat2::I() { return Mat2(1,0, 0,1); }
+
+Mat2 &Mat2::diag(double d)
+{
+ row[0][0] = d; row[0][1] = 0;
+ row[1][0] = 0; row[1][1] = d;
+
+ return *this;
+}
+
+Mat2 operator*(const Mat2 &n, const Mat2& m)
+{
+ Mat2 A;
+ int i,j;
+
+ for(i=0;i<2;i++)
+ for(j=0;j<2;j++)
+ A(i,j) = n[i]*m.col(j);
+
+ return A;
+}
+
+double invert(Mat2 &inv, const Mat2 &m)
+{
+ double d = det(m);
+
+ if( d==0.0 )
+ return 0.0;
+
+ inv(0, 0) = m(1,1)/d;
+ inv(0, 1) = -m(0,1)/d;
+ inv(1, 0) = -m(1,0)/d;
+ inv(1, 1) = m(0,0)/d;
+
+ return d;
+}
+
+bool eigenvalues(const Mat2& M, Vec2& evals)
+{
+ double B = -M(0,0)-M(1,1);
+ double C = det(M);
+
+ double dis = B*B - 4.0*C;
+ if( dis<FEQ_EPS )
+ return false;
+ else
+ {
+ double s = sqrt(dis);
+
+ evals[0] = 0.5*(-B + s);
+ evals[1] = 0.5*(-B - s);
+ return true;
+ }
+}
+
+bool eigenvectors(const Mat2& M, const Vec2& evals, Vec2 evecs[2])
+{
+ evecs[0] = Vec2(-M(0,1), M(0,0)-evals[0]);
+ evecs[1] = Vec2(-M(0,1), M(0,0)-evals[1]);
+
+ unitize(evecs[0]);
+ unitize(evecs[1]);
+
+ return true;
+}
+
+bool eigen(const Mat2& M, Vec2& evals, Vec2 evecs[2])
+{
+ bool result = eigenvalues(M, evals);
+ if( result )
+ eigenvectors(M, evals, evecs);
+ return result;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/mat3.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/mat3.cxx
new file mode 100644
index 00000000..eda9fe3c
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/mat3.cxx
@@ -0,0 +1,82 @@
+/************************************************************************
+
+ 3x3 Matrix class
+
+ $Id: mat3.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/mat3.h>
+
+namespace gfx
+{
+
+Mat3 Mat3::I() { return Mat3(Vec3(1,0,0), Vec3(0,1,0), Vec3(0,0,1)); }
+
+Mat3 &Mat3::diag(double d)
+{
+ *this = 0.0;
+ row[0][0] = row[1][1] = row[2][2] = d;
+ return *this;
+}
+
+Mat3 diag(const Vec3& v)
+{
+ return Mat3(Vec3(v[0],0,0), Vec3(0,v[1],0), Vec3(0,0,v[2]));
+}
+
+Mat3 Mat3::outer_product(const Vec3& v)
+{
+ Mat3 A;
+ double x=v[0], y=v[1], z=v[2];
+
+ A(0,0) = x*x; A(0,1) = x*y; A(0,2) = x*z;
+ A(1,0)=A(0,1); A(1,1) = y*y; A(1,2) = y*z;
+ A(2,0)=A(0,2); A(2,1)=A(1,2); A(2,2) = z*z;
+
+ return A;
+}
+
+Mat3 Mat3::outer_product(const Vec3& u, const Vec3& v)
+{
+ Mat3 A;
+
+ for(int i=0; i<3; i++)
+ for(int j=0; j<3; j++)
+ A(i, j) = u[i]*v[j];
+
+ return A;
+}
+
+Mat3 operator*(const Mat3& n, const Mat3& m)
+{
+ Mat3 A;
+
+ for(int i=0;i<3;i++)
+ for(int j=0;j<3;j++)
+ A(i,j) = n[i]*m.col(j);
+
+ return A;
+}
+
+Mat3 adjoint(const Mat3& m)
+{
+ return Mat3(m[1]^m[2],
+ m[2]^m[0],
+ m[0]^m[1]);
+}
+
+double invert(Mat3& inv, const Mat3& m)
+{
+ Mat3 A = adjoint(m);
+ double d = A[0] * m[0];
+
+ if( d==0.0 )
+ return 0.0;
+
+ inv = transpose(A) / d;
+ return d;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/mat4.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/mat4.cxx
new file mode 100644
index 00000000..0ad2a271
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/mat4.cxx
@@ -0,0 +1,206 @@
+/************************************************************************
+
+ 4x4 Matrix class
+
+ $Id: mat4.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/mat4.h>
+
+namespace gfx
+{
+
+Mat4 Mat4::I()
+{
+ return Mat4(Vec4(1,0,0,0),Vec4(0,1,0,0),Vec4(0,0,1,0),Vec4(0,0,0,1));
+}
+
+Mat4 translation_matrix(const Vec3& d)
+{
+ return Mat4(Vec4(1, 0, 0, d[0]),
+ Vec4(0, 1, 0, d[1]),
+ Vec4(0, 0, 1, d[2]),
+ Vec4(0, 0, 0, 1));
+}
+
+Mat4 scaling_matrix(const Vec3& s)
+{
+ return Mat4(Vec4(s[0], 0, 0, 0),
+ Vec4(0, s[1], 0, 0),
+ Vec4(0, 0, s[2], 0),
+ Vec4(0, 0, 0, 1));
+}
+
+Mat4 rotation_matrix_rad(double theta, const Vec3& axis)
+{
+ double c=cos(theta), s=sin(theta),
+ xx=axis[0]*axis[0], yy=axis[1]*axis[1], zz=axis[2]*axis[2],
+ xy=axis[0]*axis[1], yz=axis[1]*axis[2], xz=axis[0]*axis[2];
+
+ double xs=axis[0]*s, ys=axis[1]*s, zs=axis[2]*s;
+
+ Mat4 M;
+ M(0,0)=xx*(1-c)+c; M(0,1)=xy*(1-c)-zs; M(0,2)=xz*(1-c)+ys; M(0,3) = 0;
+ M(1,0)=xy*(1-c)+zs; M(1,1)=yy*(1-c)+c; M(1,2)=yz*(1-c)-xs; M(1,3)=0;
+ M(2,0)=xz*(1-c)-ys; M(2,1)=yz*(1-c)+xs; M(2,2)=zz*(1-c)+c; M(2,3)=0;
+ M(3,0)=0; M(3,1)=0; M(3,2)=0; M(3,3)=1;
+
+ return M;
+}
+
+Mat4 perspective_matrix(double fovy, double aspect, double zmin, double zmax)
+{
+ double A, B;
+ Mat4 M;
+
+ if( zmax==0.0 )
+ {
+ A = B = 1.0;
+ }
+ else
+ {
+ A = (zmax+zmin)/(zmin-zmax);
+ B = (2*zmax*zmin)/(zmin-zmax);
+ }
+
+ double f = 1.0/tan(fovy*M_PI/180.0/2.0);
+ M(0,0) = f/aspect;
+ M(1,1) = f;
+ M(2,2) = A;
+ M(2,3) = B;
+ M(3,2) = -1;
+ M(3,3) = 0;
+
+ return M;
+}
+
+Mat4 lookat_matrix(const Vec3& from, const Vec3& at, const Vec3& v_up)
+{
+ Vec3 up = v_up; unitize(up);
+ Vec3 f = at - from; unitize(f);
+
+ Vec3 s=f^up;
+ Vec3 u=s^f;
+
+ // NOTE: These steps are left out of the GL man page!!
+ unitize(s);
+ unitize(u);
+
+ Mat4 M(Vec4(s, 0), Vec4(u, 0), Vec4(-f, 0), Vec4(0, 0, 0, 1));
+
+ return M * translation_matrix(-from);
+}
+
+Mat4 viewport_matrix(double w, double h)
+{
+ return scaling_matrix(Vec3(w/2.0, -h/2.0, 1)) *
+ translation_matrix(Vec3(1, -1, 0));
+}
+
+Mat4 operator*(const Mat4& n, const Mat4& m)
+{
+ Mat4 A;
+ int i,j;
+
+ for(i=0;i<4;i++)
+ for(j=0;j<4;j++)
+ A(i,j) = n[i]*m.col(j);
+
+ return A;
+}
+
+Mat4 adjoint(const Mat4& m)
+{
+ Mat4 A;
+
+ A[0] = cross( m[1], m[2], m[3]);
+ A[1] = cross(-m[0], m[2], m[3]);
+ A[2] = cross( m[0], m[1], m[3]);
+ A[3] = cross(-m[0], m[1], m[2]);
+
+ return A;
+}
+
+double invert_cramer(Mat4& inv, const Mat4& m)
+{
+ Mat4 A = adjoint(m);
+ double d = A[0] * m[0];
+
+ if( d==0.0 )
+ return 0.0;
+
+ inv = transpose(A) / d;
+ return d;
+}
+
+
+
+// Matrix inversion code for 4x4 matrices using Gaussian elimination
+// with partial pivoting. This is a specialized version of a
+// procedure originally due to Paul Heckbert <[email protected]>.
+//
+// Returns determinant of A, and B=inverse(A)
+// If matrix A is singular, returns 0 and leaves trash in B.
+//
+#define SWAP(a, b, t) {t = a; a = b; b = t;}
+double invert(Mat4& B, const Mat4& m)
+{
+ Mat4 A = m;
+ int i, j, k;
+ double max, t, det, pivot;
+
+ /*---------- forward elimination ----------*/
+
+ for (i=0; i<4; i++) /* put identity matrix in B */
+ for (j=0; j<4; j++)
+ B(i, j) = (double)(i==j);
+
+ det = 1.0;
+ for (i=0; i<4; i++) { /* eliminate in column i, below diag */
+ max = -1.;
+ for (k=i; k<4; k++) /* find pivot for column i */
+ if (fabs(A(k, i)) > max) {
+ max = fabs(A(k, i));
+ j = k;
+ }
+ if (max<=0.) return 0.; /* if no nonzero pivot, PUNT */
+ if (j!=i) { /* swap rows i and j */
+ for (k=i; k<4; k++)
+ SWAP(A(i, k), A(j, k), t);
+ for (k=0; k<4; k++)
+ SWAP(B(i, k), B(j, k), t);
+ det = -det;
+ }
+ pivot = A(i, i);
+ det *= pivot;
+ for (k=i+1; k<4; k++) /* only do elems to right of pivot */
+ A(i, k) /= pivot;
+ for (k=0; k<4; k++)
+ B(i, k) /= pivot;
+ /* we know that A(i, i) will be set to 1, so don't bother to do it */
+
+ for (j=i+1; j<4; j++) { /* eliminate in rows below i */
+ t = A(j, i); /* we're gonna zero this guy */
+ for (k=i+1; k<4; k++) /* subtract scaled row i from row j */
+ A(j, k) -= A(i, k)*t; /* (ignore k<=i, we know they're 0) */
+ for (k=0; k<4; k++)
+ B(j, k) -= B(i, k)*t;
+ }
+ }
+
+ /*---------- backward elimination ----------*/
+
+ for (i=4-1; i>0; i--) { /* eliminate in column i, above diag */
+ for (j=0; j<i; j++) { /* eliminate in rows above i */
+ t = A(j, i); /* we're gonna zero this guy */
+ for (k=0; k<4; k++) /* subtract scaled row i from row j */
+ B(j, k) -= B(i, k)*t;
+ }
+ }
+
+ return det;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/quat.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/quat.cxx
new file mode 100644
index 00000000..a3db2a68
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/quat.cxx
@@ -0,0 +1,136 @@
+/************************************************************************
+
+ Quaternion class
+
+ $Id: quat.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/quat.h>
+
+namespace gfx
+{
+
+// Based on code from the Appendix of
+// Quaternion Calculus for Computer Graphics, by Ken Shoemake
+// Computes the exponential of a quaternion, assuming scalar part w=0
+Quat exp(const Quat& q)
+{
+ double theta = norm(q.vector());
+ double c = cos(theta);
+
+ if( theta > FEQ_EPS )
+ {
+ double s = sin(theta) / theta;
+ return Quat( s*q.vector(), c);
+ }
+ else
+ return Quat(q.vector(), c);
+}
+
+// Based on code from the Appendix of
+// Quaternion Calculus for Computer Graphics, by Ken Shoemake
+// Computes the natural logarithm of a UNIT quaternion
+Quat log(const Quat& q)
+{
+ double scale = norm(q.vector());
+ double theta = atan2(scale, q.scalar());
+
+ if( scale > 0.0 ) scale=theta/scale;
+
+ return Quat(scale*q.vector(), 0.0);
+}
+
+Quat axis_to_quat(const Vec3& a, double phi)
+{
+ Vec3 u = a;
+ unitize(u);
+
+ double s = sin(phi/2.0);
+ return Quat(u[0]*s, u[1]*s, u[2]*s, cos(phi/2.0));
+}
+
+Mat4 quat_to_matrix(const Quat& q)
+{
+ Mat4 M;
+
+ const double x = q.vector()[0];
+ const double y = q.vector()[1];
+ const double z = q.vector()[2];
+ const double w = q.scalar();
+ const double s = 2/norm(q);
+
+ M(0,0)=1-s*(y*y+z*z); M(0,1)=s*(x*y-w*z); M(0,2)=s*(x*z+w*y); M(0,3)=0;
+ M(1,0)=s*(x*y+w*z); M(1,1)=1-s*(x*x+z*z); M(1,2)=s*(y*z-w*x); M(1,3)=0;
+ M(2,0)=s*(x*z-w*y); M(2,1)=s*(y*z+w*x); M(2,2)=1-s*(x*x+y*y); M(2,3)=0;
+ M(3,0)=0; M(3,1)=0; M(3,2)=0; M(3,3)=1;
+
+ return M;
+}
+
+Mat4 unit_quat_to_matrix(const Quat& q)
+{
+ Mat4 M;
+
+ const double x = q.vector()[0];
+ const double y = q.vector()[1];
+ const double z = q.vector()[2];
+ const double w = q.scalar();
+
+ M(0,0)=1-2*(y*y+z*z); M(0,1)=2*(x*y-w*z); M(0,2)=2*(x*z+w*y); M(0,3)=0;
+ M(1,0)=2*(x*y+w*z); M(1,1)=1-2*(x*x+z*z); M(1,2)=2*(y*z-w*x); M(1,3)=0;
+ M(2,0)=2*(x*z-w*y); M(2,1)=2*(y*z+w*x); M(2,2)=1-2*(x*x+y*y); M(2,3)=0;
+ M(3,0)=0; M(3,1)=0; M(3,2)=0; M(3,3)=1;
+
+ return M;
+}
+
+Quat slerp(const Quat& from, const Quat& to, double t)
+{
+ const Vec3& v_from = from.vector();
+ const Vec3& v_to = to.vector();
+ const double s_from = from.scalar();
+ const double s_to = to.scalar();
+
+ double cosine = v_from*v_to + s_from*s_to;
+
+ if( (1+cosine) < FEQ_EPS )
+ {
+ // The quaternions are (nearly) diametrically opposed. We
+ // treat this specially (based on suggestion in Watt & Watt).
+ //
+ double A = sin( (1-t)*M_PI/2.0 );
+ double B = sin( t*M_PI/2.0 );
+
+ return Quat( A*v_from[0] + B*(-v_from[1]),
+ A*v_from[1] + B*(v_from[0]),
+ A*v_from[2] + B*(-s_from),
+ A*s_from + B*(v_from[2]) );
+ }
+
+ double A, B;
+ if( (1-cosine) < FEQ_EPS )
+ {
+ // The quaternions are very close. Approximate with normal
+ // linear interpolation. This is cheaper and avoids division
+ // by very small numbers.
+ //
+ A = 1.0 - t;
+ B = t;
+ }
+ else
+ {
+ // This is the normal case. Perform SLERP.
+ //
+ double theta = acos(cosine);
+ double sine = sqrt(1 - cosine*cosine);
+
+ A = sin( (1-t)*theta ) / sine;
+ B = sin( t*theta ) / sine;
+
+ }
+
+ return Quat( A*v_from + B*v_to, A*s_from + B*s_to);
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/raster-jpeg.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/raster-jpeg.cxx
new file mode 100644
index 00000000..d6612ed4
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/raster-jpeg.cxx
@@ -0,0 +1,113 @@
+/************************************************************************
+
+ JPEG image file format support.
+
+ The I/O code in this file was originally based on the example.c
+ skeleton code distributed with the JPEG library (release 6b).
+
+ $Id: raster-jpeg.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/raster.h>
+
+namespace gfx {
+// Quality factors are expressed on a 0--100 scale
+int jpeg_output_quality = 100;
+}
+
+#ifdef HAVE_LIBJPEG
+
+#include <stdio.h>
+extern "C" {
+#include <jpeglib.h>
+}
+
+namespace gfx
+{
+
+bool write_jpeg_image(const char *filename, const ByteRaster& img)
+{
+ FILE *outfile = fopen(filename, "wb");
+ if( !outfile ) return false;
+
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ jpeg_stdio_dest(&cinfo, outfile);
+
+ cinfo.image_width = img.width();
+ cinfo.image_height = img.height();
+ cinfo.input_components = img.channels();
+
+ if(img.channels()==1) cinfo.in_color_space = JCS_GRAYSCALE;
+ else if(img.channels()==3) cinfo.in_color_space = JCS_RGB;
+ else cinfo.in_color_space = JCS_UNKNOWN;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, jpeg_output_quality, TRUE);
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+ int row_stride = img.width() * img.channels();
+ const unsigned char *scanline = img.head();
+ while( cinfo.next_scanline < cinfo.image_height )
+ {
+ (void) jpeg_write_scanlines(&cinfo, (JSAMPLE **)&scanline, 1);
+ scanline += row_stride;
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ fclose(outfile);
+
+ return true;
+}
+
+ByteRaster *read_jpeg_image(const char *filename)
+{
+ FILE *infile = fopen(filename, "rb");
+ if( !infile ) return NULL;
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ cinfo.err = jpeg_std_error(&jerr);
+
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, infile);
+
+ (void) jpeg_read_header(&cinfo, TRUE);
+ (void) jpeg_start_decompress(&cinfo);
+
+ ByteRaster *img = new ByteRaster(cinfo.output_width,
+ cinfo.output_height,
+ cinfo.output_components);
+
+ int row_stride = cinfo.output_width * cinfo.output_components;
+ unsigned char *scanline = img->head();
+ while( cinfo.output_scanline < cinfo.output_height)
+ {
+ (void) jpeg_read_scanlines(&cinfo, (JSAMPLE **)&scanline, 1);
+ scanline += row_stride;
+ }
+
+ (void) jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ fclose(infile);
+ return img;
+}
+
+} // namespace gfx
+
+#else
+
+namespace gfx
+{
+bool write_jpeg_image(const char *, const ByteRaster&) { return false; }
+ByteRaster *read_jpeg_image(const char *) { return NULL; }
+}
+
+#endif
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/raster-png.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/raster-png.cxx
new file mode 100644
index 00000000..c98da9b1
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/raster-png.cxx
@@ -0,0 +1,180 @@
+/************************************************************************
+
+ PNG image file format support.
+
+ The I/O code in this file was originally based on the example.c
+ skeleton code distributed with the PNG library.
+
+ $Id: raster-png.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <vector>
+#include <gfx/gfx.h>
+#include <gfx/raster.h>
+
+#ifdef HAVE_LIBPNG
+
+#include <png.h>
+
+namespace gfx
+{
+
+ByteRaster *read_png_image(const char *file_name)
+{
+ FILE *fp = fopen(file_name, "rb");
+ if( !fp ) return NULL;
+
+ // The last three arguments can be used to set up error handling callbacks.
+ png_structp png_ptr =
+ png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if( !png_ptr ) { fclose(fp); return NULL; }
+
+ // Allocate required structure to hold memory information.
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if( !info_ptr )
+ {
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ return NULL;
+ }
+
+ // Because we didn't set up any error handlers, we need to be
+ // prepared to handle longjmps out of the library on error
+ // conditions.
+ if( setjmp(png_ptr->jmpbuf) )
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ fclose(fp);
+ return NULL;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ // Read in all the image information
+ png_read_info(png_ptr, info_ptr);
+
+ // Get the header for the first image chunk
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ &interlace_type, NULL, NULL);
+
+
+ ////////////////////////////////////////////////////////////////
+ // the following tell the PNG library how to transform the image
+ // during input
+
+ if( bit_depth == 16 )
+ // truncate 16 bits/pixel to 8 bits/pixel
+ png_set_strip_16(png_ptr);
+
+ if( color_type == PNG_COLOR_TYPE_PALETTE )
+ // expand paletted colors into RGB color values
+ png_set_expand(png_ptr);
+ else if( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
+ // expand grayscale images to full 8 bits/pixel
+ png_set_expand(png_ptr);
+
+ // Expand paletted or RGB images with transparency to full alpha
+ // channels so the data will be available as RGBA quartets.
+ if( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) )
+ png_set_expand(png_ptr);
+
+ // update the palette and info structure
+ png_read_update_info(png_ptr, info_ptr);
+
+
+ // read the image data
+ std::vector<png_bytep> row_pointers(height);
+ int row;
+ int nchan = png_get_channels(png_ptr, info_ptr);
+ int nbytes = png_get_rowbytes(png_ptr, info_ptr);
+
+ for (row = 0; row < height; row++)
+ row_pointers[row] = (png_bytep)malloc(nbytes);
+
+ png_read_image(png_ptr, &row_pointers.front());
+ png_read_end(png_ptr, info_ptr);
+
+ // Read it into a ByteRaster structure
+ ByteRaster *img = new ByteRaster(width, height, nchan);
+
+ unsigned char *pixel = img->pixel(0,0);
+ for(row=0; row<height; row++)
+ {
+ memcpy(pixel, row_pointers[row], nbytes);
+ pixel += nbytes;
+ }
+
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ for(row=0; row<height; row++) free(row_pointers[row]);
+
+ fclose(fp);
+ return img;
+}
+
+bool write_png_image(const char *file_name, const ByteRaster& img)
+{
+ FILE *fp = fopen(file_name, "wb");
+ if( !fp ) return false;
+
+ png_structp png_ptr =
+ png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if( !png_ptr ) { fclose(fp); return false; }
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if( !info_ptr )
+ {
+ fclose(fp);
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ return false;
+ }
+
+ if( setjmp(png_ptr->jmpbuf) )
+ {
+ fclose(fp);
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ return false;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ int img_type = PNG_COLOR_TYPE_RGB;
+ switch( img.channels() )
+ {
+ case 1: img_type=PNG_COLOR_TYPE_GRAY; break;
+ case 2: img_type=PNG_COLOR_TYPE_GRAY_ALPHA; break;
+ case 4: img_type=PNG_COLOR_TYPE_RGB_ALPHA; break;
+ }
+
+ png_set_IHDR(png_ptr, info_ptr,
+ img.width(), img.height(), 8, img_type, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_write_info(png_ptr, info_ptr);
+
+ std::vector<png_bytep> row_pointers(img.height());
+ for(int k=0; k<img.height(); k++)
+ row_pointers[k] = (png_bytep)img.head() +k*img.width()*img.channels();
+
+ png_write_image(png_ptr, &row_pointers.front());
+ png_write_end(png_ptr, info_ptr);
+
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ fclose(fp);
+ return true;
+}
+
+} // namespace gfx
+
+#else
+
+namespace gfx
+{
+bool write_png_image(const char *, const ByteRaster&) { return false; }
+ByteRaster *read_png_image(const char *) { return NULL; }
+} // namespace gfx
+
+#endif
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/raster-pnm.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/raster-pnm.cxx
new file mode 100644
index 00000000..75a88990
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/raster-pnm.cxx
@@ -0,0 +1,174 @@
+/************************************************************************
+
+ PNM image file format support
+
+ $Id: raster-pnm.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/raster.h>
+
+#include <fstream>
+
+namespace gfx
+{
+
+using namespace std;
+
+bool will_write_raw_pnm = true;
+
+////////////////////////////////////////////////////////////////////////
+//
+// PNM output routine
+//
+
+bool write_pnm_image(const char *filename, const ByteRaster& img)
+{
+ ofstream out(filename, ios::out|ios::binary);
+ if( !out.good() ) return false;
+
+ bool is_raw = will_write_raw_pnm;
+
+ //
+ // First, write the PNM header.
+ //
+ char magic;
+ if(img.channels() == 1) magic = is_raw ? '5':'2'; // PGM
+ else if(img.channels() < 3) return false; // unsupported
+ else magic = is_raw ? '6':'3'; // truncate to PPM
+
+ out << "P" << magic << " "
+ << img.width() << " " << img.height() << " 255" << endl;
+
+ //
+ // Now, write the PNM data. If there are more than 3 channels,
+ // we'll just write out the first 3 as RGB and ignore the rest.
+ //
+ if( is_raw )
+ {
+ if( img.channels() > 3 )
+ for(int i=0; i<img.length(); i+=img.channels())
+ out.write((const char *)img.pixel(0,0)+i, 3);
+ else
+ out.write((const char *)img.pixel(0,0), img.length());
+ }
+ else
+ {
+ for(int i=0; i<img.length(); i+=img.channels())
+ {
+ out << (int)(img[i]) << " "
+ << (int)(img[i+1]) << " "
+ << (int)(img[i+2]) << endl;
+ }
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// PNM input routines
+//
+
+static
+istream& pnm_skip(istream& in)
+{
+ for(;;)
+ {
+ in >> ws;
+ if( in.peek() == '#' )
+ in.ignore(65535, '\n');
+ else
+ return in;
+ }
+}
+
+static
+void pnm_read_ascii(istream& in, ByteRaster& img)
+{
+ unsigned char *current = img.head();
+ int val;
+
+ for(int j=0; j<img.height(); j++) for(int i=0; i<img.width(); i++)
+ for(int k=0; k<img.channels(); k++)
+ {
+ pnm_skip(in) >> val;
+ *current++ = (unsigned char)val;
+ }
+}
+
+static
+void pnm_read_ascii(istream& in, ByteRaster& img, float scale)
+{
+ unsigned char *current = img.head();
+ float val;
+
+ for(int j=0; j<img.height(); j++) for(int i=0; i<img.width(); i++)
+ for(int k=0; k<img.channels(); k++)
+ {
+ pnm_skip(in) >> val;
+ *current++ = (unsigned char)(val*scale);
+ }
+}
+
+static
+void pnm_read_raw(istream& in, ByteRaster& img)
+{
+ char c; in.get(c); // extract 1 whitespace character
+
+ //
+ // Is this guaranteed to read all the requested bytes?
+ //
+ in.read((char *)img.head(), img.length());
+}
+
+ByteRaster *read_pnm_image(const char *filename)
+{
+ ifstream in(filename, ios::in|ios::binary);
+ if( !in.good() ) return NULL;
+
+ //
+ // Read the PNM header and allocate and appropriate raster.
+ //
+
+ unsigned char P, N;
+ in >> P >> N;
+
+ if( P!='P' ) return NULL;
+
+ int width, height, maxval;
+ pnm_skip(in) >> width;
+ pnm_skip(in) >> height;
+ pnm_skip(in) >> maxval;
+
+ int magic = N - '0';
+ bool is_raw = magic > 3;
+
+ int channels = 1;
+ if( magic==3 || magic==6 )
+ channels = 3;
+
+ ByteRaster *img = new ByteRaster(width, height, channels);
+
+ //
+ // Read the image data into the raster
+ //
+
+ if( is_raw )
+ {
+ if( maxval>255 ) return NULL;
+
+ // BUG: We ignore the scaling implied by maxval<255
+
+ pnm_read_raw(in, *img);
+ }
+ else if( maxval==255 )
+ pnm_read_ascii(in, *img);
+ else
+ pnm_read_ascii(in, *img, 255.0f/(float)maxval);
+
+ return img;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/raster-tiff.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/raster-tiff.cxx
new file mode 100644
index 00000000..a0005849
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/raster-tiff.cxx
@@ -0,0 +1,158 @@
+/************************************************************************
+
+ TIFF image file format support.
+
+ $Id: raster-tiff.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/raster.h>
+#include <cstring>
+
+#ifdef HAVE_LIBTIFF
+#include <tiffio.h>
+
+namespace gfx
+{
+
+////////////////////////////////////////////////////////////////////////
+//
+// TIFF output
+//
+static
+bool __tiff_write(TIFF *tif, const ByteRaster& img)
+{
+ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.width());
+ TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.height());
+
+ TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, img.channels());
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,
+ img.channels()==1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB);
+
+#ifdef HAVE_LIBTIFF_LZW
+ //
+ // LZW compression is problematic because it is patented by Unisys.
+ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
+ //
+ // Predictors:
+ // 1 (default) -- No predictor
+ // 2 -- Horizontal differencing
+ TIFFSetField(tif, TIFFTAG_PREDICTOR, 2);
+#endif
+
+ uint32 scanline_size = img.channels() * img.width();
+ if( TIFFScanlineSize(tif) != scanline_size )
+ // ??BUG: Can this mismatch of scanline sizes every occur?
+ return false;
+
+
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0));
+
+ char *scanline_buf = new char[scanline_size];
+
+ const unsigned char *scanline = img.head();
+ for(int y=0; y<img.height(); y++)
+ {
+ memcpy(scanline_buf, scanline, scanline_size);
+ // NOTE: TIFFWriteScanline modifies the buffer you pass it.
+ // Thus, we need to copy stuff out of the raster first.
+ TIFFWriteScanline(tif, scanline_buf, y, 0);
+ scanline += scanline_size;
+ }
+ delete[] scanline_buf;
+
+ return true;
+}
+
+bool write_tiff_image(const char *filename, const ByteRaster& img)
+{
+ TIFF *tif = TIFFOpen(filename, "w");
+ if( !tif ) return false;
+
+ bool result = __tiff_write(tif, img);
+
+ TIFFClose(tif);
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// TIFF input
+//
+static
+void unpack_tiff_raster(uint32 *raster, ByteRaster *img, int npixels)
+{
+ unsigned char *pix = img->head();
+
+ for(int i=0; i<npixels; i++)
+ {
+ *pix++ = TIFFGetR(raster[i]);
+ if( img->channels() >= 3 )
+ {
+ *pix++ = TIFFGetG(raster[i]);
+ *pix++ = TIFFGetB(raster[i]);
+ if( img->channels() == 4 )
+ *pix++ = TIFFGetA(raster[i]);
+ }
+ }
+}
+
+static
+ByteRaster *__tiff_read(TIFF *tif)
+{
+ uint32 w, h;
+ uint16 nchan;
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
+ TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &nchan);
+
+ int npixels = w*h;
+
+ uint32 *raster = (uint32 *)_TIFFmalloc(npixels * sizeof(uint32));
+ if( !raster ) return NULL;
+
+ TIFFReadRGBAImage(tif, w, h, raster, true);
+
+ ByteRaster *img = new ByteRaster(w, h, nchan);
+ unpack_tiff_raster(raster, img, npixels);
+ //
+ // libtiff returned the pixels with the origin in the lower left
+ // rather than the upper left corner. We fix that by flipping the
+ // pixels.
+ //
+ img->vflip();
+
+
+ _TIFFfree(raster);
+
+ return img;
+}
+
+ByteRaster *read_tiff_image(const char *filename)
+{
+ TIFF *tif = TIFFOpen(filename, "r");
+ if( !tif ) return NULL;
+
+ ByteRaster *img = __tiff_read(tif);
+
+ TIFFClose(tif);
+
+ return img;
+}
+
+} // namespace gfx
+
+#else
+
+namespace gfx
+{
+bool write_tiff_image(const char *, const ByteRaster&) { return false; }
+ByteRaster *read_tiff_image(const char *) { return NULL; }
+}
+
+#endif
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/raster.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/raster.cxx
new file mode 100644
index 00000000..e5a15228
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/raster.cxx
@@ -0,0 +1,113 @@
+/************************************************************************
+
+ Raster image support.
+
+ $Id: raster.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/raster.h>
+
+#include <string>
+#include <cctype>
+#include <cstring>
+
+namespace gfx
+{
+
+ByteRaster::ByteRaster(const ByteRaster &img)
+ : Raster<unsigned char>(img.width(), img.height(), img.channels())
+{
+ memcpy(head(), img.head(), img.length()*sizeof(unsigned char));
+}
+
+ByteRaster::ByteRaster(const FloatRaster &img)
+ : Raster<unsigned char>(img.width(), img.height(), img.channels())
+{
+ for(int i=0; i<length(); i++ )
+ (*this)[i] = (unsigned char) (255.0f * img[i]);
+}
+
+FloatRaster::FloatRaster(const ByteRaster &img)
+ : Raster<float>(img.width(), img.height(), img.channels())
+{
+ for(int i=0; i<length(); i++)
+ (*this)[i] = (float)img[i] / 255.0f;
+}
+
+FloatRaster::FloatRaster(const FloatRaster &img)
+ : Raster<float>(img.width(), img.height(), img.channels())
+{
+ memcpy(head(), img.head(), img.length()*sizeof(float));
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// Table of supported formats
+//
+
+
+
+static char *img_names[] = {"PPM", "PNG", "TIFF", "JPEG"};
+static char *img_ext[] = {"ppm", "png", "tif", "jpg"};
+
+const char *image_type_name(int type)
+ { return type>=IMG_LIMIT ? NULL : img_names[type]; }
+
+const char *image_type_ext(int type)
+ { return type>=IMG_LIMIT ? NULL : img_ext[type]; }
+
+
+int infer_image_type(const char *filename)
+{
+ const char *ext = strrchr(filename, '.');
+ if( !ext ) return -1;
+
+ // Make sure extension is lower case
+ std::string lo(ext+1);
+ for(int i=0; i<lo.length(); i++) lo[i] = tolower(lo[i]);
+
+ // Search for extension in the table
+ for(int typ=0; typ<IMG_LIMIT; typ++)
+ if(lo == img_ext[typ]) return typ;
+
+ // Test for alternatives
+ if(lo=="tiff") return IMG_TIFF;
+
+ // Unknown type
+ return -1;
+}
+
+
+bool write_image(const char *filename, const ByteRaster& img, int type)
+{
+ if( type<0 )
+ type = infer_image_type(filename);
+
+ switch( type )
+ {
+ case IMG_PNM: return write_pnm_image(filename, img);
+ case IMG_PNG: return write_png_image(filename, img);
+ case IMG_TIFF: return write_tiff_image(filename, img);
+ case IMG_JPEG: return write_jpeg_image(filename, img);
+ default: return false;
+ }
+}
+
+ByteRaster *read_image(const char *filename, int type)
+{
+ if( type<0 )
+ type = infer_image_type(filename);
+
+ switch( type )
+ {
+ case IMG_PNM: return read_pnm_image(filename);
+ case IMG_PNG: return read_png_image(filename);
+ case IMG_TIFF: return read_tiff_image(filename);
+ case IMG_JPEG: return read_jpeg_image(filename);
+ default: return NULL;
+ }
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/script.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/script.cxx
new file mode 100644
index 00000000..5f1bdff2
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/script.cxx
@@ -0,0 +1,295 @@
+#include <gfx/script.h>
+#include <fstream>
+
+#if !defined(HAVE_SSTREAM) && defined(HAVE_STRSTREAM)
+# include <strstream>
+typedef istrstream istringstream;
+#else
+# include <sstream>
+#endif
+
+#ifdef HAVE_GZSTREAM
+# include <gzstream.h>
+#endif
+
+namespace gfx
+{
+
+using namespace std;
+
+
+////////////////////////////////////////////////////////////////////////
+//
+// CmdLine methods -- These implement all the basic line manipulations
+//
+
+string CmdLine::token_to_string(int i) const { return substr(tokens[i]); }
+
+string CmdLine::rest_to_string(int i) const
+{
+ return line.substr(tokens[i].first);
+}
+
+double CmdLine::token_to_double(int i) const
+ { string str = substr(tokens[i]); return atof(str.c_str()); }
+
+float CmdLine::token_to_float(int i) const
+ { string str = substr(tokens[i]); return atof(str.c_str()); }
+
+int CmdLine::token_to_int(int i) const
+ { string str = substr(tokens[i]); return atoi(str.c_str()); }
+
+string CmdLine::argline() const
+{
+ if( argcount() == 0 ) return "";
+
+ index_type start = tokens.front().first;
+ index_type end = tokens.back().second;
+ return substr(range_type(start, end));
+}
+
+int CmdLine::collect_as_strings(vector<string> &v, int offset) const
+{
+ for(int i=offset; i<tokens.size(); i++)
+ v.push_back( substr(tokens[i]) );
+ return tokens.size();
+}
+
+int CmdLine::collect_as_numbers(vector<double> &v, int offset) const
+{
+ for(int i=offset; i<tokens.size(); i++)
+ v.push_back(token_to_double(i));
+ return tokens.size();
+}
+
+int CmdLine::collect_as_numbers(vector<int> &v, int offset) const
+{
+ for(int i=offset; i<tokens.size(); i++)
+ v.push_back(token_to_int(i));
+ return tokens.size();
+}
+
+int CmdLine::collect_as_numbers(double *v, int size, int offset) const
+{
+ int i;
+ for(i=0; (i+offset)<tokens.size() && i<size; i++)
+ v[i] = token_to_double(i+offset);
+ return i;
+}
+
+int CmdLine::collect_as_numbers(float *v, int size, int offset) const
+{
+ int i;
+ for(i=0; (i+offset)<tokens.size() && i<size; i++)
+ v[i] = token_to_float(i+offset);
+ return i;
+}
+
+int CmdLine::collect_as_numbers(int *v, int size, int offset) const
+{
+ int i;
+ for(i=0; (i+offset)<tokens.size() && i<size; i++)
+ v[i] = token_to_int(i+offset);
+ return i;
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// CmdEnv methods -- Minimal interface supported by all environments
+//
+
+void CmdEnv::register_command(const std::string& name, CmdObject *fn)
+{
+ script_commands[name] = fn;
+}
+
+void CmdEnv::register_command(const std::string& name, CmdHandler proc)
+{
+ register_command(name, new CmdFunction(proc));
+}
+
+CmdObject *CmdEnv::lookup_command(const std::string& name)
+{
+ CmdTable::const_iterator iter = script_commands.find(name);
+
+ return iter!=script_commands.end() ? iter->second : NULL;
+}
+
+static int ignored(const CmdLine& line) { return SCRIPT_OK; }
+
+void CmdEnv::ignore_command(const std::string& name)
+{
+ register_command(name, ignored);
+}
+
+void CmdEnv::register_vocabulary(const std::string& name, CmdEnv *env)
+{
+ register_method(name, env, &CmdEnv::script_eval);
+}
+
+CmdEnv::CmdEnv()
+{
+ register_method("include", this, &CmdEnv::script_include);
+ register_method("ignore", this, &CmdEnv::script_ignore);
+ register_method("end", this, &CmdEnv::script_end);
+}
+
+CmdEnv::~CmdEnv()
+{
+ // Free all the CmdObject's held by script_commands
+ //
+ for(CmdTable::iterator i = script_commands.begin();
+ i != script_commands.end(); ++i)
+ {
+ CmdObject *obj = i->second;
+ delete obj;
+ }
+}
+
+int CmdEnv::script_include(const CmdLine& cmd)
+{
+ if( cmd.argcount() != 1 ) return SCRIPT_ERR_SYNTAX;
+
+ string filename = cmd.token_to_string(0);
+ return do_file(cmd.token_to_string(0));
+}
+
+int CmdEnv::script_ignore(const CmdLine& cmd)
+{
+ for(int i=0; i<cmd.argcount(); ++i)
+ {
+ string name = cmd.token_to_string(i);
+ ignore_command(name);
+ }
+
+ return SCRIPT_OK;
+}
+
+int CmdEnv::script_end(const CmdLine& cmd)
+{
+ return SCRIPT_END;
+}
+
+int CmdEnv::script_eval(const CmdLine& cmd)
+{
+ return do_line(cmd.argline());
+}
+
+void CmdEnv::begin_scope(CmdEnv *sub) { scopes.push_back(sub); }
+
+void CmdEnv::end_scope()
+{
+ if( scopes.size() > 0 )
+ {
+ CmdEnv *sub = scopes.back();
+ scopes.pop_back();
+ delete sub;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// Toplevel functions -- extract and execute scripting commands
+//
+
+int CmdEnv::do_line(const string &line)
+{
+ CmdEnv& env = *this;
+
+ // Pass this line off to the sub-scope (if any)
+ if( scopes.size() > 0 && scopes.back() )
+ {
+ int rc = scopes.back()->do_line(line);
+ if( rc==SCRIPT_END )
+ {
+ end_scope();
+ rc = SCRIPT_OK;
+ }
+ return rc;
+ }
+
+ const char *ws = " \t\n\r";
+ string::size_type start, end;
+
+ // First, process the initial (command) token
+ start = line.find_first_not_of(ws);
+
+ // Only continue processing if line is a non-empty, non-comment line
+ if( start!=string::npos && line[start]!='#' )
+ {
+ end = line.find_first_of(ws, start);
+ string op = line.substr(start, end-start);
+
+ CmdObject *fn = env.lookup_command(op);
+ if( !fn ) return SCRIPT_ERR_UNDEF;
+
+ CmdLine argv(line);
+ argv.op = CmdLine::range_type(start, end);
+
+ while(1)
+ {
+ start = line.find_first_not_of(ws, end);
+ if( start==string::npos ) break;
+ end = line.find_first_of(ws, start);
+
+ argv.tokens.push_back( CmdLine::range_type(start, end) );
+ }
+
+ return (*fn)(argv);
+ }
+
+ return SCRIPT_OK;
+}
+
+int CmdEnv::do_stream(istream &in)
+{
+ string line;
+
+ while( !in.eof() )
+ {
+ getline(in, line);
+ if( in.fail() ) break;
+
+ int rc = do_line(line);
+ if( rc != SCRIPT_OK )
+ {
+ cerr << "Script Error: " << line << endl;
+ return rc;
+ }
+ }
+
+ return SCRIPT_OK;
+}
+
+int CmdEnv::do_file(const std::string& filename)
+{
+#ifdef HAVE_GZSTREAM
+ if( !filename.compare(filename.size()-3, 3, ".gz") ||
+ !filename.compare(filename.size()-2, 2, ".z") ||
+ !filename.compare(filename.size()-2, 2, ".Z") )
+ {
+ igzstream in(filename.c_str());
+ if( in.good() ) return do_stream(in);
+ else return SCRIPT_ERR_NOFILE;
+ }
+ else
+ {
+ ifstream in(filename.c_str());
+ if( in.good() ) return do_stream(in);
+ else return SCRIPT_ERR_NOFILE;
+ }
+#else
+ ifstream in(filename.c_str());
+ if( in.good() ) return do_stream(in);
+ else return SCRIPT_ERR_NOFILE;
+#endif
+}
+
+int CmdEnv::do_string(const std::string& str)
+{
+ istringstream in(str.c_str());
+ if( in.good() ) return CmdEnv::do_stream(in);
+ else return SCRIPT_ERR_NOFILE;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/symmat2.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/symmat2.cxx
new file mode 100644
index 00000000..df923f33
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/symmat2.cxx
@@ -0,0 +1,61 @@
+#include <gfx/gfx.h>
+#include <gfx/symmat2.h>
+
+namespace gfx
+{
+
+SymMat2 SymMat2::I()
+{
+ SymMat2 A;
+ A(0,0) = A(1,1) = 1;
+ return A;
+}
+
+Mat2 SymMat2::fullmatrix() const
+{
+ Mat2 A;
+
+ for(int i=0; i<A.dim(); i++)
+ for(int j=0; j<A.dim(); j++)
+ A(i, j) = (*this)(i,j);
+
+ return A;
+}
+
+SymMat2 operator*(const SymMat2& n, const SymMat2& m)
+{
+ SymMat2 A;
+ for(int i=0; i<2; i++) for(int j=i; j<2; j++)
+ A(i,j) = n.row(i)*m.col(j);
+ return A;
+}
+
+std::ostream &operator<<(std::ostream &out, const SymMat2& M)
+{
+ for(int i=0; i<M.dim(); i++)
+ {
+ for(int j=0; j<M.dim(); j++)
+ out << M(i, j) << " ";
+ out << std::endl;
+ }
+
+ return out;
+}
+
+SymMat2 SymMat2::outer_product(const Vec2& v)
+{
+ SymMat2 A;
+
+ for(int i=0; i<A.dim(); i++)
+ for(int j=i; j<A.dim(); j++)
+ A(i, j) = v[i]*v[j];
+
+ return A;
+}
+
+double invert(Mat2& m_inv, const SymMat2& m)
+{
+ return invert(m_inv, m.fullmatrix());
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/symmat3.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/symmat3.cxx
new file mode 100644
index 00000000..36c684e3
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/symmat3.cxx
@@ -0,0 +1,61 @@
+#include <gfx/gfx.h>
+#include <gfx/symmat3.h>
+
+namespace gfx
+{
+
+SymMat3 SymMat3::I()
+{
+ SymMat3 A;
+ A(0,0) = A(1,1) = A(2,2) = 1;
+ return A;
+}
+
+Mat3 SymMat3::fullmatrix() const
+{
+ Mat3 A;
+
+ for(int i=0; i<A.dim(); i++)
+ for(int j=0; j<A.dim(); j++)
+ A(i, j) = (*this)(i,j);
+
+ return A;
+}
+
+SymMat3 operator*(const SymMat3& n, const SymMat3& m)
+{
+ SymMat3 A;
+ for(int i=0; i<3; i++) for(int j=i; j<3; j++)
+ A(i,j) = n.row(i)*m.col(j);
+ return A;
+}
+
+std::ostream &operator<<(std::ostream &out, const SymMat3& M)
+{
+ for(int i=0; i<M.dim(); i++)
+ {
+ for(int j=0; j<M.dim(); j++)
+ out << M(i, j) << " ";
+ out << std::endl;
+ }
+
+ return out;
+}
+
+SymMat3 SymMat3::outer_product(const Vec3& v)
+{
+ SymMat3 A;
+
+ for(int i=0; i<A.dim(); i++)
+ for(int j=i; j<A.dim(); j++)
+ A(i, j) = v[i]*v[j];
+
+ return A;
+}
+
+double invert(Mat3& m_inv, const SymMat3& m)
+{
+ return invert(m_inv, m.fullmatrix());
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/symmat4.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/symmat4.cxx
new file mode 100644
index 00000000..d8483017
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/symmat4.cxx
@@ -0,0 +1,52 @@
+/************************************************************************
+
+ 4X4 Symmetric Matrix class
+
+ $Id: symmat4.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+#include <gfx/symmat4.h>
+
+namespace gfx
+{
+
+SymMat4 SymMat4::I()
+{
+ SymMat4 A;
+ A(0,0) = A(1,1) = A(2,2) = A(3,3) = 1;
+ return A;
+}
+
+Mat4 SymMat4::fullmatrix() const
+{
+ Mat4 temp;
+ for (int i=0; i<4; i++)
+ for (int j=0; j<4; j++)
+ temp(i,j) = (*this) (i,j);
+ return temp;
+}
+
+SymMat4 SymMat4::outer_product(const Vec4& v)
+{
+ SymMat4 tmp;
+ for(int i=0; i<4; i++)
+ for(int j=0; j<4; j++)
+ tmp(i,j)=v[i]*v[j];
+ return tmp;
+}
+
+SymMat4 operator* (const SymMat4& n, const SymMat4& m)
+{
+ SymMat4 temp;
+ for (int i=0; i<4; i++)
+ for(int j=0; j<4; j++)
+ temp(i,j)=n.row(i) * m.col(j);
+ return temp;
+}
+
+double invert(Mat4& m_inv, const SymMat4& m)
+{
+ return invert(m_inv, m.fullmatrix());
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/time.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/time.cxx
new file mode 100644
index 00000000..cbbea1c5
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/time.cxx
@@ -0,0 +1,86 @@
+/************************************************************************
+
+ Routines for measuring time.
+
+ $Id: time.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+
+#if defined(WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+namespace gfx
+{
+// Only Windows NT supports getting proper time usage information.
+// In Windows 95, we have to settle for measuring real time.
+double get_cpu_time()
+{
+ FILETIME start, end, kernel, user;
+
+ if( !GetThreadTimes(GetCurrentThread(), &start, &end, &kernel, &user) )
+ {
+ // We're running under Windows 95 instead of NT.
+ // Just get the current time and be done with it.
+ SYSTEMTIME now;
+ GetSystemTime(&now);
+ SystemTimeToFileTime(&now, &user);
+ }
+
+ // Convert into something we can do math on
+ LARGE_INTEGER i;
+ i.LowPart = user.dwLowDateTime;
+ i.HighPart = user.dwHighDateTime;
+
+#ifdef __GNUC__
+
+ // The Win32 headers shipped with GCC don't define the QuadPart
+ // accessor for the LARGE_INTEGER type. So we have to build it
+ // directly.
+ long long quad = i.HighPart;
+ quad = (quad << 32) + i.LowPart;
+ return (double)quad / 1e7;
+#else
+ // Convert to seconds and return
+ return (double)(i.QuadPart) / 1e7;
+#endif
+}
+}
+
+#elif defined(HAVE_GETRUSAGE)
+#include <sys/time.h>
+#include <sys/resource.h>
+
+namespace gfx
+{
+double get_cpu_time()
+{
+ struct rusage t;
+
+ getrusage(RUSAGE_SELF, &t);
+
+ return (double)t.ru_utime.tv_sec + (double)t.ru_utime.tv_usec/1000000;
+}
+}
+
+#elif defined(HAVE_TIMES)
+
+namespace gfx
+{
+double get_cpu_time()
+{
+ struct tms t;
+
+ times(&t);
+
+ return (double)(t.tms_utime) / (double)CLK_TCK;
+}
+}
+
+#else
+
+#error "No supported timing mechanism available."
+
+#endif
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/trackball.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/trackball.cxx
new file mode 100644
index 00000000..40615660
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/trackball.cxx
@@ -0,0 +1,153 @@
+/************************************************************************
+
+ Virtual Trackball for manipulating objects on the screen.
+
+ This code is based on the virtual trackball mechanism developed by
+ Gavin Bell of Silicon Graphics.
+
+ $Id: trackball.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/gfx.h>
+#include <gfx/gl.h>
+#include <gfx/trackball.h>
+
+namespace gfx
+{
+
+static
+float proj_to_sphere(float r, float x, float y)
+{
+ // This is a magic number taken from the SGI trackball.
+ //
+ const float MAGIC_RLIMIT = 0.70710678118654752440f;
+
+ // Project (x,y) onto a sphere of radius r or a hyperbolic sheet
+ // if the point is far enough away from the origin.
+ //
+ float d = sqrt(x*x + y*y);
+ if (d < r * MAGIC_RLIMIT )
+ {
+ // Inside sphere
+ return sqrt(r*r - d*d);
+ }
+ else
+ {
+ // On hyperbola
+ float t = r * MAGIC_RLIMIT;
+ return t*t / d;
+ }
+}
+
+//
+// This is the core routine that actually simulates the action of the
+// trackball. It projects the given coordinates onto the trackball
+// surface, and computes an appropriate rotation.
+//
+// NOTE: This uses the combined spherical/hyperbolic trackball surface
+// used in the SGI trackball.
+//
+void trackball(Quat& q, float p1x, float p1y, float p2x, float p2y)
+{
+ if (p1x == p2x && p1y == p2y)
+ {
+ q = Quat::ident();
+ return;
+ }
+
+ // This is a magic number taken from the SGI trackball source.
+ // Here is the original explanation of this constant:
+ //
+ // This size should really be based on the distance from the
+ // center of rotation to the point on the object underneath
+ // the mouse. That point would then track the mouse as
+ // closely as possible. This is a simple example, though, so
+ // that is left as an Exercise for the Programmer.
+ //
+ const float TRACKBALLSIZE = 0.8f;
+
+ // Project the window coordinates onto the trackball surface.
+ //
+ Vec3 p1(p1x,p1y,proj_to_sphere(TRACKBALLSIZE,p1x,p1y));
+ Vec3 p2(p2x,p2y,proj_to_sphere(TRACKBALLSIZE,p2x,p2y));
+
+ // And how much do we rotate?
+ //
+ float t = norm(p1-p2) / (2.0*TRACKBALLSIZE);
+ if (t > 1.0) t = 1.0;
+ if (t < -1.0) t = -1.0;
+
+ // Convert this axis/angle rotation to a quaternion.
+ //
+ q = axis_to_quat(p2^p1, 2.0*asin(t));
+}
+
+static
+void add_quats(const Quat& q1, const Quat& q2, Quat& dest)
+{
+ dest = q2*q1;
+ unitize(dest);
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// Encapsulate the standard interface of the trackball to simplify
+// its use in most applications.
+//
+
+Trackball::Trackball()
+{
+}
+
+void Trackball::update_animation()
+{
+ add_quats(lastquat, curquat, curquat);
+}
+
+bool Trackball::mouse_up(int *where, int which)
+{
+ return false;
+}
+
+bool Trackball::mouse_down(int *where, int which)
+{
+ if( which==1 )
+ lastquat = Quat::ident();
+
+ return false;
+}
+
+bool Trackball::mouse_drag(int *where, int *last, int which)
+{
+ float vp[4];
+ glGetFloatv(GL_VIEWPORT, vp);
+ float W=vp[2], H=vp[3];
+
+ float diam = 2*radius;
+
+ if( which==1 )
+ {
+ trackball(lastquat,
+ (2.0 * last[0] - W)/W,
+ (H - 2.0 * last[1])/H,
+ (2.0 * where[0] - W)/W,
+ (H - 2.0 * where[1])/H);
+ add_quats(lastquat, curquat, curquat);
+ }
+ else if( which==2 )
+ {
+ trans[0] += diam * (where[0] - last[0]) / W;
+ trans[1] += diam * (last[1] - where[1]) / H;
+ }
+ else if( which==3 )
+ {
+ trans[2] += 0.02*diam*(where[1] - last[1]);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+} // namespace gfx
diff --git a/debian/fireflies/fireflies-2.08/libgfx/src/wintools.cxx b/debian/fireflies/fireflies-2.08/libgfx/src/wintools.cxx
new file mode 100644
index 00000000..dc4fae15
--- /dev/null
+++ b/debian/fireflies/fireflies-2.08/libgfx/src/wintools.cxx
@@ -0,0 +1,88 @@
+/************************************************************************
+
+ Support code for handling various tasks under Win32
+
+ $Id: wintools.cxx 427 2004-09-27 04:45:31Z garland $
+
+ ************************************************************************/
+
+#include <gfx/win/wintools.h>
+
+namespace gfx
+{
+
+HGLRC create_glcontext(HDC dc)
+{
+ HGLRC context = wglCreateContext(dc);
+ if( context )
+ {
+ if( !wglMakeCurrent(dc, context) )
+ {
+ // Destroy context if it fails to bind
+ wglDeleteContext(context);
+ context = NULL;
+ }
+ }
+
+ return context;
+}
+
+int set_pixel_format(HDC dc)
+{
+ PIXELFORMATDESCRIPTOR pixelDesc;
+
+ //
+ // These are the important fields of the PFD
+ //
+ pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pixelDesc.nVersion = 1;
+
+ pixelDesc.dwFlags =
+ PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;
+ pixelDesc.iPixelType = PFD_TYPE_RGBA;
+ pixelDesc.cColorBits = 24;
+ pixelDesc.iLayerType = PFD_MAIN_PLANE;
+
+ //
+ // According to the docs, these can be/are ignored.
+ //
+ pixelDesc.cRedBits = 8;
+ pixelDesc.cRedShift = 16;
+ pixelDesc.cGreenBits = 8;
+ pixelDesc.cGreenShift = 8;
+ pixelDesc.cBlueBits = 8;
+ pixelDesc.cBlueShift = 0;
+ pixelDesc.cAlphaBits = 0;
+ pixelDesc.cAlphaShift = 0;
+ pixelDesc.cAccumBits = 0;
+ pixelDesc.cAccumRedBits = 0;
+ pixelDesc.cAccumGreenBits = 0;
+ pixelDesc.cAccumBlueBits = 0;
+ pixelDesc.cAccumAlphaBits = 0;
+ pixelDesc.cDepthBits = 32;
+ pixelDesc.cStencilBits = 0;
+ pixelDesc.cAuxBuffers = 0;
+ pixelDesc.bReserved = 0;
+ pixelDesc.dwLayerMask = 0;
+ pixelDesc.dwVisibleMask = 0;
+ pixelDesc.dwDamageMask = 0;
+
+
+ int pixel_format = ChoosePixelFormat(dc, &pixelDesc);
+ if( !pixel_format )
+ {
+ // Try and guess a decent default pixel format
+ pixel_format = 1;
+ if( !DescribePixelFormat(dc, pixel_format,
+ sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc) )
+ return NULL;
+ }
+
+ if( !SetPixelFormat(dc, pixel_format, &pixelDesc) )
+ return NULL;
+
+ return pixel_format;
+}
+
+} // namespace gfx