diff --git a/rtengine/LUT.h b/rtengine/LUT.h
new file mode 100644
index 000000000..c63b99112
--- /dev/null
+++ b/rtengine/LUT.h
@@ -0,0 +1,177 @@
+/*
+ * LUT.h
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2011 Jan Rinze Peterzon (janrinze@gmail.com)
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+
+/*
+ * Declaration of flexible Lookup Tables
+ *
+ * Usage:
+ *
+ * LUT name (size);
+ * LUT name (size, flags);
+ *
+ * creates an array which is valid within the normal C/C++ scope "{ ... }"
+ *
+ * access to elements is a simple as:
+ *
+ * LUT my_lut (10);
+ * float value = my_lut[3];
+ * float value = my_lut[2.5]; // this will interpolate
+ *
+ * when using a float type index it will interpolate the lookup values
+ *
+ * extra setting in flags: (clipping is set by default)
+ * LUT_CLIP_ABOVE
+ * LUT_CLIP_BELOW
+ *
+ * example:
+ * LUT my_lut (10,LUT_CLIP_BELOW);
+ * float value = my_lut[22.5]; // this will extrapolate
+ * float value = my_lut[-22.5]; // this will not extrapolate
+ *
+ * LUT my_lut (10,0); // this will extrapolate on either side
+ *
+ * shotcuts:
+ *
+ * LUTf stands for LUT
+ * LUTi stands for LUT
+ * LUTu stands for LUT
+ */
+
+#ifndef LUT_H_
+#define LUT_H_
+
+// bit representations of flags
+#define LUT_CLIP_BELOW 1
+#define LUT_CLIP_ABOVE 2
+
+#define LUTf LUT
+#define LUTi LUT
+#define LUTu LUT
+
+template
+class LUT {
+private:
+ // list of variables ordered to improve cache speed
+ unsigned int maxs;
+ T * data;
+ unsigned int clip, size, owner;
+public:
+ LUT(int s, int flags = 0xfffffff) {
+ clip = flags;
+ data = new T[s];
+ owner = 1;
+ size = s;
+ maxs=size-2;
+ }
+ void operator ()(int s, int flags = 0xfffffff) {
+ if (owner&&data)
+ delete[] data;
+ clip = flags;
+ data = new T[s];
+ owner = 1;
+ size = s;
+ maxs=size-2;
+ }
+
+ LUT(int s, T * source) {
+ data = new T[s];
+ owner = 1;
+ size = s;
+ maxs=size-2;
+ for (int i = 0; i < s; i++) {
+ data[i] = source[i];
+ }
+ }
+
+ LUT(void) {
+ data = NULL;
+ owner = 1;
+ size = 0;
+ maxs=0;
+ }
+
+ ~LUT() {
+ if (owner)
+ delete[] data;
+ }
+
+ LUT & operator=(const LUT &rhs) {
+ if (this != &rhs) {
+ if (rhs.size>this->size)
+ {
+ delete [] this->data;
+ this->data=NULL;
+ }
+ if (this->data==NULL) this->data=new T[rhs.size];
+ this->clip=rhs.clip;
+ this->owner=1;
+ memcpy(this->data,rhs.data,rhs.size*sizeof(T));
+ this->size=rhs.size;
+ this->maxs=this->size-2;
+ }
+
+ return *this;
+ }
+ // use with integer indices
+ T& operator[](int index) {
+ if (((unsigned int)index) maxs) {
+ if (idx<0)
+ {
+ if (clip & LUT_CLIP_BELOW)
+ return data[0];
+ idx=0;
+ }
+ else
+ {
+ if (clip & LUT_CLIP_ABOVE)
+ return data[size - 1];
+ idx =maxs;
+ }
+ }
+ float diff = index - (float) idx;
+ T p1 = data[idx];
+ T p2 = data[idx + 1]-p1;
+ return (p1 + p2*diff);
+ }
+
+ operator bool (void)
+ {
+ return size>0;
+ }
+
+ void clear(void) {
+ memset(data, 0, size * sizeof(T));
+ }
+};
+
+#endif /* LUT_H_ */
diff --git a/rtengine/array2D.h b/rtengine/array2D.h
new file mode 100644
index 000000000..06ec053b7
--- /dev/null
+++ b/rtengine/array2D.h
@@ -0,0 +1,265 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2011 Jan Rinze Peterzon (janrinze@gmail.com)
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+
+/*
+ * Declaration of flexible 2D arrays
+ *
+ * Usage:
+ *
+ * array2D name (X-size,Y-size);
+ * array2D name (X-size,Y-size type ** data);
+ *
+ * creates an array which is valid within the normal C/C++ scope "{ ... }"
+ *
+ * access to elements is a simple as:
+ *
+ * array2D my_array (10,10); // creates 10x10 array of floats
+ * value = my_array[3][5];
+ * my_array[4][6]=value;
+ *
+ * or copy an existing 2D array
+ *
+ * float ** mydata;
+ * array2D my_array (10,10,mydata);
+ *
+ *
+ * Useful extra pointers
+ *
+ * ** my_array gives access to the pointer for access with [][]
+ * * my_array gives access to the flat stored data.
+ *
+ * Advanced usage:
+ * array2D my_array ; // empty container.
+ * my_array(10,10) ; // resize to 10x10 array
+ * my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data
+ * my_array(10,10,ARRAY2D_CLEAR_DATA|ARRAY2D_LOCK_DATA) ; same but set a lock on changes
+ *
+ * !! locked arrays cannot be resized and cannot be unlocked again !!
+ */
+#ifndef ARRAY2D_H_
+#define ARRAY2D_H_
+#include // for raise()
+// flags for use
+#define ARRAY2D_LOCK_DATA 1
+#define ARRAY2D_CLEAR_DATA 2
+#define ARRAY2D_BYREFERENCE 4
+#define ARRAY2D_VERBOSE 8
+
+template
+class array2D {
+
+private:
+ int x, y, owner, flags;
+ T ** ptr;
+ T * data;
+ bool lock; // useful lock to ensure data is not changed anymore.
+ void ar_realloc(int w, int h) {
+ if ((ptr) && ((h > y) || (4 * h < y))) {
+ delete[] ptr;
+ ptr = NULL;
+ }
+ if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) {
+ delete[] data;
+ data = NULL;
+ }
+ if (ptr == NULL)
+ ptr = new T*[h];
+ if (data == NULL)
+ data = new T[h * w];
+
+ x = w;
+ y = h;
+ for (int i = 0; i < h; i++)
+ ptr[i] = data + w * i;
+ owner = 1;
+ }
+public:
+
+ // use as empty declaration, resize before use!
+ // very useful as a member object
+ array2D() :
+ x(0), y(0), owner(0), data(NULL), ptr(NULL), lock(0) {
+ printf("got empty array2D init\n");
+ }
+
+ // creator type1
+ array2D(int w, int h, unsigned int flgs = 0) {
+ flags = flgs;
+ lock = flags & ARRAY2D_LOCK_DATA;
+ data = new T[h * w];
+ owner = 1;
+ x = w;
+ y = h;
+ ptr = new T*[h];
+ for (int i = 0; i < h; i++)
+ ptr[i] = data + i * w;
+ if (flags & ARRAY2D_CLEAR_DATA)
+ memset(data, 0, w * h * sizeof(T));
+ }
+
+ // creator type 2
+ array2D(int w, int h, T ** source, unsigned int flgs = 0) {
+ flags = flgs;
+ //if (lock) { printf("array2D attempt to overwrite data\n");raise(SIGSEGV);}
+ lock |= flags & ARRAY2D_LOCK_DATA;
+ // when by reference
+ // TODO: improve this code with ar_realloc()
+ owner = (flags & ARRAY2D_BYREFERENCE) ? 0 : 1;
+ if (owner)
+ data = new T[h * w];
+ else
+ data = NULL;
+ x = w;
+ y = h;
+ ptr = new T*[h];
+ for (int i = 0; i < h; i++) {
+ if (owner) {
+ ptr[i] = data + i * w;
+ for (int j = 0; j < w; j++)
+ ptr[i][j] = source[i][j];
+ } else
+ ptr[i] = source[i];
+ }
+ }
+
+ // destructor
+ ~array2D() {
+
+ if (flags & ARRAY2D_VERBOSE)
+ printf(" deleting array2D size %dx%d \n", x, y);
+
+ if ((owner) && (data))
+ delete[] data;
+ if (ptr)
+ delete[] ptr;
+ }
+
+ // use with indices
+ T * operator[](size_t index) {
+ return ptr[index];
+ }
+
+ // use as pointer to T**
+ operator T**() {
+ return ptr;
+ }
+
+ // use as pointer to data
+ operator T*() {
+ // only if owner this will return a valid pointer
+ return data;
+ }
+
+
+ // useful within init of parent object
+ // or use as resize of 2D array
+ void operator()(int w, int h, unsigned int flgs = 0) {
+ flags = flgs;
+ if (flags & ARRAY2D_VERBOSE) {
+ printf("got init request %dx%d flags=%d\n", w, h, flags);
+ printf("previous was data %p ptr %p \n", data, ptr);
+ }
+ if (lock) // our object was locked so don't allow a change.
+ {
+ printf("got init request but object was locked!\n");
+ raise( SIGSEGV);
+ }
+ lock = flags & ARRAY2D_LOCK_DATA;
+
+ ar_realloc(w,h);
+ if (flags & ARRAY2D_CLEAR_DATA)
+ memset(data, 0, w * h * sizeof(T));
+ }
+
+ // import from flat data
+ void operator()(int w, int h, T* copy, unsigned int flgs = 0) {
+ flags = flgs;
+ if (flags & ARRAY2D_VERBOSE) {
+ printf("got init request %dx%d flags=%d\n", w, h, flags);
+ printf("previous was data %p ptr %p \n", data, ptr);
+ }
+ if (lock) // our object was locked so don't allow a change.
+ {
+ printf("got init request but object was locked!\n");
+ raise( SIGSEGV);
+ }
+ lock = flags & ARRAY2D_LOCK_DATA;
+
+ ar_realloc(w,h);
+ memcpy(data, copy, w * h * sizeof(T));
+ }
+ int width() {
+ return x;
+ }
+ int height() {
+ return y;
+ }
+
+ operator bool() {
+ return (x > 0 && y > 0);
+ }
+
+ array2D & operator=( array2D & rhs) {
+ if (this != &rhs)
+
+ {
+ if (!owner) // we can only copy same size data
+ {
+ if ((x != rhs.x) || (y != rhs.y)) {
+ printf(" assignment error in array2D\n");
+ printf(" sizes differ and not owner\n");
+ raise( SIGSEGV);
+ }
+
+ } else {
+ ar_realloc(rhs.x, rhs.y);
+ }
+ // we could have been created from a different
+ // array format where each row is created by 'new'
+ for (int i=0;i
+class multi_array2D {
+private:
+ array2D list[num];
+
+public:
+ multi_array2D(int x, int y, int flags = 0) {
+ for (int i = 0; i < num; i++)
+ list[i](x, y, flags | ARRAY2D_VERBOSE);
+ }
+
+ ~multi_array2D() {
+ printf("trying to delete the list of array2D objects\n");
+ }
+
+ array2D & operator[](size_t index) {
+ if (index < 0 || index >= num) {
+ printf("index %d is out of range[0..%d]", index, num - 1);
+ raise( SIGSEGV);
+ }
+ return list[index];
+ }
+};
+#endif /* array2D_H_ */
diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc
new file mode 100644
index 000000000..7e6bf48bd
--- /dev/null
+++ b/rtengine/imagefloat.cc
@@ -0,0 +1,237 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+#include
+#include
+#include
+#include
+#include
+
+using namespace rtengine;
+
+Imagefloat::Imagefloat ()
+ : unaligned (NULL), data (NULL), r (NULL), g (NULL), b (NULL){
+}
+
+Imagefloat::Imagefloat (int w, int h)
+ : unaligned (NULL), width(w), height (h), data (NULL), r (NULL), g (NULL), b (NULL) {
+
+ allocate (w, h);
+}
+
+Imagefloat::~Imagefloat () {
+
+ if (data!=NULL) {
+ delete [] data;
+ delete [] r;
+ delete [] g;
+ delete [] b;
+ }
+}
+
+void Imagefloat::allocate (int W, int H) {
+
+ width=W;
+ height=H;
+
+ if (data!=NULL) {
+ delete [] data;
+ delete [] r;
+ delete [] g;
+ delete [] b;
+ }
+
+ /*
+ int lsize = width + 8 - width % 8;
+ unaligned = new unsigned char[16 + 3 * lsize * sizeof(float) * height];
+ memset(unaligned, 0, (16 + 3 * lsize * sizeof(float) * height) * sizeof(unsigned char));
+
+ uintptr_t poin = (uintptr_t)unaligned + 16 - (uintptr_t)unaligned % 16;
+ data = (float*) (poin);
+ */
+ r = new float*[height];
+ g = new float*[height];
+ b = new float*[height];
+
+ data = new float[W*H*3];
+ rowstride = W;
+ planestride = rowstride * H;
+
+ float * redstart = data + 0*planestride;
+ float * greenstart = data + 1*planestride;
+ float * bluestart = data + 2*planestride;
+
+
+ for (int i=0; ir[i], r[i], width*sizeof(float));
+ memcpy (cp->g[i], g[i], width*sizeof(float));
+ memcpy (cp->b[i], b[i], width*sizeof(float));
+ }
+
+ return cp;
+}
+
+Imagefloat* Imagefloat::rotate (int deg) {
+
+ if (deg==90) {
+ Imagefloat* result = new Imagefloat (height, width);
+ for (int i=0; ir[i][j] = r[height-1-j][i];
+ result->g[i][j] = g[height-1-j][i];
+ result->b[i][j] = b[height-1-j][i];
+ }
+ return result;
+ }
+ else if (deg==270) {
+ Imagefloat* result = new Imagefloat (height, width);
+ for (int i=0; ir[i][j] = r[j][width-1-i];
+ result->g[i][j] = g[j][width-1-i];
+ result->b[i][j] = b[j][width-1-i];
+ }
+ return result;
+ }
+ else if (deg==180) {
+ Imagefloat* result = new Imagefloat (width, height);
+ for (int i=0; ir[i][j] = r[height-1-i][width-1-j];
+ result->g[i][j] = g[height-1-i][width-1-j];
+ result->b[i][j] = b[height-1-i][width-1-j];
+ }
+ return result;
+ }
+ else
+ return NULL;
+}
+
+Imagefloat* Imagefloat::hflip () {
+
+ Imagefloat* result = new Imagefloat (width, height);
+ for (int i=0; ir[i][j] = r[i][width-1-j];
+ result->g[i][j] = g[i][width-1-j];
+ result->b[i][j] = b[i][width-1-j];
+ }
+ return result;
+
+}
+
+Imagefloat* Imagefloat::vflip () {
+
+ Imagefloat* result = new Imagefloat (width, height);
+ for (int i=0; ir[i][j] = r[height-1-i][j];
+ result->g[i][j] = g[height-1-i][j];
+ result->b[i][j] = b[height-1-i][j];
+ }
+ return result;
+
+}
+
+/*Imagefloat* Imagefloat::resize (int nw, int nh, TypeInterpolation interp) {
+
+ if (interp == TI_Nearest) {
+ Imagefloat* res = new Imagefloat (nw, nh);
+ for (int i=0; ir[i][j] = r[ri][ci];
+ res->g[i][j] = g[ri][ci];
+ res->b[i][j] = b[ri][ci];
+ }
+ }
+ return res;
+ }
+ else if (interp == TI_Bilinear) {
+ Imagefloat* res = new Imagefloat (nw, nh);
+ for (int i=0; i=height) sy = height-1;
+ double dy = (double)i*height/nh - sy;
+ int ny = sy+1;
+ if (ny>=height) ny = sy;
+ for (int j=0; j=width) sx = width;
+ double dx = (double)j*width/nw - sx;
+ int nx = sx+1;
+ if (nx>=width) nx = sx;
+ res->r[i][j] = r[sy][sx]*(1-dx)*(1-dy) + r[sy][nx]*dx*(1-dy) + r[ny][sx]*(1-dx)*dy + r[ny][nx]*dx*dy;
+ res->g[i][j] = g[sy][sx]*(1-dx)*(1-dy) + g[sy][nx]*dx*(1-dy) + g[ny][sx]*(1-dx)*dy + g[ny][nx]*dx*dy;
+ res->b[i][j] = b[sy][sx]*(1-dx)*(1-dy) + b[sy][nx]*dx*(1-dy) + b[ny][sx]*(1-dx)*dy + b[ny][nx]*dx*dy;
+ }
+ }
+ return res;
+ }
+ return NULL;
+}*/
+
+Image8*
+Imagefloat::to8() const
+{
+ Image8* img8 = new Image8(width,height);
+ for ( int h = 0; h < height; ++h )
+ {
+ for ( int w = 0; w < width; ++w )
+ {
+ img8->r(h,w,((int)r[h][w]) >> 8);
+ img8->g(h,w,((int)g[h][w]) >> 8);
+ img8->b(h,w,((int)b[h][w]) >> 8);
+ }
+ }
+ return img8;
+}
+
+Image16*
+Imagefloat::to16() const
+{
+ Image16* img16 = new Image16(width,height);
+ for ( int h = 0; h < height; ++h )
+ {
+ for ( int w = 0; w < width; ++w )
+ {
+ img16->r[h][w] = ((int)r[h][w]) ;
+ img16->g[h][w] = ((int)g[h][w]) ;
+ img16->b[h][w] = ((int)b[h][w]) ;
+ }
+ }
+ return img16;
+}
+
+
diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h
new file mode 100644
index 000000000..8ddf953f6
--- /dev/null
+++ b/rtengine/imagefloat.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+//
+// A class representing a 16 bit rgb image with separate planes and 16 byte aligned data
+//
+#ifndef _IMAGEFLOAT_
+#define _IMAGEFLOAT_
+
+#include
+#include
+//#include
+
+namespace rtengine {
+
+//enum TypeInterpolation { TI_Nearest, TI_Bilinear };
+
+class Image8;
+class Image16;
+
+class Imagefloat : public ImageIO, public IImagefloat {
+
+ private:
+ unsigned char* unaligned;
+
+ public:
+ int rowstride;
+ int planestride;
+
+ int width;
+ int height;
+
+ float* data;
+
+ float** r;
+ float** g;
+ float** b;
+
+
+ Imagefloat ();
+ Imagefloat (int width, int height);
+ ~Imagefloat ();
+
+ Imagefloat* copy ();
+
+ Image8* to8() const;
+ Image16* to16() const;
+
+
+ Imagefloat* rotate (int deg);
+ Imagefloat* hflip ();
+ Imagefloat* vflip ();
+ //Imagefloat* resize (int nw, int nh, TypeInterpolation interp);
+
+ virtual int getW () { return width; }
+ virtual int getH () { return height; }
+ virtual void allocate (int width, int height);
+ virtual int getBPS () { return 8*sizeof(float); }
+ //virtual void getScanline (int row, unsigned char* buffer, int bps);
+ //virtual void setScanline (int row, unsigned char* buffer, int bps);
+
+ // functions inherited from IImagefloat:
+ virtual int getWidth () { return width; }
+ virtual int getHeight () { return height; }
+ virtual Glib::Mutex& getMutex () { return mutex (); }
+ virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); }
+ virtual int getBitsPerPixel () { return 16; }
+ virtual int saveToFile (Glib::ustring fname) { return save (fname); }
+ virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) { return savePNG (fname, compression, bps); }
+ virtual int saveAsJPEG (Glib::ustring fname, int quality = 100) { return saveJPEG (fname, quality); }
+ virtual int saveAsTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false) { return saveTIFF (fname, bps, uncompressed); }
+ virtual void setSaveProgressListener (ProgressListener* pl) { return setProgressListener (pl); }
+ virtual void free () { delete this; }
+ virtual float** getRPlane () { return r; }
+ virtual float** getGPlane () { return g; }
+ virtual float** getBPlane () { return b; }
+};
+};
+#endif