adding files

This commit is contained in:
Emil Martinec 2011-04-06 21:54:59 -05:00
parent b4b8c0602f
commit 7cfaf6c6a2
4 changed files with 773 additions and 0 deletions

177
rtengine/LUT.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* Declaration of flexible Lookup Tables
*
* Usage:
*
* LUT<type> name (size);
* LUT<type> name (size, flags);
*
* creates an array which is valid within the normal C/C++ scope "{ ... }"
*
* access to elements is a simple as:
*
* LUT<float> 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<float> 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<float> my_lut (10,0); // this will extrapolate on either side
*
* shotcuts:
*
* LUTf stands for LUT<float>
* LUTi stands for LUT<int>
* LUTu stands for LUT<unsigned int>
*/
#ifndef LUT_H_
#define LUT_H_
// bit representations of flags
#define LUT_CLIP_BELOW 1
#define LUT_CLIP_ABOVE 2
#define LUTf LUT<float>
#define LUTi LUT<int>
#define LUTu LUT<unsigned int>
template<typename T>
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<T> & operator=(const LUT<T> &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)<size) return data[index];
else
{
if (index < 0)
return data[0];
else
return data[size - 1];
}
}
// use with float indices
T operator[](float index) {
int idx = floor(index);
if (((unsigned int)idx) > 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_ */

265
rtengine/array2D.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/*
* Declaration of flexible 2D arrays
*
* Usage:
*
* array2D<type> name (X-size,Y-size);
* array2D<type> 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<float> 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<float> my_array (10,10,mydata);
*
*
* Useful extra pointers
*
* <type> ** my_array gives access to the pointer for access with [][]
* <type> * my_array gives access to the flat stored data.
*
* Advanced usage:
* array2D<float> 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 <csignal> // for raise()
// flags for use
#define ARRAY2D_LOCK_DATA 1
#define ARRAY2D_CLEAR_DATA 2
#define ARRAY2D_BYREFERENCE 4
#define ARRAY2D_VERBOSE 8
template<typename T>
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<T> & operator=( array2D<T> & 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<y;i++)
memcpy(ptr[i],rhs.ptr[i],x*sizeof(T));
}
return *this;
}
};
template<typename T, const size_t num>
class multi_array2D {
private:
array2D<T> 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<T> & 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_ */

237
rtengine/imagefloat.cc Normal file
View File

@ -0,0 +1,237 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.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 <http://www.gnu.org/licenses/>.
*/
#include <imagefloat.h>
#include <image16.h>
#include <image8.h>
#include <string.h>
#include <rtengine.h>
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; i<height; i++) {
r[i] = (redstart + i*rowstride);
g[i] = (greenstart + i*rowstride);
b[i] = (bluestart + i*rowstride);
}
}
Imagefloat* Imagefloat::copy () {
Imagefloat* cp = new Imagefloat (width, height);
for (int i=0; i<height; i++) {
memcpy (cp->r[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; i<width; i++)
for (int j=0; j<height; j++) {
result->r[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; i<width; i++)
for (int j=0; j<height; j++) {
result->r[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; i<height; i++)
for (int j=0; j<width; j++) {
result->r[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; i<height; i++)
for (int j=0; j<width; j++) {
result->r[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; i<height; i++)
for (int j=0; j<width; j++) {
result->r[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; i<nh; i++) {
int ri = i*height/nh;
for (int j=0; j<nw; j++) {
int ci = j*width/nw;
res->r[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<nh; i++) {
int sy = i*height/nh;
if (sy>=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<nw; j++) {
int sx = j*width/nw;
if (sx>=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;
}

94
rtengine/imagefloat.h Normal file
View File

@ -0,0 +1,94 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.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 <http://www.gnu.org/licenses/>.
*/
//
// A class representing a 16 bit rgb image with separate planes and 16 byte aligned data
//
#ifndef _IMAGEFLOAT_
#define _IMAGEFLOAT_
#include <imageio.h>
#include <rtengine.h>
//#include <image16.h>
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