adding files
This commit is contained in:
parent
b4b8c0602f
commit
7cfaf6c6a2
177
rtengine/LUT.h
Normal file
177
rtengine/LUT.h
Normal 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
265
rtengine/array2D.h
Normal 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
237
rtengine/imagefloat.cc
Normal 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
94
rtengine/imagefloat.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user